Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
51 changes: 36 additions & 15 deletions src/algorithms/ED.jl
Original file line number Diff line number Diff line change
@@ -1,24 +1,45 @@
"""
exact_diagonalization(opp::FiniteMPOHamiltonian;
sector=first(sectors(oneunit(physicalspace(opp, 1)))),
len::Int=length(opp), num::Int=1, which::Symbol=:SR,
exact_diagonalization(H::FiniteMPOHamiltonian;
sector=first(sectors(oneunit(physicalspace(H, 1)))),
len::Int=length(H), num::Int=1, which::Symbol=:SR,
alg=Defaults.alg_eigsolve(; dynamic_tols=false))
-> vals, state_vecs, convhist

Use [`KrylovKit.eigsolve`](@extref) to perform exact diagonalization on a
`FiniteMPOHamiltonian` to find its eigenvectors as `FiniteMPS` of maximal rank, essentially
equivalent to dense eigenvectors.

### Arguments
- `H::FiniteMPOHamiltonian`: the Hamiltonian to diagonalize.

### Keyword arguments
- `sector=first(sectors(oneunit(physicalspace(H, 1))))`: the total charge of the
eigenvectors, which is chosen trivial by default.
- `len::Int=length(H)`: the length of the system.
- `num::Int=1`: the number of eigenvectors to find.
- `which::Symbol=:SR`: the kind eigenvalues to find, see [`KrylovKit.eigsolve`](@extref).
- `alg=Defaults.alg_eigsolve(; dynamic_tols=false)`: the diagonalization algorithm to use,
see [`KrylovKit.eigsolve`](@extref).

!!! note "Valid `sector` values"
The total charge of the eigenvectors is imposed by adding a charged auxiliary space as
the leftmost virtualspace of each eigenvector. Specifically, this is achieved by passing
`left=Vect[typeof(sector)](sector => 1)` to the [`FiniteMPS`](@ref) constructor. As
such, the only valid `sector` values (i.e. `sector` values for which the corresponding
eigenstates have valid fusion channels) are those that occur in the dual of the fusion
of all the physical spaces in the system.

"""
function exact_diagonalization(opp::FiniteMPOHamiltonian;
sector=first(sectors(oneunit(physicalspace(opp, 1)))),
len::Int=length(opp), num::Int=1, which::Symbol=:SR,
function exact_diagonalization(H::FiniteMPOHamiltonian;

Check warning on line 33 in src/algorithms/ED.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/ED.jl#L33

Added line #L33 was not covered by tests
sector=first(sectors(oneunit(physicalspace(H, 1)))),
len::Int=length(H), num::Int=1, which::Symbol=:SR,
alg=Defaults.alg_eigsolve(; dynamic_tols=false))
left = ℂ[typeof(sector)](sector => 1)
right = oneunit(left)

middle_site = Int(round(len / 2))

Ot = eltype(opp[1])
Ot = eltype(H[1])

Check warning on line 42 in src/algorithms/ED.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/ED.jl#L42

Added line #L42 was not covered by tests

mpst_type = tensormaptype(spacetype(Ot), 2, 1, storagetype(Ot))
mpsb_type = tensormaptype(spacetype(Ot), 1, 1, storagetype(Ot))
Expand All @@ -28,27 +49,27 @@
ACs = Vector{Union{Missing,mpst_type}}(missing, len)

for i in 1:(middle_site - 1)
ALs[i] = isomorphism(storagetype(Ot), left * physicalspace(opp, i),
fuse(left * physicalspace(opp, i)))
ALs[i] = isomorphism(storagetype(Ot), left * physicalspace(H, i),

Check warning on line 52 in src/algorithms/ED.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/ED.jl#L52

Added line #L52 was not covered by tests
fuse(left * physicalspace(H, i)))
left = _lastspace(ALs[i])'
end
for i in len:-1:(middle_site + 1)
ARs[i] = _transpose_front(isomorphism(storagetype(Ot),
fuse(right * physicalspace(opp, i)'),
right * physicalspace(opp, i)'))
fuse(right * physicalspace(H, i)'),
right * physicalspace(H, i)'))
right = _firstspace(ARs[i])
end
ACs[middle_site] = randomize!(similar(opp[1][1, 1, 1, 1],
left * physicalspace(opp, middle_site) ← right))
ACs[middle_site] = randomize!(similar(H[1][1, 1, 1, 1],

Check warning on line 62 in src/algorithms/ED.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/ED.jl#L62

Added line #L62 was not covered by tests
left * physicalspace(H, middle_site) ← right))
norm(ACs[middle_site]) == 0 && throw(ArgumentError("invalid sector"))
normalize!(ACs[middle_site])

#construct the largest possible finite mps of that length
state = FiniteMPS(ALs, ARs, ACs, Cs)
envs = environments(state, opp)
envs = environments(state, H)

Check warning on line 69 in src/algorithms/ED.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/ED.jl#L69

Added line #L69 was not covered by tests

#optimize the middle site. Because there is no truncation, this single site captures the entire possible hilbert space
H_ac = ∂∂AC(middle_site, state, opp, envs) # this linear operator is now the actual full hamiltonian!
H_ac = ∂∂AC(middle_site, state, H, envs) # this linear operator is now the actual full hamiltonian!

Check warning on line 72 in src/algorithms/ED.jl

View check run for this annotation

Codecov / codecov/patch

src/algorithms/ED.jl#L72

Added line #L72 was not covered by tests
(vals, vecs, convhist) = eigsolve(H_ac, state.AC[middle_site], num, which, alg)

state_vecs = map(vecs) do v
Expand Down
6 changes: 4 additions & 2 deletions src/states/finitemps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,9 @@ By convention, we have that:
FiniteMPS(As::Vector{<:GenericMPSTensor}; normalize=false, overwrite=false)

Construct an MPS via a specification of physical and virtual spaces, or from a list of
tensors `As`. All cases reduce to the latter.
tensors `As`. All cases reduce to the latter. In particular, a state with a non-trivial
total charge can be constructed by passing a non-trivially charged vector space as the
`left` or `right` virtual spaces.

### Arguments
- `As::Vector{<:GenericMPSTensor}`: vector of site tensors
Expand All @@ -50,7 +52,7 @@ tensors `As`. All cases reduce to the latter.
- `maxvirtualspace::S`: maximum virtual space

### Keywords
- `normalize`: normalize the constructed state
- `normalize=true`: normalize the constructed state
- `overwrite=false`: overwrite the given input tensors
- `left=oneunit(S)`: left-most virtual space
- `right=oneunit(S)`: right-most virtual space
Expand Down