Skip to content

Commit 91ac4fd

Browse files
authored
add ket_l and bra_r for LazyProduct (#44)
* add ket_l and bra_r for LazyProduct * Tuples * Length 1 and cache optimized * change type of ket_l and bra_r to Tuples
1 parent c87d01d commit 91ac4fd

File tree

1 file changed

+33
-21
lines changed

1 file changed

+33
-21
lines changed

src/operators_lazyproduct.jl

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -10,28 +10,39 @@ The factors of the product are stored in the `operators` field. Additionally a
1010
complex factor is stored in the `factor` field which allows for fast
1111
multiplication with numbers.
1212
"""
13-
mutable struct LazyProduct{BL,BR,F,T} <: AbstractOperator{BL,BR}
13+
14+
mutable struct LazyProduct{BL,BR,F,T,KTL,BTR} <: AbstractOperator{BL,BR}
1415
basis_l::BL
1516
basis_r::BR
1617
factor::F
1718
operators::T
18-
function LazyProduct{BL,BR,F,T}(operators::T, factor::F=1) where {BL,BR,F,T}
19+
ket_l::KTL
20+
bra_r::BTR
21+
function LazyProduct{BL,BR,F,T,KTL,BTR}(operators::T, ket_l::KTL, bra_r::BTR, factor::F=1) where {BL,BR,F,T,KTL,BTR}
1922
for i = 2:length(operators)
2023
check_multiplicable(operators[i-1], operators[i])
2124
end
22-
new(operators[1].basis_l, operators[end].basis_r, factor, operators)
25+
new(operators[1].basis_l, operators[end].basis_r, factor, operators,ket_l,bra_r)
2326
end
2427
end
2528
function LazyProduct(operators::T, factor::F=1) where {T,F}
2629
BL = typeof(operators[1].basis_l)
2730
BR = typeof(operators[end].basis_r)
28-
LazyProduct{BL,BR,F,T}(operators, factor)
31+
ket_l=Tuple(Ket(operators[i].basis_l) for i in 2:length(operators))
32+
bra_r=Tuple(Bra(operators[i].basis_r) for i in 1:length(operators)-1)
33+
KTL = typeof(ket_l)
34+
BTR = typeof(bra_r)
35+
LazyProduct{BL,BR,F,T,KTL,BTR}(operators, ket_l, bra_r, factor)
2936
end
37+
38+
39+
40+
3041
LazyProduct(operators::Vector{T}, factor=1) where T<:AbstractOperator = LazyProduct((operators...,), factor)
3142
LazyProduct(operators::AbstractOperator...) = LazyProduct((operators...,))
3243
LazyProduct() = throw(ArgumentError("LazyProduct needs at least one operator!"))
3344

34-
Base.copy(x::T) where T<:LazyProduct = T(([copy(op) for op in x.operators]...,), x.factor)
45+
Base.copy(x::T) where T<:LazyProduct = T(([copy(op) for op in x.operators]...,),x.ket_l,x.bra_r, x.factor)
3546
Base.eltype(x::LazyProduct) = promote_type(eltype(x.factor), eltype.(x.operators)...)
3647

3748
dense(op::LazyProduct) = op.factor*prod(dense.(op.operators))
@@ -42,7 +53,7 @@ SparseArrays.sparse(op::LazyProduct{B1,B2,F,T}) where {B1,B2,F,T<:Tuple{Abstract
4253
==(x::LazyProduct{B1,B2}, y::LazyProduct{B1,B2}) where {B1,B2} = (x.basis_l == y.basis_l && x.basis_r == y.basis_r && x.operators==y.operators && x.factor == y.factor)
4354

4455
# Arithmetic operations
45-
-(a::T) where T<:LazyProduct = T(a.operators, -a.factor)
56+
-(a::T) where T<:LazyProduct = T(a.operators,a.ket_l,a.bra_r, -a.factor)
4657

4758
*(a::LazyProduct{B1,B2}, b::LazyProduct{B2,B3}) where {B1,B2,B3} = LazyProduct((a.operators..., b.operators...), a.factor*b.factor)
4859
*(a::LazyProduct, b::Number) = LazyProduct(a.operators, a.factor*b)
@@ -62,28 +73,29 @@ permutesystems(op::LazyProduct, perm::Vector{Int}) = LazyProduct(([permutesystem
6273
identityoperator(::Type{LazyProduct}, ::Type{S}, b1::Basis, b2::Basis) where S<:Number = LazyProduct(identityoperator(S, b1, b2))
6374

6475

65-
# Fast in-place multiplication
6676
function mul!(result::Ket{B1},a::LazyProduct{B1,B2},b::Ket{B2},alpha,beta) where {B1,B2}
67-
tmp1 = Ket(a.operators[end].basis_l)
68-
mul!(tmp1,a.operators[end],b,a.factor,0)
69-
for i=length(a.operators)-1:-1:2
70-
tmp2 = Ket(a.operators[i].basis_l)
71-
mul!(tmp2,a.operators[i],tmp1)
72-
tmp1 = tmp2
77+
if length(a.operators)==1
78+
mul!(result,a.operators[1],b,a.factor*alpha,beta)
79+
else
80+
mul!(a.ket_l[end],a.operators[end],b,a.factor,0)
81+
for i=length(a.operators)-2:-1:1
82+
mul!(a.ket_l[i],a.operators[i+1],a.ket_l[i+1])
83+
end
84+
mul!(result,a.operators[1],a.ket_l[1],alpha,beta)
7385
end
74-
mul!(result,a.operators[1],tmp1,alpha,beta)
7586
return result
7687
end
7788

7889
function mul!(result::Bra{B2},a::Bra{B1},b::LazyProduct{B1,B2},alpha,beta) where {B1,B2}
79-
tmp1 = Bra(b.operators[1].basis_r)
80-
mul!(tmp1,a,b.operators[1],b.factor,0)
81-
for i=2:length(b.operators)-1
82-
tmp2 = Bra(b.operators[i].basis_r)
83-
mul!(tmp2,tmp1,b.operators[i])
84-
tmp1 = tmp2
90+
if length(b.operators)==1
91+
mul!(result, a, b.operators[1],b.factor*alpha,beta)
92+
else
93+
mul!(b.bra_r[1], a, b.operators[1], b.factor,0)
94+
for i=2:length(b.operators)-1
95+
mul!(b.bra_r[i],b.bra_r[i-1],b.operators[i])
96+
end
97+
mul!(result,b.bra_r[end],b.operators[end],alpha,beta)
8598
end
86-
mul!(result,tmp1,b.operators[end],alpha,beta)
8799
return result
88100
end
89101

0 commit comments

Comments
 (0)