Hi thanks for the question. When you say your results arenāt matching with ED, could you please say more about it? I see that your gates here are evolving in imaginary time, so are you trying to use them to obtain the ground state or to evolve to a specific amount of imaginary time?
I see ā so here you are only evolving to a time beta_max = 1.0 apparently. The ground state is only reached for a very large beta, and formally only when beta goes to infinity. In practice a beta of 20 is often enough to reach the ground state, but it depends on the size of the energy gap.
Did you try larger values of beta?
Also if you are trying to compute ground states with ITensor, itās much more efficient to use DMRG to do that.
Hi, Miles, Basically I want to calculate the Ground state magnetisation of the same system at some finite temperature T. Is this (above code) not the correct way to do so ? If not , then how I can find the finite T properties (magnetisation )
Sorry for asking the naive questions.
ā I see ā so here you are only evolving to a time beta_max = 1.0 apparentlyā
Is the beta_max is related to time, not to T ?
Is this beta_max is inverse of Temperature T ? If so then beta_max = 1.0 corresponds to T =1.0. ?
I assumed that, since beta=1/T, so properties at any T can be found by reaching that T (corresponding beta). Do I need to evolve the system ? Could you please comment on that. We donāt do this in ED. We can directly find the properties by giving that particular T.
I see, I was confused by you calling the finite temperature state the ground state. The term āground stateā only refers to the state of the system at T=0 which is a pure. A state at a finite temperature is given by a mixed state and is not called a ground state.
The code you linked to does look possibly correct for obtaining the thermal mixed state at inverse temperature \beta=beta_max since you start with an infinite temperature state as an MPO and imaginary time evolve that.
So I donāt know off hand the reason that you are getting a different energy from your ED code if that one is also computing finite temperature properties, I assume in a correct way.
We have put an example code showing how to implement the āpurificationā method for finite-temperature systems which is equivalent to what you are trying to do. It could be helpful for you to compare your implementation to ours, which is available in the ITensor example folder here: https://github.com/ITensor/ITensors.jl/blob/main/examples/finite_temperature/purification.jl
Your code does look correct, but as always a code has to be run and checked to be sure of its correctness.
Did you take into account the partition function, that is, the trace of rho no longer being equal to 1 after the imaginary time evolution? You will need to either make it equal to 1 or else divide by the trace when computing any observables.
I was using Gj = exp(-1.0* tau/2 * hj) so far!! I was getting negative real numbers as energy, but if I use Gj = exp(-1.0im* tau/2 * hj) then I get the complex energies!! ?
Right, so the reason you are getting complex energies in that case is because apply(gates,rho) is defined to only apply the gates to one side of rho. So it is doing e^{-i H \tau} \rho.
In contrast, the correct way to evolve a density matrix in real time is e^{-i H \tau} \rho e^{i H \tau} for a time step \tau. For this purpose, there is a keyword argument called apply_dag you can use like this:
rho = apply(gates,rho; apply_dag=true)
The documentation for apply_dag can currently be hard to find, so I can see why you did not know about it!
For the imaginary time case of what you are doing you donāt need apply_dag however, because computing just e^{- H \tau} \rho ought to be fine for obtaining e^{- H \beta} when starting from \rho being an identity operator.
As to why you are still getting a different energy from your ED code, I donāt know the reason as it seems it is a bug you need to find, but it could be one of many different things:
is it possible your ED code is using Pauli matrices for the spin operators whereas ITensor uses spin operators which include a factor of 1/2 ?
perhaps you are not accounting correctly for the total amount of imaginary time evolved in one or both codes?
I note in your code that you are printing out the energy before taking the imaginary time step. Maybe you should print it out after taking the time step?