@@ -31,47 +31,51 @@ equivalent to dense eigenvectors.
3131
3232"""
3333function exact_diagonalization (H:: FiniteMPOHamiltonian ;
34- sector= first ( sectors ( oneunit ( physicalspace (H, 1 )) )),
35- len :: Int = length (H), num:: Int = 1 , which:: Symbol = :SR ,
34+ sector= one ( sectortype (H )),
35+ num:: Int = 1 , which:: Symbol = :SR ,
3636 alg= Defaults. alg_eigsolve (; dynamic_tols= false ))
37- left = ℂ[typeof (sector)](sector => 1 )
38- right = oneunit (left)
37+ L = length (H)
38+ @assert L > 1 " FiniteMPOHamiltonian must have length > 1"
39+ middle_site = (L >> 1 ) + 1
3940
40- middle_site = Int (round (len / 2 ))
41-
42- Ot = eltype (H[1 ])
43-
44- mpst_type = tensormaptype (spacetype (Ot), 2 , 1 , storagetype (Ot))
45- mpsb_type = tensormaptype (spacetype (Ot), 1 , 1 , storagetype (Ot))
46- Cs = Vector {Union{Missing,mpsb_type}} (missing , len + 1 )
47- ALs = Vector {Union{Missing,mpst_type}} (missing , len)
48- ARs = Vector {Union{Missing,mpst_type}} (missing , len)
49- ACs = Vector {Union{Missing,mpst_type}} (missing , len)
41+ T = storagetype (eltype (H))
42+ TA = tensormaptype (spacetype (H), 2 , 1 , T)
5043
44+ # fuse from left to right
45+ ALs = Vector {Union{Missing,TA}} (missing , L)
46+ left = oneunit (spacetype (H))
5147 for i in 1 : (middle_site - 1 )
52- ALs[i] = isomorphism ( storagetype (Ot), left * physicalspace (H, i),
53- fuse (left * physicalspace (H, i) ))
54- left = _lastspace (ALs[i])'
48+ P = physicalspace (H, i)
49+ ALs[i] = isomorphism (T, left ⊗ P ← fuse (left ⊗ P ))
50+ left = right_virtualspace (ALs[i])
5551 end
56- for i in len: - 1 : (middle_site + 1 )
57- ARs[i] = _transpose_front (isomorphism (storagetype (Ot),
58- fuse (right * physicalspace (H, i)' ),
59- right * physicalspace (H, i)' ))
60- right = _firstspace (ARs[i])
52+
53+ # fuse from right to left
54+ ARs = Vector {Union{Missing,TA}} (missing , L)
55+ right = spacetype (H)(sector => 1 )
56+ for i in reverse ((middle_site + 1 ): L)
57+ P = physicalspace (H, i)
58+ ARs[i] = _transpose_front (isomorphism (T, fuse (right ⊗ P' ) ← right ⊗ P' ))
59+ right = left_virtualspace (ARs[i])
6160 end
62- ACs[middle_site] = randomize! (similar (H[1 ][1 , 1 , 1 , 1 ],
63- left * physicalspace (H, middle_site) ← right))
64- norm (ACs[middle_site]) == 0 && throw (ArgumentError (" invalid sector" ))
65- normalize! (ACs[middle_site])
6661
67- # construct the largest possible finite mps of that length
62+ # center
63+ ACs = Vector {Union{Missing,TA}} (missing , L)
64+ P = physicalspace (H, middle_site)
65+ ACs[middle_site] = rand! (similar (ALs[1 ], left ⊗ P ← right))
66+
67+ TB = tensormaptype (spacetype (H), 1 , 1 , T)
68+ Cs = Vector {Union{Missing,TB}} (missing , L + 1 )
6869 state = FiniteMPS (ALs, ARs, ACs, Cs)
6970 envs = environments (state, H)
7071
71- # optimize the middle site. Because there is no truncation, this single site captures the entire possible hilbert space
72- H_ac = ∂∂AC (middle_site, state, H, envs) # this linear operator is now the actual full hamiltonian!
73- (vals, vecs, convhist) = eigsolve (H_ac, state. AC[middle_site], num, which, alg)
72+ # optimize the middle site
73+ # Because the MPS is full rank - this is equivalent to the full Hamiltonian
74+ AC₀ = state. AC[middle_site]
75+ H_ac = ∂∂AC (middle_site, state, H, envs)
76+ vals, vecs, convhist = eigsolve (H_ac, AC₀, num, which, alg)
7477
78+ # repack eigenstates
7579 state_vecs = map (vecs) do v
7680 cs = copy (state)
7781 cs. AC[middle_site] = v
0 commit comments