Hi Miles,

I have tried following your directions but for some reason I am still unable to get the largest truncation error. I have created a new observer containing a max_trunc_err variable, and overloaded the measure! and checkdone! functions so that measure! does max_trunc_err = max(max_trunc_err, truncerr), and checkdone! prints the max_trunc_err and then resets its value to 0. From what I understand, it seems like the checkdone! function is only called at the end of a sweep, while the measure! function is called every step of every sweep, so I thought it should work. However, I always get a value of 0 for the largest truncation error. Here is a minimum working example:

using ITensors

mutable struct DemoObserver <: AbstractObserver

max_trunc_err::Float64

end

function ITensors.measure!(obs::DemoObserver;kwargs...)

truncerr = truncerror(kwargs[:spec])

max_trunc_err=max(obs.max_trunc_err,truncerr)

end

function ITensors.checkdone!(obs::DemoObserver;kwargs...)

println("Largest truncation error = ",obs.max_trunc_err)

obs.max_trunc_err=0.0

return false

end

let

N = 10

max_trunc_err = 0.0

s = siteinds("S=1/2",N)

a = AutoMPO()

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 = randomMPS(s,4)

sweeps = Sweeps(5)

maxdim!(sweeps,10)

obs = DemoObserver(max_trunc_err)

println("Starting DMRG")

energy, psi = dmrg(H,psi0,sweeps; observer=obs, outputlevel=1)

return

end

Do you know what I am doing wrong? Did I misunderstand how/where each of these functions are called?

Best,

Rafael