1- function approximate (ost:: MultilineMPS , toapprox:: Tuple{<:MultilineMPO,<:MultilineMPS} ,
2- alg:: IDMRG1 , oenvs= environments (ost, toapprox))
3- ψ = copy (ost)
4- mpo, above = toapprox
5- envs = IDMRGEnvironments (ost, oenvs)
1+ function approximate! (ψ:: MultilineMPS , toapprox:: Tuple{<:MultilineMPO,<:MultilineMPS} ,
2+ alg:: IDMRG1 , envs= environments (ψ, toapprox))
63 log = IterLog (" IDMRG" )
74 ϵ:: Float64 = 2 * alg. tol
85
@@ -12,31 +9,27 @@ function approximate(ost::MultilineMPS, toapprox::Tuple{<:MultilineMPO,<:Multili
129 C_current = ψ. C[:, 0 ]
1310
1411 # left to right sweep
15- for col in 1 : size (ψ, 2 ), row in 1 : size (ψ, 1 )
16- h = MPO_∂∂AC (mpo[row, col], leftenv (envs, row, col),
17- rightenv (envs, row, col))
18- ψ. AC[row + 1 , col] = h * above. AC[row, col]
19- normalize! (ψ. AC[row + 1 , col])
20-
21- ψ. AL[row + 1 , col], ψ. C[row + 1 , col] = leftorth (ψ. AC[row + 1 , col])
22-
23- tm = TransferMatrix (above. AL[row, col], mpo[row, col], ψ. AL[row + 1 , col])
24- setleftenv! (envs, row, col + 1 , normalize (leftenv (envs, row, col) * tm))
12+ for col in 1 : size (ψ, 2 )
13+ for row in 1 : size (ψ, 1 )
14+ ψ. AC[row + 1 , col] = ac_proj (row, col, ψ, toapprox, envs)
15+ normalize! (ψ. AC[row + 1 , col])
16+ ψ. AL[row + 1 , col], ψ. C[row + 1 , col] = leftorth! (ψ. AC[row + 1 , col])
17+ end
18+ transfer_leftenv! (envs, ψ, toapprox, col + 1 )
2519 end
2620
2721 # right to left sweep
28- for col in size (ψ, 2 ): - 1 : 1 , row in 1 : size (ψ, 1 )
29- h = MPO_∂∂AC (mpo[row, col], leftenv (envs, row, col),
30- rightenv (envs, row, col))
31- ψ. AC[row + 1 , col] = h * above. AC[row, col]
32- normalize! (ψ. AC[row + 1 , col])
33-
34- ψ. C[row + 1 , col - 1 ], temp = rightorth (_transpose_tail (ψ. AC[row + 1 , col]))
35- ψ. AR[row + 1 , col] = _transpose_front (temp)
36-
37- tm = TransferMatrix (above. AR[row, col], mpo[row, col], ψ. AR[row + 1 , col])
38- setrightenv! (envs, row, col - 1 , normalize (tm * rightenv (envs, row, col)))
22+ for col in size (ψ, 2 ): - 1 : 1
23+ for row in 1 : size (ψ, 1 )
24+ ψ. AC[row + 1 , col] = ac_proj (row, col, ψ, toapprox, envs)
25+ normalize! (ψ. AC[row + 1 , col])
26+ ψ. C[row + 1 , col - 1 ], temp = rightorth! (_transpose_tail (ψ. AC[row + 1 ,
27+ col]))
28+ ψ. AR[row + 1 , col] = _transpose_front (temp)
29+ end
30+ transfer_rightenv! (envs, ψ, toapprox, col - 1 )
3931 end
32+ normalize! (envs, ψ, toapprox)
4033
4134 ϵ = norm (C_current - ψ. C[:, 0 ])
4235
@@ -52,72 +45,62 @@ function approximate(ost::MultilineMPS, toapprox::Tuple{<:MultilineMPO,<:Multili
5245 end
5346 end
5447
48+ # TODO : immediately compute in-place
5549 nst = MultilineMPS (map (x -> x, ψ. AR); tol= alg. tol_gauge)
56- nenvs = environments (nst, toapprox)
57- return nst, nenvs, ϵ
50+ copy! (ψ, nst) # ensure output destination is unchanged
51+
52+ recalculate! (envs, ψ, toapprox)
53+ return ψ, envs, ϵ
5854end
5955
60- function approximate (ost:: MultilineMPS , toapprox:: Tuple{<:MultilineMPO,<:MultilineMPS} ,
61- alg:: IDMRG2 , oenvs= environments (ost, toapprox))
62- length (ost) < 2 && throw (ArgumentError (" unit cell should be >= 2" ))
63- mpo, above = toapprox
64- ψ = copy (ost)
65- envs = IDMRGEnvironments (ost, oenvs)
56+ function approximate! (ψ:: MultilineMPS , toapprox:: Tuple{<:MultilineMPO,<:MultilineMPS} ,
57+ alg:: IDMRG2 , envs= environments (ψ, toapprox))
58+ size (ψ, 2 ) < 2 && throw (ArgumentError (" unit cell should be >= 2" ))
6659 ϵ:: Float64 = 2 * alg. tol
6760 log = IterLog (" IDMRG2" )
61+ O, ϕ = toapprox
6862
6963 LoggingExtras. withlevel (; alg. verbosity) do
7064 @infov 2 loginit! (log, ϵ)
7165 for iter in 1 : (alg. maxiter)
7266 C_current = ψ. C[:, 0 ]
7367
7468 # sweep from left to right
75- for col in 1 : size (ψ, 2 ), row in 1 : size (ψ, 1 )
76- ac2 = above. AC[row, col] * _transpose_tail (above. AR[row, col + 1 ])
77- h = MPO_∂∂AC2 (mpo[row, col], mpo[row, col + 1 ], leftenv (envs, row, col),
78- rightenv (envs, row, col + 1 ))
79-
80- al, c, ar, = tsvd! (h * ac2; trunc= alg. trscheme, alg= TensorKit. SVD ())
81- normalize! (c)
82-
83- ψ. AL[row + 1 , col] = al
84- ψ. C[row + 1 , col] = complex (c)
85- ψ. AR[row + 1 , col + 1 ] = _transpose_front (ar)
86-
87- setleftenv! (envs, row, col + 1 ,
88- normalize (leftenv (envs, row, col) *
89- TransferMatrix (above. AL[row, col], mpo[row, col],
90- ψ. AL[row + 1 , col])))
91- setrightenv! (envs, row, col,
92- normalize (TransferMatrix (above. AR[row, col + 1 ],
93- mpo[row, col + 1 ],
94- ψ. AR[row + 1 , col + 1 ]) *
95- rightenv (envs, row, col + 1 )))
69+ for col in 1 : size (ψ, 2 )
70+ for row in 1 : size (ψ, 1 )
71+ AC2′ = ac2_proj (row, col, ψ, toapprox, envs)
72+ al, c, ar, = tsvd! (AC2′; trunc= alg. trscheme, alg= TensorKit. SVD ())
73+ normalize! (c)
74+
75+ ψ. AL[row + 1 , col] = al
76+ ψ. C[row + 1 , col] = complex (c)
77+ ψ. AR[row + 1 , col + 1 ] = _transpose_front (ar)
78+ ψ. AC[row + 1 , col + 1 ] = _transpose_front (c * ar)
79+ end
80+ transfer_leftenv! (envs, ψ, toapprox, col + 1 )
81+ transfer_rightenv! (envs, ψ, toapprox, col)
9682 end
83+ normalize! (envs, ψ, toapprox)
9784
9885 # sweep from right to left
99- for col in (size (ψ, 2 ) - 1 ): - 1 : 0 , row in 1 : size (ψ, 1 )
100- ac2 = above. AL[row, col] * _transpose_tail (above. AC[row, col + 1 ])
101- h = MPO_∂∂AC2 (mpo[row, col], mpo[row, col + 1 ], leftenv (envs, row, col),
102- rightenv (envs, row, col + 1 ))
103-
104- al, c, ar, = tsvd! (h * ac2; trunc= alg. trscheme, alg= TensorKit. SVD ())
105- normalize! (c)
106-
107- ψ. AL[row + 1 , col] = al
108- ψ. C[row + 1 , col] = complex (c)
109- ψ. AR[row + 1 , col + 1 ] = _transpose_front (ar)
110-
111- setleftenv! (envs, row, col + 1 ,
112- normalize (leftenv (envs, row, col) *
113- TransferMatrix (above. AL[row, col], mpo[row, col],
114- ψ. AL[row + 1 , col])))
115- setrightenv! (envs, row, col,
116- normalize (TransferMatrix (above. AR[row, col + 1 ],
117- mpo[row, col + 1 ],
118- ψ. AR[row + 1 , col + 1 ]) *
119- rightenv (envs, row, col + 1 )))
86+ for col in (size (ψ, 2 ) - 1 ): - 1 : 0
87+ for row in 1 : size (ψ, 1 )
88+ # TODO : also write this as ac2_proj?
89+ AC2 = ϕ. AL[row, col] * _transpose_tail (ϕ. AC[row, col + 1 ])
90+ AC2′ = ∂AC2 (AC2, O[row, col], O[row, col + 1 ],
91+ leftenv (envs[row], col, ψ[row]),
92+ rightenv (envs[row], col, ψ[row]))
93+ al, c, ar, = tsvd! (AC2′; trunc= alg. trscheme, alg= TensorKit. SVD ())
94+ normalize! (c)
95+
96+ ψ. AL[row + 1 , col] = al
97+ ψ. C[row + 1 , col] = complex (c)
98+ ψ. AR[row + 1 , col + 1 ] = _transpose_front (ar)
99+ end
100+ transfer_leftenv! (envs, ψ, toapprox, col + 1 )
101+ transfer_rightenv! (envs, ψ, toapprox, col)
120102 end
103+ normalize! (envs, ψ, toapprox)
121104
122105 # update error
123106 ϵ = sum (zip (C_current, ψ. C[:, 0 ])) do (c1, c2)
@@ -139,7 +122,10 @@ function approximate(ost::MultilineMPS, toapprox::Tuple{<:MultilineMPO,<:Multili
139122 end
140123 end
141124
125+ # TODO : immediately compute in-place
142126 nst = MultilineMPS (map (x -> x, ψ. AR); tol= alg. tol_gauge)
143- nenvs = environments (nst, toapprox)
144- return nst, nenvs, ϵ
127+ copy! (ψ, nst) # ensure output destination is unchanged
128+ recalculate! (envs, ψ, toapprox)
129+
130+ return ψ, envs, ϵ
145131end
0 commit comments