# SVD an ITensor with QN in Julia?

+1 vote
edited

Hi Miles,

I am using the latest Julia version ITensors.

1.I defined an Index with QN. When I set "dir = In", the Index is not ordered, e.g. qn(s(2)) = QN("N",4,5). When I set "dir = Neither", qn(s(j)) always gives QN("N",0,5). Is this a bug?

s = Index([QN(("N",i,5)) => 1 for i = 0:4];dir = ITensors.Arrow(0))
qn(s(2))


BTW, the direction name "Out", "In" conflict with Out and In in Jupyter Notebook.

2.I wanted to svd an ITensor with QN, but it says "In setindex!, the element you are trying to set is in a block that does not have the same flux as the other blocks of the ITensor. You may be trying to create an ITensor that does not have a well defined quantum number flux."

dim0 = 4
s = Index([QN(("N",i,dim0))=>1 for i = 0:(dim0-1)];dir = ITensors.Arrow(1))
#s = Index(dim0)

A = emptyITensor(l,r,u,d)
for sl = 1:dim0, sd = 1:dim0, sr = 1:dim0, su = 1:dim0
#if sl+sd == sr+su || abs(sl+sd-sr-su) == dim0
if val(qn(l(sl))+qn(d(sd))-qn(r(sr))-qn(u(su)),"N") == 0
A[l(sl),r(sr),u(su),d(sd)] = 1
end
end
svd(A, (l,d))


Am I doing wrong?

Thanks.

Jin

commented by (1.1k points)
I figured out the second question by reversing the direction of "l" and "d", and using "if sl+sd == sr+su || abs(sl+sd-sr-su) == dim0" instead of "if val(qn(l(sl))+qn(d(sd))-qn(r(sr))-qn(u(su)),"N") == 0". The two conditional statements are the same in C++ ITensor. I think this will be fixed if the first question is resolved.

+1 vote

Hi Jin,
Thanks for the question. So I think I see the possible issue: the qn function is defined as the "bare" QN which is the one you see printed when you do @show s say, times the arrow direction of the Index. The direction ITensors.Out corresponds to a multiplication of +1, so no change to the bare QN and you see the one printed. But if the direction is ITensors.In, then it multiples the QN by -1 (effectively) which really means to compute the additive inverse of the QN.

The other thing happening here is that your QN's are defined modulo 5; is that intentional? So since you put a modulus value of 5, the additive inverse of 1 modulo 5 is 4 and so for the case where the direction is ITensors.In you are getting the inverse of the bare QN, hence QN("N",4,5). (The "bare" QN in your case is QN("N",1,5) for subspace number 2.)

I don't think any of this is a bug, but it does raise a potential issue we should think about which is whether we should print the total QN (direction times bare QN, as returned by the qn function) rather than just the bare QN when printing an Index. We will think about it.

Regarding the name space conflict for In and Out, it is unfortunate which is why we don't export those values from ITensors.jl. Are you ok with just writing ITensors.In and ITensors.Out ? In a lot of ITensor code it's not required to work with arrows anyway; usually you obtain an In arrow Index by just taking the conjugate of an Out arrow Index using the function dag.

Miles

commented by (1.1k points)
Hi Miles, thanks for the explanation. Yes, the defined modulo 5 is intentional. I wanted to define a ITensor in "mod(l+d-u-r, 5) = 0" block. I am ok with writing ITensors.In and ITensors.Out.
commented by (47.7k points)