@@ -14,25 +14,30 @@ struct DMRG{A, F} <: Algorithm
1414 " maximal amount of iterations"
1515 maxiter:: Int
1616
17+ miniter:: Int
18+
1719 " setting for how much information is displayed"
1820 verbosity:: Int
1921
2022 " algorithm used for the eigenvalue solvers"
2123 alg_eigsolve:: A
2224
25+ expscheme:: Algorithm
26+
2327 " callback function applied after each iteration, of signature `finalize(iter, ψ, H, envs) -> ψ, envs`"
2428 finalize:: F
2529end
2630function DMRG (;
2731 tol = Defaults. tol, maxiter = Defaults. maxiter, alg_eigsolve = (;),
28- verbosity = Defaults. verbosity, finalize = Defaults. _finalize
32+ verbosity = Defaults. verbosity, finalize = Defaults. _finalize,
33+ miniter = 0 , expscheme = NoExpand ()
2934 )
3035 alg_eigsolve′ = alg_eigsolve isa NamedTuple ? Defaults. alg_eigsolve (; alg_eigsolve... ) :
3136 alg_eigsolve
32- return DMRG (tol, maxiter, verbosity, alg_eigsolve′, finalize)
37+ return DMRG (tol, maxiter, miniter, verbosity, alg_eigsolve′, expscheme , finalize)
3338end
3439
35- function find_groundstate! (ψ :: AbstractFiniteMPS , H, alg:: DMRG , envs = environments (ψ, H))
40+ function find_groundstate! (:: FiniteChainStyle , ψ , H, alg:: DMRG , envs = environments (ψ, H))
3641 ϵs = map (pos -> calc_galerkin (pos, ψ, H, ψ, envs), 1 : length (ψ))
3742 ϵ = maximum (ϵs)
3843 log = IterLog (" DMRG" )
@@ -43,17 +48,29 @@ function find_groundstate!(ψ::AbstractFiniteMPS, H, alg::DMRG, envs = environme
4348 alg_eigsolve = updatetol (alg. alg_eigsolve, iter, ϵ)
4449
4550 zerovector! (ϵs)
51+ dir = 1
4652 for pos in [1 : (length (ψ) - 1 ); length (ψ): - 1 : 2 ]
53+ pos == length (ψ) && (dir = - 1 )
4754 h = AC_hamiltonian (pos, ψ, H, ψ, envs)
4855 _, vec = fixedpoint (h, ψ. AC[pos], :SR , alg_eigsolve)
4956 ϵs[pos] = max (ϵs[pos], calc_galerkin (pos, ψ, H, ψ, envs))
50- ψ. AC[pos] = vec
57+ if alg. expscheme isa NoExpand
58+ ψ. AC[pos] = vec
59+ elseif dir == 1
60+ AL, C = left_orth! (vec; positive = true )
61+ AL, C, ψ. AC[pos + 1 ] = changebonds_left (AL, C, ψ. AC[pos + 1 ], alg. expscheme)
62+ ψ. AC[pos] = (AL, C)
63+ elseif dir == - 1
64+ C, temp = right_orth! (_transpose_tail (ψ. AC[pos]; copy = true ); positive = true )
65+ C, ψ. AC[pos - 1 ], temp = changebonds_right (C, ψ. AC[pos - 1 ], temp, alg. expscheme)
66+ ψ. AC[pos] = (C, _transpose_front (temp))
67+ end
5168 end
5269 ϵ = maximum (ϵs)
5370
5471 ψ, envs = alg. finalize (iter, ψ, H, envs):: Tuple{typeof(ψ), typeof(envs)}
5572
56- if ϵ <= alg. tol
73+ if ϵ <= alg. tol && iter > alg . miniter
5774 @infov 2 logfinish! (log, iter, ϵ, expectation_value (ψ, H, envs))
5875 break
5976 end
@@ -83,6 +100,8 @@ struct DMRG2{A, S, F} <: Algorithm
83100 " maximal amount of iterations"
84101 maxiter:: Int
85102
103+ miniter:: Int
104+
86105 " setting for how much information is displayed"
87106 verbosity:: Int
88107
@@ -95,21 +114,23 @@ struct DMRG2{A, S, F} <: Algorithm
95114 " algorithm used for [truncation](@extref MatrixAlgebraKit.TruncationStrategy) of the two-site update"
96115 trscheme:: TruncationStrategy
97116
117+ expscheme:: Algorithm
118+
98119 " callback function applied after each iteration, of signature `finalize(iter, ψ, H, envs) -> ψ, envs`"
99120 finalize:: F
100121end
101122# TODO : find better default truncation
102123function DMRG2 (;
103124 tol = Defaults. tol, maxiter = Defaults. maxiter, verbosity = Defaults. verbosity,
104- alg_eigsolve = (;), alg_svd = Defaults. alg_svd (), trscheme,
105- finalize = Defaults. _finalize
125+ miniter = 0 , alg_eigsolve = (;), alg_svd = Defaults. alg_svd (), trscheme,
126+ expscheme = NoExpand (), finalize = Defaults. _finalize
106127 )
107128 alg_eigsolve′ = alg_eigsolve isa NamedTuple ? Defaults. alg_eigsolve (; alg_eigsolve... ) :
108129 alg_eigsolve
109- return DMRG2 (tol, maxiter, verbosity, alg_eigsolve′, alg_svd, trscheme, finalize)
130+ return DMRG2 (tol, maxiter, miniter, verbosity, alg_eigsolve′, alg_svd, trscheme, expscheme , finalize)
110131end
111132
112- function find_groundstate! (ψ :: AbstractFiniteMPS , H, alg:: DMRG2 , envs = environments (ψ, H))
133+ function find_groundstate! (:: FiniteChainStyle , ψ , H, alg:: DMRG2 , envs = environments (ψ, H))
113134 ϵs = map (pos -> calc_galerkin (pos, ψ, H, ψ, envs), 1 : length (ψ))
114135 ϵ = maximum (ϵs)
115136 log = IterLog (" DMRG2" )
@@ -126,6 +147,7 @@ function find_groundstate!(ψ::AbstractFiniteMPS, H, alg::DMRG2, envs = environm
126147 _, newA2center = fixedpoint (Hac2, ac2, :SR , alg_eigsolve)
127148
128149 al, c, ar = svd_trunc! (newA2center; trunc = alg. trscheme, alg = alg. alg_svd)
150+ al, c = changebonds_left (al, c, alg. expscheme)
129151 normalize! (c)
130152 v = @plansor ac2[1 2 ; 3 4 ] * conj (al[1 2 ; 5 ]) * conj (c[5 ; 6 ]) * conj (ar[6 ; 3 4 ])
131153 ϵs[pos] = max (ϵs[pos], abs (1 - abs (v)))
@@ -141,6 +163,7 @@ function find_groundstate!(ψ::AbstractFiniteMPS, H, alg::DMRG2, envs = environm
141163 _, newA2center = fixedpoint (Hac2, ac2, :SR , alg_eigsolve)
142164
143165 al, c, ar = svd_trunc! (newA2center; trunc = alg. trscheme, alg = alg. alg_svd)
166+ c, ar = changebonds_right (c, ar, alg. expscheme)
144167 normalize! (c)
145168 v = @plansor ac2[1 2 ; 3 4 ] * conj (al[1 2 ; 5 ]) * conj (c[5 ; 6 ]) * conj (ar[6 ; 3 4 ])
146169 ϵs[pos] = max (ϵs[pos], abs (1 - abs (v)))
@@ -152,7 +175,7 @@ function find_groundstate!(ψ::AbstractFiniteMPS, H, alg::DMRG2, envs = environm
152175 ϵ = maximum (ϵs)
153176 ψ, envs = alg. finalize (iter, ψ, H, envs):: Tuple{typeof(ψ), typeof(envs)}
154177
155- if ϵ <= alg. tol
178+ if ϵ <= alg. tol && iter > alg . miniter
156179 @infov 2 logfinish! (log, iter, ϵ, expectation_value (ψ, H, envs))
157180 break
158181 end
@@ -165,7 +188,3 @@ function find_groundstate!(ψ::AbstractFiniteMPS, H, alg::DMRG2, envs = environm
165188 end
166189 return ψ, envs, ϵ
167190end
168-
169- function find_groundstate (ψ, H, alg:: Union{DMRG, DMRG2} , envs... ; kwargs... )
170- return find_groundstate! (copy (ψ), H, alg, envs... ; kwargs... )
171- end
0 commit comments