-
Notifications
You must be signed in to change notification settings - Fork 21
Subspace expansion #160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
wladiKrin
wants to merge
26
commits into
ITensor:main
Choose a base branch
from
b-kloss:subspace-exp-new-interface
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Subspace expansion #160
Changes from 20 commits
Commits
Show all changes
26 commits
Select commit
Hold shift + click to select a range
0d504a1
Initial commit, checking out files from other branch.
6a97fa8
Add subspace expander, compose_updater, truncating extracter.
ce1f170
Actually add compose_updater now.
b6ed42d
Merge branch 'main' into subspace-exp-new-interface
99a95a7
update includes
4393544
Slurp kwargs in scaling by cutoff, and cosmetic change to compose_upd…
8334f59
Merge branch 'main' into subspace-exp-new-interface
73cab2b
Merge branch 'main' into subspace-exp-new-interface
39c6529
Bump compat entry for ITensors.
2d0a744
Merge branch 'main' into subspace-exp-new-interface
22565df
Fix typos in compose_updater.
b542881
Comment out instrumentation in subspace expansion.
94efab9
Fix wrong paths in includes.
679da47
Fix lacking conversion to NamedTuple in compose_updaters.
4dac808
Fix bugs in expand.jl and two-site expansion
cea57a0
Remove duplicate implementation of two-site expansion, leaving only c…
0400446
Update includes.
0c5bb69
Cleanup two-site expansion, unify svd wrapper signature.
b7d08b6
Specify reasonable default for scaling maxdim for subspace expansion.
2896eb1
Add example test for subspace expansion, to be improved later.
732506d
Remove code for global subspace expansion.
b-kloss c6235cd
Remove outdated comments.
b-kloss d4cccbd
Merge branch 'main' into subspace-exp-new-interface
mtfishman 87e1ed9
Merge branch 'main' into subspace-exp-new-interface
mtfishman 833ed21
Merge remote-tracking branch 'origin' into subspace-exp-new-interface
b-kloss 6f4993b
Remove rsvd related files, to be included in separate MR.
b-kloss File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,207 @@ | ||
#ToDo: is this the correct scaling for infinite timestep? DMRG will not have infinite timestep, unless we set it explicitly | ||
#ToDo: implement this as a closure, to be constructed in sweep_plan (where time_step is known) | ||
#scale_cutoff_by_timestep(cutoff;time_step) = isinf(time_step) ? cutoff : cutoff / abs(time_step) | ||
|
||
function two_site_expansion_updater( | ||
init; | ||
state!, | ||
projected_operator!, | ||
outputlevel, | ||
which_sweep, | ||
sweep_plan, | ||
which_region_update, | ||
internal_kwargs, | ||
svd_func_expand=ITensorNetworks.rsvd_iterative, | ||
maxdim, | ||
maxdim_func= (arg;kwargs...) -> identity(arg), | ||
cutoff, | ||
cutoff_func= (arg;kwargs...) -> identity(arg), | ||
use_relative_cutoff=false, | ||
use_absolute_cutoff=true, | ||
) | ||
maxdim=maxdim_func(maxdim;internal_kwargs...) | ||
cutoff=cutoff_func(cutoff;internal_kwargs...) | ||
region = first(sweep_plan[which_region_update]) | ||
typeof(region) <: NamedEdge && return init, (;) | ||
region = only(region) | ||
# figure out next region, since we want to expand there | ||
# ToDo: account for non-integer indices into which_region_update | ||
next_region = if which_region_update == length(sweep_plan) | ||
nothing | ||
else | ||
first(sweep_plan[which_region_update + 1]) | ||
end | ||
previous_region = | ||
which_region_update == 1 ? nothing : first(sweep_plan[which_region_update - 1]) | ||
isnothing(next_region) && return init, (;) | ||
!(typeof(next_region) <: NamedEdge) && return init, (;) | ||
!(region == src(next_region) || region == dst(next_region)) && return init, (;) | ||
next_vertex = src(next_region) == region ? dst(next_region) : src(next_region) | ||
|
||
phi, has_changed = _two_site_expand_core( | ||
init, region, region => next_vertex; | ||
projected_operator!, | ||
state!, | ||
svd_func_expand, | ||
maxdim, | ||
cutoff, | ||
use_relative_cutoff, | ||
use_absolute_cutoff, | ||
) | ||
!has_changed && return init, (;) | ||
return phi, (;) | ||
end | ||
|
||
""" | ||
Returns a function which applies Nullspace projector to an ITensor with matching indices without | ||
explicitly constructing the projector as an ITensor or Network. | ||
""" | ||
function implicit_nullspace(A, linkind) | ||
# only works when applied in the direction of the environment tensor, not the other way (due to use of ITensorNetworkMap which is not reversible) | ||
outind = uniqueinds(A, linkind) | ||
inind = outind #? | ||
# ToDo: implement without ITensorNetworkMap | ||
P = ITensors.ITensorNetworkMaps.ITensorNetworkMap( | ||
[prime(dag(A), linkind), prime(A, linkind)], inind, outind | ||
) | ||
return x::ITensor -> x - P(x) | ||
end | ||
|
||
""" | ||
Performs a local expansion using the two-site projected variance. | ||
The input state should have orthogonality center on a single vertex (region), and phi0 is that site_tensors. | ||
Expansion is performed on vertex that would be visited next (if next vertex is a neighbor of region). | ||
""" | ||
function _two_site_expand_core( | ||
phi0, | ||
region, | ||
vertexpair::Pair; | ||
projected_operator!, | ||
state!, | ||
svd_func_expand, | ||
cutoff, | ||
maxdim, | ||
use_relative_cutoff, | ||
use_absolute_cutoff, | ||
) | ||
# preliminaries | ||
theflux = flux(phi0) | ||
v1 = first(vertexpair) | ||
v2 = last(vertexpair) | ||
verts = [v1, v2] | ||
PH = copy(projected_operator![]) | ||
state = copy(state![]) | ||
old_linkdim = dim(commonind(state[v1],state[v2])) | ||
(old_linkdim >= maxdim) && return phi0, false | ||
# orthogonalize on the edge | ||
#update of environment not strictly necessary here | ||
state, PH, phi = default_extracter(state, PH, edgetype(state)(vertexpair), v1; | ||
internal_kwargs=(;)) | ||
psis = map(n -> state[n], verts) # extract local site tensors | ||
linkinds = map(psi -> commonind(psi, phi), psis) | ||
|
||
# compute nullspace to the left and right | ||
#@timeit_debug timer "nullvector" begin | ||
nullVecs = map(zip(psis, linkinds)) do (psi, linkind) | ||
#return nullspace(psi, linkind; atol=atol) | ||
return ITensorNetworks.implicit_nullspace(psi, linkind) | ||
end | ||
#end | ||
|
||
# update the projected operator | ||
#ToDo: may not be necessary if we use the extracter anyway | ||
PH = set_nsite(PH, 2) | ||
PH = position(PH, state, verts) | ||
|
||
# build environments | ||
g = underlying_graph(PH) | ||
#@timeit_debug timer "build environments" begin | ||
envs = map(zip(verts, psis)) do (n, psi) | ||
return noprime( | ||
mapreduce(*, [v => n for v in neighbors(g, n) if !(v ∈ verts)]; init=psi) do e | ||
return PH.environments[NamedEdge(e)] | ||
end * PH.operator[n], | ||
) | ||
end | ||
#end | ||
|
||
# apply the projection into nullspace, | ||
# FIXME: think through again whether we really want to evaluate null space projector already | ||
envs=[ first(nullVecs)(first(envs)),last(nullVecs)(last(envs))] | ||
ininds = uniqueinds(last(psis), phi) | ||
outinds = uniqueinds(first(psis), phi) | ||
cin = combiner(ininds) | ||
cout = combiner(outinds) | ||
envMap=[cout * envs[1], phi* (cin * envs[2])] | ||
|
||
# factorize | ||
#FIXME: remove specialization on svd_func, define interface for svd_funcs | ||
#@timeit_debug timer "svd_func" begin | ||
U, S, V = svd_func_expand( | ||
envMap, | ||
uniqueinds(inds(cout), outinds); | ||
maxdim=maxdim - old_linkdim, | ||
cutoff=cutoff, | ||
use_relative_cutoff, | ||
use_absolute_cutoff, | ||
) | ||
#end | ||
|
||
# catch cases when we decompose a map of norm==0.0 | ||
(isnothing(U) || iszero(norm(U))) && return phi0, false | ||
#FIXME: somehow the svd funcs sometimes return empty ITensors instead of nothing, that should be caught in the SVD routines instead... | ||
all(isempty.([U, S, V])) && return phi0, false #ToDo: do not rely on isempty here | ||
|
||
# uncombine indices on the non-link-indices | ||
U *= dag(cout) | ||
V *= dag(cin) | ||
|
||
# direct sum the site tensors | ||
#@timeit_debug timer "direct sum" begin | ||
new_psis = map(zip(psis, [U, V])) do (psi, exp_basis) | ||
return ITensors.directsum( | ||
psi => commonind(psi, phi), | ||
exp_basis => uniqueind(exp_basis, psi); | ||
tags=tags(commonind(psi, phi)), | ||
) | ||
end | ||
#end | ||
new_inds = [last(x) for x in new_psis] | ||
new_psis = [first(x) for x in new_psis] | ||
|
||
# extract the expanded linkinds from expanded site tensors and create a zero-tensor | ||
phi_indices = replace( | ||
inds(phi), (commonind(phi, psis[n]) => dag(new_inds[n]) for n in 1:2)... | ||
) | ||
if hasqns(phi) | ||
new_phi = ITensor(eltype(phi), flux(phi), phi_indices...) | ||
#ToDo: Remove? This used to be necessary, but may have been fixed with bugfixes in ITensor | ||
#fill!(new_phi, 0.0) | ||
else | ||
new_phi = ITensor(eltype(phi), phi_indices...) | ||
end | ||
|
||
# set the new bond tensor elements from the old bond tensor | ||
map(eachindex(phi)) do I | ||
v = phi[I] | ||
!iszero(v) && (return new_phi[I] = v) # I think this line errors without the fill! with zeros above | ||
end | ||
|
||
# apply combiners on linkinds #ToDo: figure out why this is strictly necessary | ||
combiners = map( | ||
new_ind -> combiner(new_ind; tags=tags(new_ind), dir=dir(new_ind)), new_inds | ||
) | ||
for (v, new_psi, C) in zip(verts, new_psis, combiners) | ||
state[v] = noprime(new_psi * C) | ||
end | ||
new_phi = dag(first(combiners)) * new_phi * dag(last(combiners)) | ||
|
||
# apply expanded bond tensor to site tensor and reset projected operator to region | ||
state[v1] *= new_phi | ||
new_phi = state[v1] | ||
PH = set_nsite(PH, 1) | ||
PH = position(PH, state, [region]) | ||
projected_operator![] = PH | ||
state![] = state | ||
return new_phi, true | ||
end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this commented out?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be deleted, as discussed in #137.