-
Notifications
You must be signed in to change notification settings - Fork 15
/
projmpo_apply.jl
90 lines (82 loc) · 2.24 KB
/
projmpo_apply.jl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
using ITensors: ITensor
using ITensors.ITensorMPS: ITensorMPS, AbstractProjMPO, MPO, MPS
"""
A ProjMPOApply represents the application of an
MPO `H` onto an MPS `psi0` but "projected" by
the basis of a different MPS `psi` (which
could be an approximation to H|psi>).
As an implementation of the AbstractProjMPO
type, it supports multiple `nsite` values for
one- and two-site algorithms.
```
*--*--*- -*--*--*--*--*--* <psi|
| | | | | | | | | | |
h--h--h--h--h--h--h--h--h--h--h H
| | | | | | | | | | |
o--o--o- -o--o--o--o--o--o |psi0>
```
"""
mutable struct ProjMPOApply <: AbstractProjMPO
lpos::Int
rpos::Int
nsite::Int
psi0::MPS
H::MPO
LR::Vector{ITensor}
end
function ProjMPOApply(psi0::MPS, H::MPO)
return ProjMPOApply(0, length(H) + 1, 2, psi0, H, Vector{ITensor}(undef, length(H)))
end
function Base.copy(P::ProjMPOApply)
return ProjMPOApply(P.lpos, P.rpos, P.nsite, copy(P.psi0), copy(P.H), copy(P.LR))
end
function ITensorMPS.set_nsite!(P::ProjMPOApply, nsite)
P.nsite = nsite
return P
end
function ITensorMPS.makeL!(P::ProjMPOApply, psi::MPS, k::Int)
# Save the last `L` that is made to help with caching
# for DiskProjMPO
ll = P.lpos
if ll ≥ k
# Special case when nothing has to be done.
# Still need to change the position if lproj is
# being moved backward.
P.lpos = k
return nothing
end
# Make sure ll is at least 0 for the generic logic below
ll = max(ll, 0)
L = lproj(P)
while ll < k
L = L * P.psi0[ll + 1] * P.H[ll + 1] * dag(psi[ll + 1])
P.LR[ll + 1] = L
ll += 1
end
# Needed when moving lproj backward.
P.lpos = k
return P
end
function ITensorMPS.makeR!(P::ProjMPOApply, psi::MPS, k::Int)
# Save the last `R` that is made to help with caching
# for DiskProjMPO
rl = P.rpos
if rl ≤ k
# Special case when nothing has to be done.
# Still need to change the position if rproj is
# being moved backward.
P.rpos = k
return nothing
end
N = length(P.H)
# Make sure rl is no bigger than `N + 1` for the generic logic below
rl = min(rl, N + 1)
R = rproj(P)
while rl > k
R = R * P.psi0[rl - 1] * P.H[rl - 1] * dag(psi[rl - 1])
P.LR[rl - 1] = R
rl -= 1
end
P.rpos = k
return P
end