Hello! It is well known that there is a phase ambiguity in SVD:
$$
USV=(Ue^{+i\phi})S(Ve^{-i\phi})
$$
Is there anyone willing to explain how iTensor chooses this phase angle @@\phi@@ in the function svd
and bondSVD
(which includes a direction argument Fromleft
or Fromright
)? Is this special choice good for numerical stability? Thank you very much!
I tried an example:
// decompose AA into m1 and m2
auto i = Index("d",2,Link);
auto j = Index("d",2,Link);
auto a = Index("S=1/2 2",2,Site);
auto b = Index("S=1/2 3",2,Site);
ITensor AA(i,a,b,j);
AA.set(i(1),a(1),b(1),j(1), 0.706886 + 0.017676*Complex_i);
AA.set(i(2),a(2),b(2),j(2), 0.706886 + 0.017676*Complex_i);
// do SVD
ITensor U(i,a), S, V;
svd(AA, U, S, V, {"Cutoff",1E-5});
ITensor m1 = U;
ITensor m2 = S*V;
The result is
m1 =
ITensor r=3: ("d",2,Link|372) ("S=1/2 2",2,Site|797) ("ul",2,Link|8)
{norm=1.41 (Dense Cplx)}
(1,1,1) 1.000000+0.000000i
(2,2,2) 1.000000+0.000000i
m2 =
ITensor r=3: ("ul",2,Link|8) ("S=1/2 3",2,Site|286) ("d",2,Link|624)
{norm=1.00 (Dense Cplx)}
(1,1,1) 0.706886+0.017676i
(2,2,2) 0.706886+0.017676i
However, if I use the NumPy function numpy.linalg.svd
(together with some numpy.reshape
operations), the result will be (I have translated it into the iTensor format)
m1 =
(1,1,1) -0.99968752-0.0249974i
(2,2,2) -0.99968752-0.0249974i
m2 =
(1,1,1) -0.70710678+0.i
(2,2,2) -0.70710678+0.i
The difference is only a phase factor, as can be verified directly. It seems that they both want to make one of m1 and m2 be real (iTensor chooses m1, and NumPy chooses m2).