@@ -38,12 +38,13 @@ $(TYPEDFIELDS)
3838 " include higher-order corrections"
3939 extension:: Bool = true
4040 " approximate compression of corrections, accurate up to order `N`"
41- compression:: Bool = true
41+ compression:: Bool = false
4242end
4343
4444const WI = TaylorCluster (; N= 1 , extension= false , compression= false )
4545
46- function make_time_mpo (H:: MPOHamiltonian , dt:: Number , alg:: TaylorCluster )
46+ function make_time_mpo (H:: MPOHamiltonian , dt:: Number , alg:: TaylorCluster ;
47+ tol= eps (real (scalartype (H)))^ (3 / 4 ))
4748 N = alg. N
4849 τ = - 1im * dt
4950
@@ -80,73 +81,65 @@ function make_time_mpo(H::MPOHamiltonian, dt::Number, alg::TaylorCluster)
8081 if alg. extension
8182 H_next = H_n * H′
8283 linds_next = LinearIndices (ntuple (i -> V, N + 1 ))
83- cinds_next = CartesianIndices (linds_next)
8484 for (i, slice) in enumerate (parent (H_n))
85- for Inext in nonzero_keys (H_next[i])
86- aₑ = cinds_next[Inext[1 ]]
87- bₑ = cinds_next[Inext[4 ]]
88- for c in findall (== (1 ), aₑ. I), d in findall (== (V), bₑ. I)
89- a = TT. deleteat (Tuple (aₑ), c)
90- b = TT. deleteat (Tuple (bₑ), d)
91- if all (> (1 ), b) && ! (all (in ((1 , V), a)) && any (== (V), a))
92- n1 = count (== (1 ), a) + 1
93- n3 = count (== (V), b) + 1
94- factor = τ * factorial (N) / (factorial (N + 1 ) * n1 * n3)
95- slice[linds[a... ], 1 , 1 , linds[b... ]] += factor * H_next[i][Inext]
96- end
85+ for a in cinds, b in cinds
86+ all (> (1 ), b. I) || continue
87+ all (in ((1 , V)), a. I) && any (== (V), a. I) && continue
88+
89+ n1 = count (== (1 ), a. I) + 1
90+ n3 = count (== (V), b. I) + 1
91+ factor = τ * factorial (N) / (factorial (N + 1 ) * n1 * n3)
92+
93+ for c in 1 : (N + 1 ), d in 1 : (N + 1 )
94+ aₑ = insert! ([a. I... ], c, 1 )
95+ bₑ = insert! ([b. I... ], d, V)
96+
97+ # TODO : use VectorInterface for memory efficiency
98+ slice[linds[a], 1 , 1 , linds[b]] += factor *
99+ H_next[i][linds_next[aₑ... ], 1 , 1 ,
100+ linds_next[bₑ... ]]
97101 end
98102 end
99103 end
100104 end
101105
102106 # loopback step: Algorithm 1
103107 # constructing the Nth order time evolution MPO
104- if H isa FiniteMPOHamiltonian
105- mpo = FiniteMPO (parent (H_n))
106- else
107- mpo = InfiniteMPO (parent (H_n))
108- end
108+ mpo = MPO (parent (H_n))
109109 for slice in parent (mpo)
110- for (I, v) in nonzero_pairs (slice)
111- a = cinds[I[1 ]]
112- b = cinds[I[4 ]]
113- if all (in ((1 , V)), a. I) && any (!= (1 ), a. I)
114- delete! (slice, I)
115- elseif any (!= (1 ), b. I) && all (in ((1 , V)), b. I)
116- exponent = count (== (V), b. I)
117- factor = τ^ exponent * factorial (N - exponent) / factorial (N)
118- Idst = CartesianIndex (Base. setindex (I. I, 1 , 4 ))
119- slice[Idst] += factor * v
120- delete! (slice, I)
110+ for b in cinds[2 : end ]
111+ all (in ((1 , V)), b. I) || continue
112+
113+ b_lin = linds[b]
114+ a = count (== (V), b. I)
115+ factor = τ^ a * factorial (N - a) / factorial (N)
116+ slice[:, 1 , 1 , 1 ] = slice[:, 1 , 1 , 1 ] + factor * slice[:, 1 , 1 , b_lin]
117+ for I in nonzero_keys (slice)
118+ (I[1 ] == b_lin || I[4 ] == b_lin) && delete! (slice, I)
121119 end
122120 end
123121 end
124122
125123 # Remove equivalent rows and columns: Algorithm 2
126124 for slice in parent (mpo)
127- for I in nonzero_keys (slice)
128- a = cinds[I[1 ]]
129- a_sort = CartesianIndex (sort (collect (a. I); by= (!= (1 )))... )
130- n1_a = count (== (1 ), a. I)
131- n3_a = count (== (V), a. I)
132- if n3_a <= n1_a && a_sort != a
133- Idst = CartesianIndex (Base. setindex (I. I, linds[a_sort], 1 ))
134- slice[Idst] += slice[I]
135- delete! (slice, I)
136- elseif a != a_sort
137- delete! (slice, I)
138- end
125+ for c in cinds
126+ c_lin = linds[c]
127+ s_c = CartesianIndex (sort (collect (c. I); by= (!= (1 )))... )
128+ s_r = CartesianIndex (sort (collect (c. I); by= (!= (V)))... )
129+
130+ n1 = count (== (1 ), c. I)
131+ n3 = count (== (V), c. I)
139132
140- b = cinds[I[ 4 ]]
141- b_sort = CartesianIndex ( sort ( collect (b . I); by = ( != (V))) ... )
142- n1_b = count ( == ( 1 ), b . I )
143- n3_b = count ( == (V), b . I)
144- if n3_b > n1_b && b_sort != b
145- Idst = CartesianIndex (Base . setindex (I . I, linds[b_sort], 4 ))
146- slice[Idst] += slice[I ]
147- delete! (slice, I )
148- elseif b != b_sort
149- delete! (slice, I)
133+ if n3 <= n1 && s_c != c
134+ slice[linds[s_c], 1 , 1 , :] += slice[c_lin, 1 , 1 , :]
135+ for I in nonzero_keys (slice )
136+ (I[ 1 ] == c_lin || I[ 4 ] == c_lin) && delete! (slice, I)
137+ end
138+ elseif n3 > n1 && s_r != c
139+ slice[:, 1 , 1 , linds[s_r]] += slice[:, 1 , 1 , c_lin ]
140+ for I in nonzero_keys (slice )
141+ (I[ 1 ] == c_lin || I[ 4 ] == c_lin) && delete! (slice, I)
142+ end
150143 end
151144 end
152145 end
@@ -161,14 +154,10 @@ function make_time_mpo(H::MPOHamiltonian, dt::Number, alg::TaylorCluster)
161154 b = CartesianIndex (replace (a. I, V => 1 ))
162155 b_lin = linds[b]
163156 factor = τ^ n1 * factorial (N - n1) / factorial (N)
157+ slice[:, 1 , 1 , b_lin] += factor * slice[:, 1 , 1 , a_lin]
158+
164159 for I in nonzero_keys (slice)
165- if I[4 ] == a_lin
166- Idst = CartesianIndex (Base. setindex (I. I, b_lin, 4 ))
167- slice[Idst] += factor * slice[I]
168- delete! (slice, I)
169- elseif I[1 ] == a_lin
170- delete! (slice, I)
171- end
160+ (I[1 ] == a_lin || I[4 ] == a_lin) && delete! (slice, I)
172161 end
173162 end
174163 end
@@ -180,7 +169,7 @@ function make_time_mpo(H::MPOHamiltonian, dt::Number, alg::TaylorCluster)
180169 mpo[end ] = mpo[end ][:, :, :, 1 ]
181170 end
182171
183- return remove_orphans! (mpo)
172+ return remove_orphans! (mpo; tol = tol )
184173end
185174
186175has_prod_elem (slice, t1, t2) = all (map (x -> contains (slice, x... ), zip (t1, t2)))
@@ -223,65 +212,6 @@ function interweave(a, b)
223212 end
224213end
225214
226- # function make_time_mpo(H::MPOHamiltonian{S,T}, dt, alg::WII) where {S,T}
227- # WA = PeriodicArray{T,3}(undef, H.period, H.odim - 2, H.odim - 2)
228- # WB = PeriodicArray{T,2}(undef, H.period, H.odim - 2)
229- # WC = PeriodicArray{T,2}(undef, H.period, H.odim - 2)
230- # WD = PeriodicArray{T,1}(undef, H.period)
231- #
232- # δ = dt * (-1im)
233- #
234- # for i in 1:(H.period), j in 2:(H.odim - 1), k in 2:(H.odim - 1)
235- # init_1 = isometry(storagetype(H[i][1, H.odim]), codomain(H[i][1, H.odim]),
236- # domain(H[i][1, H.odim]))
237- # init = [init_1, zero(H[i][1, k]), zero(H[i][j, H.odim]), zero(H[i][j, k])]
238- #
239- # (y, convhist) = exponentiate(1.0, RecursiveVec(init),
240- # Arnoldi(; tol=alg.tol, maxiter=alg.maxiter)) do x
241- # out = similar(x.vecs)
242- #
243- # @plansor out[1][-1 -2; -3 -4] := δ * x[1][-1 1; -3 -4] *
244- # H[i][1, H.odim][2 3; 1 4] * τ[-2 4; 2 3]
245- #
246- # @plansor out[2][-1 -2; -3 -4] := δ * x[2][-1 1; -3 -4] *
247- # H[i][1, H.odim][2 3; 1 4] * τ[-2 4; 2 3]
248- # @plansor out[2][-1 -2; -3 -4] += sqrt(δ) * x[1][1 2; -3 4] *
249- # H[i][1, k][-1 -2; 3 -4] * τ[3 4; 1 2]
250- #
251- # @plansor out[3][-1 -2; -3 -4] := δ * x[3][-1 1; -3 -4] *
252- # H[i][1, H.odim][2 3; 1 4] * τ[-2 4; 2 3]
253- # @plansor out[3][-1 -2; -3 -4] += sqrt(δ) * x[1][1 2; -3 4] *
254- # H[i][j, H.odim][-1 -2; 3 -4] * τ[3 4; 1 2]
255- #
256- # @plansor out[4][-1 -2; -3 -4] := δ * x[4][-1 1; -3 -4] *
257- # H[i][1, H.odim][2 3; 1 4] * τ[-2 4; 2 3]
258- # @plansor out[4][-1 -2; -3 -4] += x[1][1 2; -3 4] * H[i][j, k][-1 -2; 3 -4] *
259- # τ[3 4; 1 2]
260- # @plansor out[4][-1 -2; -3 -4] += sqrt(δ) * x[2][1 2; -3 -4] *
261- # H[i][j, H.odim][-1 -2; 3 4] * τ[3 4; 1 2]
262- # @plansor out[4][-1 -2; -3 -4] += sqrt(δ) * x[3][-1 4; -3 3] *
263- # H[i][1, k][2 -2; 1 -4] * τ[3 4; 1 2]
264- #
265- # return RecursiveVec(out)
266- # end
267- # convhist.converged == 0 &&
268- # @warn "exponentiate failed to converge: normres = $(convhist.normres)"
269- #
270- # WA[i, j - 1, k - 1] = y[4]
271- # WB[i, j - 1] = y[3]
272- # WC[i, k - 1] = y[2]
273- # WD[i] = y[1]
274- # end
275- #
276- # W2 = PeriodicArray{Union{T,Missing},3}(missing, H.period, H.odim - 1, H.odim - 1)
277- # W2[:, 2:end, 2:end] = WA
278- # W2[:, 2:end, 1] = WB
279- # W2[:, 1, 2:end] = WC
280- # W2[:, 1, 1] = WD
281- #
282- # return SparseMPO(W2)
283- # end
284-
285215function make_time_mpo (H:: InfiniteMPOHamiltonian{T} , dt, alg:: WII ) where {T}
286216 WA = H. A
287217 WB = H. B
0 commit comments