# Ground state wavefunction

**URL:** <https://itensor.discourse.group/t/ground-state-wavefunction/1470>\
**Category:** ITensor Julia Questions\
**Created:** [February 10, 2024, 12:51pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470 "2024-02-10T12:51:22Z")\
**Posts on this page:** 16\
**Page:** 1

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 10, 2024, 12:51pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/1 "2024-02-10T12:51:22Z")

</div>

Dear all,

I try to obtain ground state wavefunction using dmrg:

```julia
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.

Thank you in advance.

---

<div class="post-metadata">

**Author:** ![kmp5](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/kmp5/32/251_2.png) [@kmp5](https://itensor.discourse.group/u/kmp5)\
**Post date:** [February 12, 2024, 5:06pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/2 "2024-02-12T17:06:47Z")

</div>

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

```auto
ψ = 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.

---

<div class="post-metadata">

**Author:** ![mtfishman](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/mtfishman/32/11_2.png) [@mtfishman](https://itensor.discourse.group/u/mtfishman)\
**Post date:** [February 12, 2024, 6:01pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/3 "2024-02-12T18:01:45Z")

</div>

> [@Faridun](#):
>
> Also, I tried psi.data This gives NDTensors.BlockSparse and I do not know how to manage with this data.

I’m confused why you say `psi.data` returns `NDTensors.BlockSparse`, it should be `Vector{ITensor}` (a vector of the tensors of the MPS).

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 12, 2024, 8:45pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/4 "2024-02-12T20:45:56Z")

</div>

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?

---

<div class="post-metadata">

**Author:** ![kmp5](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/kmp5/32/251_2.png) [@kmp5](https://itensor.discourse.group/u/kmp5)\
**Post date:** [February 12, 2024, 8:57pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/5 "2024-02-12T20:57:50Z")

</div>

@mtfishman is right I actually didn’t catch that `psi.data` does return a `Vector{ITensors}`

```auto
julia> typeof(psi.data)
Vector{ITensor} (alias for Array{ITensor, 1})

```

potentially you are looking at the output of `psi.data` and seeing something like this

```auto
ITensor ord=2
Dim 1: (dim=3|id=146|"S=1,Site,n=5") <Out>
 1: QN("Sz",2) => 1
 2: QN("Sz",0) => 1
 3: QN("Sz",-2) => 1
Dim 2: (dim=3|id=479|"Link,l=4") <In>
 1: QN("Sz",-2) => 1
 2: QN("Sz",0) => 1
 3: QN("Sz",2) => 1
NDTensors.BlockSparse{Float64, Vector{Float64}, 2}
 3×3
Block(3, 1)
 [3:3, 1:1]
 1.0

Block(2, 2)
 [2:2, 2:2]
 1.0

Block(1, 3)
 [1:1, 3:3]
 1.0]

```

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)`

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 12, 2024, 9:15pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/6 "2024-02-12T21:15:45Z")

</div>

Sure!  
Here is full code

```julia
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)

```

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 12, 2024, 9:16pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/7 "2024-02-12T21:16:16Z")

</div>

Here you are

---

<div class="post-metadata">

**Author:** ![kmp5](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/kmp5/32/251_2.png) [@kmp5](https://itensor.discourse.group/u/kmp5)\
**Post date:** [February 12, 2024, 9:55pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/8 "2024-02-12T21:55:02Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![mtfishman](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/mtfishman/32/11_2.png) [@mtfishman](https://itensor.discourse.group/u/mtfishman)\
**Post date:** [February 12, 2024, 9:58pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/9 "2024-02-12T21:58:15Z")

</div>

> [@Faridun](#):
>
> Is there any way to obtain array like wavefunction for further calculations (for example to calculate fractal dimensions)?

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.

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 13, 2024, 9:21am UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/10 "2024-02-13T09:21:30Z")

</div>

Thank you for your reply. I mean something like:

S\_q = \ln(\sum\_s^{N\_H}|\psi(s)|^2)

where N\_H is dimensional Hilbert space. It means the logarithm of the square of the sum of all elements of wavefunction.

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [February 13, 2024, 4:26pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/11 "2024-02-13T16:26:53Z")

</div>

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.

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 14, 2024, 2:36pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/12 "2024-02-14T14:36:01Z")

</div>

That’s right. What if I want to calculate:

Sq=\ln(\sum\_s^{N\_H}|\psi(s)|^4)

In this case we need, what we should to do?

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 16, 2024, 10:23am UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/13 "2024-02-16T10:23:06Z")

</div>

In case of degree equal 4, is any way to use MPS to calculate?

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [February 16, 2024, 3:30pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/14 "2024-02-16T15:30:49Z")

</div>

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”.

Another option is to square the MPS using the network for squaring functions described in this paper:  
[https://journals.aps.org/prx/abstract/10.1103/PhysRevX.13.021015](https://journals.aps.org/prx/abstract/10.1103/PhysRevX.13.021015)

---

<div class="post-metadata">

**Author:** ![Faridun](https://avatars.discourse-cdn.com/v4/letter/f/45deac/32.png) [@Faridun](https://itensor.discourse.group/u/Faridun)\
**Post date:** [February 26, 2024, 12:25pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/15 "2024-02-26T12:25:38Z")

</div>

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 ?

---

<div class="post-metadata">

**Author:** ![miles](https://yyz2.discourse-cdn.com/free1/user_avatar/itensor.discourse.group/miles/32/6_2.png) [@miles](https://itensor.discourse.group/u/miles)\
**Post date:** [February 26, 2024, 2:10pm UTC](https://itensor.discourse.group/t/ground-state-wavefunction/1470/16 "2024-02-26T14:10:47Z")

</div>

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.

If you are interested in computing D\_1 in this basis, since it is equivalent to entanglement entropy, please see our Code Example on how to compute entanglement:  
[https://itensor.github.io/ITensors.jl/dev/examples/MPSandMPO.html#Computing-the-Entanglement-Entropy-of-an-MPS](https://itensor.github.io/ITensors.jl/dev/examples/MPSandMPO.html#Computing-the-Entanglement-Entropy-of-an-MPS)
