I try to obtain ground state wavefunction using dmrg:
energy, psi = dmrg(H, psi0, sweeps)
println(psi)
Is there any way to obtain array like wavefunction for further calculations (for example to calculate fractal dimensions)?
Also, I tried psi.data This gives NDTensors.BlockSparse and I do not know how to manage with this data.
The returned value psi is the DMRG optimized wavefunction in an MPS form. If you would like to turn the wavefunction into a single order-N tensor (where N is the number of sites) you have to contract over all of the bond dimensions. This can be done like this
Ļ = contract(psi)
however it will be very large (if site size = 2, 30 sites will create a tensor of dimension 2^30 which is 8Gb of storage in Float64)
Note also you are finding that psi.data is a BlockSparse because you have the variable conserve_qns=true in the siteinds function.
Thank you so much for your reply!
Yes, a data is very large. Is there any way to obtain the value psi, when I have the variable conserve_qns=true in the siteinds function?
which is an ITensor with a BlokcSparse storage structure.
Would you please show more lines of code so we can know what is going on.
Also if psi is in fact a Vector{ITensor} you can create the full non-mps wavefunction with the code contract(psi)
using ITensors
N = 12
Npart = 6
t1 = 1.0
U = 0.5
h = 1.0
sites = siteinds("Electron", N; )
ampo = AutoMPO()
for f = 1:N-1
ampo += -t1, "Cdagup", f, "Cup", f+1
ampo += -t1, "Cdagup", f+1, "Cup", f
ampo += -t1, "Cdagdn", f, "Cdn", f+1
ampo += -t1, "Cdagdn", f+1, "Cdn", f
end
for i = 1:N
ampo += U, "Nupdn", i
end
# Magnetic field (Zeeman) term
for i = 1:N
hz = 0.1 * (rand() ) # [-1, 1]
#println(hz)
ampo += hz, "Sz", i
end
# Potential field term
for i = 1:N
hE = rand() - 0.5 # [-0.5, 0.5]
#println(hE)
ampo += hE, "Ntot", i
end
H = MPO(ampo, sites)
state = [isodd(n) ? "Up" : "Dn" for n = 1:N]
psi0 = randomMPS(sites, state)
@show flux(psi0)
sweeps = Sweeps(6)
maxdim!(sweeps, 50, 100, 200, 400, 800, 800)
cutoff!(sweeps, 1E-12)
@show sweeps
energy, psi = dmrg(H, psi0, sweeps)
I donāt see anything related to BlockSparse in this code. And adding something like psi_dense = contract(psi)
does successful construct the order-12 representation of psi I just tested.
Could you explain what might be involved in computing fractal dimensions? Itās possible that you could do it with an MPS, I think you just need to give us some more details about what kind of calculation you are trying to perform and what operations you might need.
If I understand your formula correctly, the value inside the log is the squared norm of the wavefunction, which as you know of course is usually taken to equal 1.0 by convention (and certainly our DMRG code and other codes will generally output a state normalized to 1). So then the above quantity would be ln(1) = 0 unless I am missing something such as about what the sum runs over.
What I would suggest for you is to test your calculation idea out on a small system just by finding the ground state (if thatās what youāre after) in a direct (āexact diagonalizationā or āfull stateā) manner, to test your observable and whether it gives the result you want. Then if it does you can next scale up by using MPS and DMRG.
I believe this is possible, but it is not straightforward to do. The way I could think to do it would be to use a kind of machine learning or tomography method to ālearnā the state with amplitudes that are the square of the original ones. Then by squaring that new state again one can get the sums of the fourth powers. One such tomography method is called ātensor cross interpolationā.
Thank you so much for you reply. It was really useful. I found another property which may be calculated. It can be written as follows: D_1 = \sum_{i}^N |c_i|^2 \ln |c_i|^2
where c_i is an expansion coefficient of a given state \ket{\psi} in some (finite) orthonormal basis {\ket{\psi_i}}, i.e. \ket{\psi} = \sum_{i}^N c_i {\ket{i}}.
Any ideas how to perform this for the system with number of sites L>100 ?
I have an answer to this you might find interesting, as I think it highlights the basis dependence of the D_1 quantity.
Any MPS, when you bring it into āorthogonal formā and then if you SVD the ācenterā tensor to expose the singular values matrix on a bond, is equivalent to a Schmidt decomposition:
\ket{\psi} = \sum_i s_i \ket{L_i} \ket{R_i}
You can think of defining basis states \ket{i} = \ket{L_i} \ket{R_i} and then the expansion is of the form you are looking for.
Then the D_1 quantity you defined, when computed in this basis, would be exactly the von Neumann entanglement entropy, perhaps up to a minus sign. And then while this quantity is equal for a large system on any bond deep in the ābulkā, near the edges it depends strongly on which bond you compute it across.