When I read the tutorials, I was confused about the usage of the dag function. For example, dag(T::ITensor; allow_alias = true). By default, an alias of the ITensor is returned (i.e. the output ITensor may share data with the input ITensor). If allow_alias = false , an alias is never returned. However, I can not understand the meaning of alias.
I tested the following code:
using ITensors
i = Index(2,"index_i");
j = Index(2,"index_j");
A = randomITensor(ComplexF64,i,j)
B = dag(A; allow_alias = true)
C = dag(A; allow_alias = false)
A[1,1]=1
@show A==B
@show A==C
The results are two false. Like the tutorial says, B should be an alias for A. Why did I change A, but B stayed the same?
Thank you for your patience, I would be very grateful for any suggestions. I am looking to to hearing from you.
Regards,
Y.D.Shen.
Thank you for the quick reply!
Of course, the result you’ve achieved is more in keeping with the concept of alias in the tutorial. So, when we use the dag function, the alias of an ITensor can only be generated if its elements are all real numbers? If an ITensor contains complex numbers, its alias does not exist. Right?
So I added the option allow_alias=false for ITensor objects to provide more memory safety, when that is desired. The issue it is solving is that if a user knows they want to write a code like:
x = randn(2, 2) # or `randn(ComplexF64, 2, 2)`
y = conj(x)
y[1, 1] = 2
but they never want x to be modified, the only way to do that in Julia is either:
x = randn(2, 2) # or `randn(ComplexF64, 2, 2)`
y = conj(copy(x)) # Unnecessary copy in the complex case
y = isreal(x) ? copy(x) : conj(x) # Annoying to write
y[1, 1] = 2
allow_alias=false basically automatically handles the logic isreal(x) ? copy(x) : conj(x) for you.