# Calculate absolute value of magnetization

+1 vote

On the itensor homepage, there is an example given to calculate the on-site magnetization.

for(int j = 1; j <= N; ++j)
{
//Make site j the MPS "orthogonality center"
psi.position(j);
//Measure magnetization
Real Szj = elt(psi(j)
* op(sites,"Sz",j)
* dag(prime(psi(j),"Site")));
println("Sz_",j," = ",Szj);
}


I'm interested in calculating the absolute value of the on-site magnetization. Just to be clear about what I mean, given a pure state @@\ket{\psi}@@ of dimension @@ d=2^N @@ and hilbert space H comprising of all possible spin configurations, I want to do the following.

absM = 0
for idx = 1:2^N
SumSz = 0
for spin_idx = 1:N
SumSz += H[idx][spin_idx] # spin value
end
absM += abs(SumSz)*|psi(idx)|^2
end


How do I do this in itensor given an MPS from a DMRG calculation?

As a side note, there is a related thread on measuring the magnetization-squared (which I will also need) here. But, this is all that I could find that it somewhat related to my question.

Thanks again for the help, and hope you guys are staying safe!

commented by (70.1k points)
Just wanted to put a note to say I'm thinking about your question, but my feeling is that there isn't any obvious, efficient MPS algorithm to measure this quantity. It may require something like a sampling approach to be done with any reasonable scalability or efficiency. The reason is that it's related to the wavefunction and Sz operators in a non-linear way, whereas MPS and MPO can just do linear things (linear within the full Hilbert space though) efficiently.

But I will think about it more and see if I can think of a trick to do it.

+1 vote

For an official answer, I'm going to say that I think your best bet without having to do heavy algorithm development (or unless I'm missing something simple) is to use sampling to address this problem.

In the Julia version of ITensor we have a function called sample (and a more guaranteed-efficient version called sample!) which will sample a configuration "c" from an MPS with probability |psi(c)|^2. One nice thing about MPS is that this sampling algorithm is 'perfect', meaning it does not rely on a Markov chain or have any autocorrelation time or effects.

For the C++ version, you can look in itensor/tutorial/finiteT folder for the METTS code there to see a version of the same sampling algorithm in C++. Or you could adapt the Julia code to C++.

For each sample, you can straightforwardly compute your observable and I think you know that the |psi(c)|^2 factor would be implicit in the algorithm itself so you can just compute a straight average.

Again there may be other ideas but this one has the virtue of being pretty straightforward to implement.

Best,
Miles

commented by (230 points)
Thanks, Miles. I have a code already to calculate samples in C++ using ITensor v3. I believe you are referring to the algorithm outlined by Ferris & Vidal ("Perfect sampling with unitary tensor networks"). It is unfortunate that there isn't a solution to this problem that doesn't involve sampling. Nevertheless, I appreciate your help!