Skip to content

Commit 1489817

Browse files
authored
Customizable cell translation function (#53)
1 parent 4c64d60 commit 1489817

16 files changed

+878
-153
lines changed

src/ITensorInfiniteMPS.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ include("infinitecanonicalmps.jl")
3535
include("infinitempomatrix.jl")
3636
include("transfermatrix.jl")
3737
include("models/models.jl")
38+
include("models/fqhe13.jl")
3839
include("models/ising.jl")
3940
include("models/ising_extended.jl")
4041
include("models/heisenberg.jl")
@@ -73,6 +74,7 @@ export Cell,
7374
reference,
7475
subspace_expansion,
7576
translatecell,
77+
translator,
7678
tdvp,
7779
vumps,
7880
,

src/abstractinfinitemps.jl

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -16,17 +16,35 @@ function (T::Type{MPST})(
1616
return MPST(data, llim, rlim, false)
1717
end
1818

19+
function (T::Type{MPST})(
20+
data::CelledVector{<:ITensor,F}, llim, rlim
21+
) where {MPST<:AbstractInfiniteMPS,F}
22+
return MPST(data, llim, rlim, false)
23+
end
24+
1925
# TODO: use InfiniteMPS(data, -∞, ∞) when AbstractMPS
2026
# is written more generically
2127
function (T::Type{MPST})(data::Vector{<:ITensor}) where {MPST<:AbstractInfiniteMPS}
2228
return MPST(data, 0, length(data) + 1)
2329
end
2430

31+
function (T::Type{MPST})(
32+
data::Vector{<:ITensor}, translator::Function
33+
) where {MPST<:AbstractInfiniteMPS}
34+
return MPST(CelledVector(data, translator), 0, length(data) + 1)
35+
end
36+
2537
# TODO: better way to determine left and right limits
2638
function (T::Type{MPST})(ψ::MPS; reverse::Bool=false) where {MPST<:AbstractInfiniteMPS}
2739
return MPST(ITensors.data(ψ), ψ.llim, ψ.rlim, reverse)
2840
end
2941

42+
function (T::Type{MPST})(
43+
ψ::MPS, translator::Function; reverse::Bool=false
44+
) where {MPST<:AbstractInfiniteMPS}
45+
return MPST(CelledVector(ITensors.data(ψ), translator), ψ.llim, ψ.rlim, reverse)
46+
end
47+
3048
# TODO: better way to determine left and right limits
3149
function (T::Type{MPST})(
3250
ψ::MPS, llim::Integer, rlim::Integer; reverse::Bool=false
@@ -38,6 +56,12 @@ function (T::Type{MPST})(N::Integer; reverse::Bool=false) where {MPST<:AbstractI
3856
return MPST(MPS(N); reverse=reverse)
3957
end
4058

59+
function (T::Type{MPST})(
60+
N::Integer, translator::Function; reverse::Bool=false
61+
) where {MPST<:AbstractInfiniteMPS}
62+
return MPST(MPS(N), translator; reverse=reverse)
63+
end
64+
4165
function Base.reverse::MPST) where {MPST<:AbstractInfiniteMPS}
4266
return MPST(reverse.data), ψ.rlim, ψ.llim, !ψ.reverse)
4367
end
@@ -94,13 +118,13 @@ _setindex_cell1!(ψ::AbstractInfiniteMPS, val, n::Integer) = (ITensors.data(ψ)[
94118
function getindex::AbstractInfiniteMPS, n::Integer)
95119
cellₙ = cell(ψ, n)
96120
siteₙ = cellsite(ψ, n)
97-
return translatecell(_getindex_cell1(ψ, siteₙ), cellₙ - 1)
121+
return translatecell(translator(ψ), _getindex_cell1(ψ, siteₙ), cellₙ - 1)
98122
end
99123

100124
function setindex!::AbstractInfiniteMPS, T::ITensor, n::Int)
101125
cellₙ = cell(ψ, n)
102126
siteₙ = cellsite(ψ, n)
103-
_setindex_cell1!(ψ, translatecell(T, -(cellₙ - 1)), siteₙ)
127+
_setindex_cell1!(ψ, translatecell(translator(ψ), T, -(cellₙ - 1)), siteₙ)
104128
return ψ
105129
end
106130

@@ -154,12 +178,12 @@ end
154178
# MPS from an InfiniteMPS
155179
function ITensors.prime(::typeof(linkinds), ψ::AbstractInfiniteMPS)
156180
ψextended′ = prime(linkinds, ψ[0:(nsites(ψ) + 1)])
157-
return typeof(ψ)(ψextended′[2:(end - 1)]; reverse=ψ.reverse)
181+
return typeof(ψ)(ψextended′[2:(end - 1)], translator(ψ); reverse=ψ.reverse)
158182
end
159183

160184
function ITensors.dag::AbstractInfiniteMPS)
161185
ψdag = dag(ψ[1:nsites(ψ)])
162-
return typeof(ψ)(ψdag; reverse=ψ.reverse)
186+
return typeof(ψ)(ψdag, translator(ψ); reverse=ψ.reverse)
163187
end
164188

165189
ITensors.linkinds::AbstractInfiniteMPS, n1n2) = linkinds(ψ, Pair(n1n2...))
@@ -206,10 +230,10 @@ end
206230

207231
function ITensors.linkinds(f::typeof(only), ψ::AbstractInfiniteMPS)
208232
N = nsites(ψ)
209-
return CelledVector([f(commoninds(ψ[n], ψ[n + 1])) for n in 1:N])
233+
return CelledVector([f(commoninds(ψ[n], ψ[n + 1])) for n in 1:N], translator(ψ))
210234
end
211235

212236
function ITensors.siteinds(f::typeof(only), ψ::AbstractInfiniteMPS)
213237
N = nsites(ψ)
214-
return CelledVector([f(uniqueinds(ψ[n], ψ[n - 1], ψ[n + 1])) for n in 1:N])
238+
return CelledVector([f(uniqueinds(ψ[n], ψ[n - 1], ψ[n + 1])) for n in 1:N], translator(ψ))
215239
end

src/celledvectors.jl

Lines changed: 41 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -36,39 +36,68 @@ function getsite(ts::TagSet)
3636
return parse(Int, celltag[(length(indextagprefix()) + 1):end])
3737
end
3838

39-
function translatecell(ts::TagSet, n::Integer)
39+
##Translation operators
40+
41+
#Default translate cell
42+
function translatecelltags(ts::TagSet, n::Integer)
4043
ncell = getcell(ts)
4144
if isnothing(ncell)
4245
return ts
4346
end
4447
return replacetags(ts, celltags(ncell) => celltags(ncell + n))
4548
end
4649

47-
function translatecell(i::Index, n::Integer)
50+
function translatecelltags(i::Index, n::Integer)
4851
ts = tags(i)
49-
translated_ts = translatecell(ts, n)
52+
translated_ts = translatecelltags(ts, n)
5053
return replacetags(i, ts => translated_ts)
5154
end
5255

53-
function translatecell(is::Union{<:Tuple,<:Vector}, n::Integer)
54-
return translatecell.(is, n)
56+
#Transfer the functional properties
57+
#translatecell(translator, T::ITensor, n::Integer) = translator(T, n)
58+
function translatecell(translator::Function, T::ITensor, n::Integer)
59+
return ITensors.setinds(T, translatecell(translator, inds(T), n))
60+
end
61+
translatecell(translator::Function, T::MPO, n::Integer) = translatecell.(translator, T, n)
62+
function translatecell(translator::Function, T::Matrix{ITensor}, n::Integer)
63+
return translatecell.(translator, T, n)
64+
end
65+
translatecell(translator::Function, i::Index, n::Integer) = translator(i, n)
66+
function translatecell(translator::Function, is::Union{<:Tuple,<:Vector}, n::Integer)
67+
return translatecell.(translator, is, n)
5568
end
5669

57-
translatecell(T::ITensor, n::Integer) = ITensors.setinds(T, translatecell(inds(T), n))
58-
translatecell(T::MPO, n::Integer) = translatecell.(T, n)
59-
translatecell(T::Matrix{ITensor}, n::Integer) = translatecell.(T, n)
70+
#Default behavior
71+
#translatecell(T::ITensor, n::Integer) = ITensors.setinds(T, translatecell(inds(T), n))
72+
#translatecell(T::MPO, n::Integer) = translatecell.(T, n)
73+
#translatecell(T::Matrix{ITensor}, n::Integer) = translatecell.(T, n)
6074

61-
struct CelledVector{T} <: AbstractVector{T}
75+
struct CelledVector{T,F} <: AbstractVector{T}
6276
data::Vector{T}
77+
translator::F
6378
end
6479
ITensors.data(cv::CelledVector) = cv.data
80+
translator(cv::CelledVector) = cv.translator
6581

82+
Base.copy(m::CelledVector) = typeof(m)(copy(m.data), m.translator) #needed to carry the translator when copying
83+
Base.deepcopy(m::CelledVector) = typeof(m)(deepcopy(m.data), m.translator) #needed to carry the translator when copying
6684
Base.convert(::Type{CelledVector{T}}, v::Vector) where {T} = CelledVector{T}(v)
6785

6886
function CelledVector{T}(::UndefInitializer, n::Integer) where {T}
6987
return CelledVector(Vector{T}(undef, n))
7088
end
7189

90+
function CelledVector{T}(::UndefInitializer, n::Integer, translator::Function) where {T}
91+
return CelledVector(Vector{T}(undef, n), translator::Function)
92+
end
93+
CelledVector(v::AbstractVector) = CelledVector(v, translatecelltags)
94+
function CelledVector{T}(v::Vector{T}) where {T}
95+
return CelledVector(v, translatecelltags)
96+
end
97+
function CelledVector{T}(v::Vector{T}, translator::Function) where {T}
98+
return CelledVector(v, translator)
99+
end
100+
72101
"""
73102
celllength(cv::CelledVector)
74103
@@ -105,12 +134,12 @@ _getindex_cell1(cv::CelledVector, n::Int) = ITensors.data(cv)[n]
105134
_setindex_cell1!(cv::CelledVector, val, n::Int) = (ITensors.data(cv)[n] = val)
106135

107136
# Fallback
108-
translatecell(x, ::Integer) = x
137+
#translatecell(x, ::Integer) = x # I think this is useless now
109138

110139
function getindex(cv::CelledVector, n::Int)
111140
cellₙ = cell(cv, n)
112141
siteₙ = cellindex(cv, n)
113-
return translatecell(_getindex_cell1(cv, siteₙ), cellₙ - 1)
142+
return translatecell(cv.translator, _getindex_cell1(cv, siteₙ), cellₙ - 1)
114143
end
115144

116145
# Do we need this definition? Maybe uses generic Julia fallback
@@ -137,44 +166,8 @@ getindex(cv::CelledVector, c::Cell) = cv[eachindex(cv, c)]
137166
function setindex!(cv::CelledVector, T, n::Int)
138167
cellₙ = cell(cv, n)
139168
siteₙ = cellindex(cv, n)
140-
_setindex_cell1!(cv, translatecell(T, -(cellₙ - 1)), siteₙ)
169+
_setindex_cell1!(cv, translatecell(cv.translator, T, -(cellₙ - 1)), siteₙ)
141170
return cv
142171
end
143172

144173
celltags(cell) = TagSet("c=$cell")
145-
146-
#
147-
# TODO: This version accepts a more general translation function between
148-
# unit cells
149-
#
150-
151-
#struct CelledVector{T, F, FINV} <: AbstractVector{T}
152-
# data::Vector{T}
153-
# f::F
154-
#end
155-
#
156-
#CelledVector(v::AbstractVector) = CelledVector(v, identity)
157-
#
158-
#cell_length(cv::CelledVector) = length(cv.data)
159-
#
160-
## Determine which cell the index is in
161-
#cell(cv::CelledVector, n::Integer) = fld1(n, cell_length(cv))
162-
#
163-
## Determine the index in the cell where the index sits
164-
#cell_index(cv::CelledVector, n::Integer) = mod1(n, cell_length(cv))
165-
#
166-
## Return the cell and the cell index
167-
#cell_and_cell_index(cv::CelledVector, n::Integer) = fldmod1(n, cell_length(cv))
168-
#
169-
#function getindex(cv::CelledVector, n::Integer)
170-
# cellₙ, cell_indexₙ = cell_and_cell_index(cv, n)
171-
# return cv.f(cv.data[cell_indexₙ], cellₙ)
172-
#end
173-
#
174-
#function setindex!(cv::CelledVector, val, n::Integer)
175-
# cellₙ, cell_indexₙ = cell_and_cell_index(cv, n)
176-
# # XXX: is this offset generally correct?
177-
# # It seems to be for "linear" functions.
178-
# cv.data[cell_indexₙ] = cv.f(val, -cellₙ + 2)
179-
# return cv
180-
#end

src/infinitecanonicalmps.jl

Lines changed: 19 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,25 +26,37 @@ function __siteinds(site_tag, N::Int, space)
2626
end
2727

2828
infsiteinds(s::Vector{<:Index}) = CelledVector(addtags(s, celltags(1)))
29-
function infsiteinds(site_tag, N::Int; space=nothing, kwargs...)
29+
function infsiteinds(s::Vector{<:Index}, translator)
30+
return CelledVector(addtags(s, celltags(1)), translator)
31+
end
32+
33+
function infsiteinds(site_tag, N::Int; space=nothing, translator=nothing, kwargs...)
3034
if !isnothing(space)
3135
s = _siteinds(site_tag, N; space=space)
3236
else
3337
# TODO: add a shift option
3438
s = siteinds(site_tag, N; kwargs...)
3539
end
36-
return infsiteinds(s)
40+
if !isnothing(translator)
41+
return infsiteinds(s, translator)
42+
else
43+
return infsiteinds(s)
44+
end
3745
end
3846

3947
function ITensors.linkinds::InfiniteMPS)
4048
N = nsites(ψ)
41-
return CelledVector([linkinds(ψ, (n, n + 1)) for n in 1:N])
49+
return CelledVector([linkinds(ψ, (n, n + 1)) for n in 1:N], translator(ψ))
4250
end
4351

4452
function InfMPS(s::Vector, f::Function)
4553
return InfMPS(infsiteinds(s), f)
4654
end
4755

56+
function InfMPS(s::Vector, f::Function, translator::Function)
57+
return InfMPS(infsiteinds(s, translator), f)
58+
end
59+
4860
function indval(iv::Pair)
4961
return ind(iv) => val(iv)
5062
end
@@ -56,7 +68,7 @@ end
5668
function insert_linkinds!(A; left_dir=ITensors.Out)
5769
# TODO: use `celllength` here
5870
N = nsites(A)
59-
l = CelledVector{indtype(A)}(undef, N)
71+
l = CelledVector{indtype(A)}(undef, N, translator(A))
6072
n = N
6173
s = siteind(A, 1)
6274
dim = if hasqns(s)
@@ -89,7 +101,8 @@ end
89101

90102
function UniformMPS(s::CelledVector, f::Function; left_dir=ITensors.Out)
91103
sᶜ¹ = s[Cell(1)]
92-
A = InfiniteMPS([ITensor(sⁿ) for sⁿ in sᶜ¹])
104+
A = InfiniteMPS([ITensor(sⁿ) for sⁿ in sᶜ¹], translator(s))
105+
#A.data.translator = translator(s)
93106
N = length(sᶜ¹)
94107
for n in 1:N
95108
Aⁿ = A[n]
@@ -105,7 +118,7 @@ function InfMPS(s::CelledVector, f::Function)
105118
N = length(s)
106119
ψL = UniformMPS(s, f; left_dir=ITensors.Out)
107120
ψR = UniformMPS(s, f; left_dir=ITensors.In)
108-
ψC = InfiniteMPS(N)
121+
ψC = InfiniteMPS(N, translator(s))
109122
l = linkinds(ψL)
110123
r = linkinds(ψR)
111124
for n in 1:N

src/infinitempo.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,3 +18,5 @@ end
1818
## getindex(l::InfiniteSumLocalOps, n::Integer) = ITensors.data(l)[n]
1919

2020
# TODO? Instead of having a big quasi empty ITensor, store only the non zero blocks
21+
22+
translator(mpo::InfiniteMPO) = mpo.data.translator

src/infinitempomatrix.jl

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@ mutable struct InfiniteMPOMatrix <: AbstractInfiniteMPS
66
reverse::Bool
77
end
88

9+
translator(mpo::InfiniteMPOMatrix) = mpo.data.translator
10+
911
# TODO better printing?
1012
function Base.show(io::IO, M::InfiniteMPOMatrix)
1113
print(io, "$(typeof(M))")
@@ -37,4 +39,8 @@ function InfiniteMPOMatrix(arrMat::Vector{Matrix{ITensor}})
3739
return InfiniteMPOMatrix(arrMat, 0, size(arrMat)[1], false)
3840
end
3941

42+
function InfiniteMPOMatrix(data::Vector{Matrix{ITensor}}, translator::Function)
43+
return InfiniteMPOMatrix(CelledVector(data, translator), 0, size(data)[1], false)
44+
end
45+
4046
#nrange(H::InfiniteMPOMatrix) = [size(H[j])[1] - 1 for j in 1:nsites(H)]

0 commit comments

Comments
 (0)