Open HumpyBlumpy opened 1 year ago
indeed, but the way sparsempo's are implemented at the moment makes this rather difficult (a single element from a sparsempo - sparsemposlice - should really be a proper object, while at the moment it is a lazy view into its parent). So I'm not entirely sure what the interface of push! should be, what kind of object would you want to push onto the sparsempo?
The good news is that we have been working on a bunch of changes to tensorkit/tensoroperations/strided, amongst which is a new "blocktensormap" type, which will replace the current sparsemposlice. A blocktensormap will act like a regular tensormap (you can permute/contract/multiply with it), and sparsempo will simply be a vector of blocktensormaps, making the implementation of push! trivial.
However this will take a bit more time, so in the meantime I'm more then willing to add a temporary push! interface to mpohamiltonian. Did you have some kind of interface in mind?
So what I have in mind is that we start from a window of some size, and non uniform Hamiltonian of the same size
non_uniform_ham = repeat(ham,10);
# modify non_uniform here
Then, as we time-evolve the state, we also dynamically expand the window
for t in 1:100
#expand window here
if window_expanded_right #need to increase non_uniform_ham on the right by one site
push!(non_uniform_ham,ham)
#modify non_uniform_ham
end
if window_expanded_left #need to increase non_uniform_ham on the left by one site
pushfirst!(non_uniform_ham,ham)
#modify non_uniform_ham
end
(ψ,ψ_envs) = timestep!(ψ,non_uniform_ham ,dt,TDVP(expalg=Lanczos(tol=TDVP_tol,eager=true)),ψ_envs)
end
My solution currently is to redefine the Hamiltonian every time step, i.e calling non_uniform_ham = repeat(ham,length(ψ));
.
Is it correct that I should be recalculating the environments like so ψ_envs = environments(ψ,non_uniform_ham ,leftenv(gs_envs,1,gs),rightenv(gs_envs,length(ψ),gs));
every time after I change the Hamiltonian ?
My Hamiltonian is time-dependent, in addition to growing the window.
I have whipped up a hacky version, but I'm not convinced that this should be included in MPSKit in its curent form:
Base.vcat(s::MPSKit.SparseMPOSlice,o::MPOHamiltonian) = MPOHamiltonian(vcat(s,o.data))
Base.vcat(o::MPOHamiltonian,s::MPSKit.SparseMPOSlice) = MPOHamiltonian(vcat(o.data,s))
function Base.vcat(o::SparseMPO,s::MPSKit.SparseMPOSlice)
o.odim == s.odim || throw(ArgumentError("unsupported"))
ndomspaces = similar(o.domspaces,length(o)+1,o.odim);
ndomspaces[1:end-1,:] = o.domspaces;
ndomspaces[end,:] = s.domspaces;
npspaces = [o.pspaces;s.pspace];
nOs = similar(o.Os,length(o)+1,o.odim,o.odim);
nOs[1:end-1,:,:] = o.Os;
nOs[end,:,:] = s.Os;
SparseMPO(nOs,ndomspaces,npspaces)
end
function Base.vcat(s::MPSKit.SparseMPOSlice,o::SparseMPO)
o.odim == s.odim || throw(ArgumentError("unsupported"))
ndomspaces = similar(o.domspaces,length(o)+1,o.odim);
ndomspaces[2:end,:] = o.domspaces;
ndomspaces[1,:] = s.domspaces;
npspaces = [s.pspace;o.pspaces];
nOs = similar(o.Os,length(o)+1,o.odim,o.odim);
nOs[2:end,:,:] = o.Os;
nOs[1,:,:] = s.Os;
SparseMPO(nOs,ndomspaces,npspaces)
end
Your version of updating the environments is indeed correct! However, we do have some code that supports time dependent hamiltonians of the form sum_i f_i(t) H_i, where the idea is that I can simply calculate the environments of H_i instead of recalculating it every timestep (we're using it at the moment in a project where even the left and right states of the window change under time evolution). Is your hamiltonian of such a form, with not that many different f_i's ?
for time dependent hamiltonians, see something like https://github.com/maartenvd/MPSKit.jl/pull/52
It will be nice to have a push! method for SparseMPO and MPOHamiltonian so as to be able to extend the Hamiltonian when working with nonuniform Hamiltonians and a growing mps window.