@@ -10,28 +10,39 @@ The factors of the product are stored in the `operators` field. Additionally a
1010complex factor is stored in the `factor` field which allows for fast
1111multiplication 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
2427end
2528function 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)
2936end
37+
38+
39+
40+
3041LazyProduct (operators:: Vector{T} , factor= 1 ) where T<: AbstractOperator = LazyProduct ((operators... ,), factor)
3142LazyProduct (operators:: AbstractOperator... ) = LazyProduct ((operators... ,))
3243LazyProduct () = 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)
3546Base. eltype (x:: LazyProduct ) = promote_type (eltype (x. factor), eltype .(x. operators)... )
3647
3748dense (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
6273identityoperator (:: Type{LazyProduct} , :: Type{S} , b1:: Basis , b2:: Basis ) where S<: Number = LazyProduct (identityoperator (S, b1, b2))
6374
6475
65- # Fast in-place multiplication
6676function 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
7687end
7788
7889function 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
88100end
89101
0 commit comments