0 votes
asked by (1.1k points)

Hi Miles,

I thought the singular values are sorted from the largest to the smallest after "svd". But it seems they are not if we conserve the parity. It is easy to sort by ourselves, but I'm not sure if you missed it for ConserveParity=true. Thanks.

#include "itensor/all.h"
using namespace itensor;

int 
main()
    {
    int N = 8;

    auto sites = SpinHalf(N,{"ConserveSz=",false, "ConserveParity",true});

    auto ampo = AutoMPO(sites);
    for(int j = 1; j < N; ++j)
        {
        ampo += 0.5,"S+",j,"S-",j+1;
        ampo += 0.5,"S-",j,"S+",j+1;
        ampo +=     "Sz",j,"Sz",j+1;
        }
    auto H = toMPO(ampo);

    auto sweeps = Sweeps(20); //number of sweeps is 5
    sweeps.maxdim() = 10,20,100,100,200;
    sweeps.cutoff() = 1E-10;

    auto state0 = InitState(sites);
    for(int is = 1; is <= N; ++is)
    {
    state0.set(is,is%2==1 ? "Up" : "Dn");
    //state0.set(is,"Dn");
    }

    auto psi0 = randomMPS(state0);

    auto [energy,psi] = dmrg(H,psi0,sweeps,{"Quiet",true,"EnergyErrgoal=",1e-6,"EntropyErrgoal=",1e-5});

    println("Ground State Energy = ",energy);

    auto b = 4;

    //"Gauge" the MPS to site b
    psi.position(b); 

    //SVD this wavefunction to get the spectrum
    //of density-matrix eigenvalues
    auto l = leftLinkIndex(psi,b);
    auto s = siteIndex(psi,b);
    auto [U,S,V] = svd(psi(b),{l,s});
    auto u = commonIndex(U,S);

    //Apply von Neumann formula
    //to the squares of the singular values
    Real SvN = 0.;
    for(auto n : range1(dim(u)))
        {
        auto Sn = elt(S,n,n);
        auto p = sqr(Sn);
        if(n<=4) println(n, " ", p);
        if(p > 1E-14) SvN += -p*log(p);
        }
    printfln("Across bond b=%d, SvN = %.10f",b,SvN);

    return 0;
    }

Jin

2 Answers

0 votes
answered by (49k points)

Hi Jin,
Thanks for the question. However, when I run the sample code you posted, I get the following output at the end:

Ground State Energy = -3.37493
1 0.893389
2 0.035519
3 1.64686e-05
4 4.13928e-06
Across bond b=4, SvN = 0.4569757731

which is indeed sorted. Are you seeing a very different output and can you post which singular values you are seeing?

Best,
Miles

commented by (1.1k points)
Hi Miles, thanks for the reply. During the sweep, the output shows that

vN Entropy at center bond b=4 = 0.456975773109
    Eigs at center bond b=4: 0.8934 0.0355 0.0355 0.0355
    Largest link dim during sweep 4/20 was 16
    Largest truncation error: 9.15589e-17
    Energy after sweep 4/20 is -3.374932598688
    Sweep 4/20 CPU time = 0.0292s (Wall time = 0.0312s)

The first 4 biggest singular values should be 0.8934 0.0355 0.0355 0.0355. The last two are placed somewhere else.
0 votes
answered by (49k points)

Hi Jin,
Ok now I've figured it out. This will be the official answer (I had missed a detail about the code in my other answer).

The answer is that, no, the diagonal entries in the S tensor are in general not sorted. They are sorted within each block, but not across blocks. This is chosen so that U and V can retain a block-sparse structure when conserving quantum numbers.

So one way to get a sorted list of all of the singular values is to loop over them all first, put them into a std::vector, then call std::sort on that vector.

Another way is to call the older interface for the SVD that takes U,S, and V as (reference) arguments:
http://itensor.org/docs.cgi?vers=cppv3&page=classes/decomp
This older interface returns a Spectrum object which can be used to access a sorted list of all of the density matrix eigenvalues (squares of singular values).

Best regards,
Miles

P.S. just for extra info, the behavior of the code in the presence of quantum numbers is not specifically programmed for each kind of quantum number, such as parity or otherwise. It is written in a very generic way, so would likely either work for parity and all other types of quantum numbers or fail for parity as well as all other quantum numbers.

commented by (1.1k points)
I see, thanks for the detail explanations.
Welcome to ITensor Support Q&A, where you can ask questions and receive answers from other members of the community.

Formatting Tips:
  • To format code, indent by four spaces
  • To format inline LaTeX, surround it by @@ on both sides
  • To format LaTeX on its own line, surround it by $$ above and below
  • For LaTeX, it may be necessary to backslash-escape underscore characters to obtain proper formatting. So for example writing \sum\_i to represent a sum over i.
If you cannot register due to firewall issues (e.g. you cannot see the capcha box) please email Miles Stoudenmire to ask for an account.

To report ITensor bugs, please use the issue tracker.

Categories

...