How do I save the dmrg output which comes on the screen (after sweep1 energy … etc) in a file for a future record. Is it possible without disturbing the inbuilt dmrg function?
Using “silent” argument in the dmrg function, we can stop this information from coming up on the screen . If I am wrong please let me know.
How many excited states can ITensor DMRG calculate with reliable accuracy?
Hi! Thanks for posting. ITensor DMRG backend has an observer object to handle exactly the situation like yours. You can refer to this section (Observer System for DMRG) in documentation. Your can also refer to the past discussion here.
You can just create a new observer object to achieve the same. Pass this object to the inbuilt DMRG routine. Here is a MWE for storing the output to a file called dmrg_output.txt.
mutable struct DemoObserver <: AbstractObserver
energy_tol::Float64
last_energy::Float64
output_file::String
DemoObserver(energy_tol=0.0, output_file="dmrg_output.txt") = new(energy_tol, 1000.0, output_file)
end
function ITensors.checkdone!(o::DemoObserver; kwargs...)
sw = kwargs[:sweep]
energy = kwargs[:energy]
if abs(energy-o.last_energy)/abs(energy) < o.energy_tol
println("Stopping DMRG after sweep $sw")
return true
end
# Otherwise, update last_energy and keep going
o.last_energy = energy
return false
end
function ITensors.measure!(o::DemoObserver; kwargs...)
energy = kwargs[:energy]
sweep = kwargs[:sweep]
bond = kwargs[:bond]
outputlevel = kwargs[:outputlevel]
# Write to file
open(o.output_file, "a") do f
write(f, "Sweep $sweep, Energy $energy\n")
end
if outputlevel > 0
println("Sweep $sweep at bond $bond, the energy is $energy")
end
end
This is adapted from the linked documentation. Notice the new memeber attribute, output_file in DemoObserver class.
Yeah, you can suppress terminal output by providing outputlevel=0 in the DMRG keyword argument. Here is a driver code for the same. This uses the DemoObserver object to store the output to a file.
let
N = 10
etol = 1E-4
s = siteinds("S=1/2",N)
a = OpSum()
for n=1:N-1
a += "Sz",n,"Sz",n+1
a += 0.5,"S+",n,"S-",n+1
a += 0.5,"S-",n,"S+",n+1
end
H = MPO(a,s)
psi0 = random_mps(s;linkdims=4)
nsweeps = 5
cutoff = 1E-8
maxdim = [10,20,100]
obs = DemoObserver(etol)
energy, psi = dmrg(H,psi0; nsweeps, cutoff, maxdim, observer=obs, outputlevel=0)
return
end
I guess this depends on the Hamiltonian (spectrum gap). In my experience, I have obtained upto 4 excited states reliably. The degeneracy in spectrum may also affect the calculations. Obtaining excited states may require significantly more DMRG sweeps than the ground states.
I see. The current version is 0.6.21 so most likely the reason you are not able to have the random_mps function is that you have not updated ITensors.jl.