Skip to content

Commit 85a6d20

Browse files
authored
Fix for multiplication of LazySum with no elements (#95)
* eltype LazySum with no elements * test multiplication with LazySum with no elements * add zero LazySum multiplication test * add dim check for LazySum with no elements * more tests for zero LazySum * small fix * zero method for Bra and Ket
1 parent ebf8947 commit 85a6d20

File tree

3 files changed

+17
-1
lines changed

3 files changed

+17
-1
lines changed

src/operators_lazysum.jl

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ LazySum(operators::AbstractOperator...) = LazySum(mapreduce(eltype, promote_type
5959
LazySum() = throw(ArgumentError("LazySum needs a basis, or at least one operator!"))
6060

6161
Base.copy(x::LazySum) = @samebases LazySum(x.basis_l, x.basis_r, copy(x.factors), copy.(x.operators))
62-
Base.eltype(x::LazySum) = promote_type(eltype(x.factors), mapreduce(eltype, promote_type, x.operators))
62+
Base.eltype(x::LazySum) = mapreduce(eltype, promote_type, x.operators; init=eltype(x.factors))
6363

6464
dense(op::LazySum) = length(op.operators) > 0 ? sum(op.factors .* dense.(op.operators)) : Operator(op.basis_l, op.basis_r, zeros(eltype(op.factors), length(op.basis_l), length(op.basis_r)))
6565
SparseArrays.sparse(op::LazySum) = length(op.operators) > 0 ? sum(op.factors .* sparse.(op.operators)) : Operator(op.basis_l, op.basis_r, spzeros(eltype(op.factors), length(op.basis_l), length(op.basis_r)))
@@ -140,6 +140,7 @@ end
140140
# Fast in-place multiplication
141141
function mul!(result::Ket{B1},a::LazySum{B1,B2},b::Ket{B2},alpha,beta) where {B1,B2}
142142
if length(a.operators) == 0
143+
_check_mul!_dim_compatibility(size(result), size(a), size(b))
143144
result.data .*= beta
144145
else
145146
mul!(result,a.operators[1],b,alpha*a.factors[1],beta)
@@ -152,6 +153,7 @@ end
152153

153154
function mul!(result::Bra{B2},a::Bra{B1},b::LazySum{B1,B2},alpha,beta) where {B1,B2}
154155
if length(b.operators) == 0
156+
_check_mul!_dim_compatibility(size(result), reverse(size(b)), size(a))
155157
result.data .*= beta
156158
else
157159
mul!(result,a,b.operators[1],alpha*b.factors[1],beta)
@@ -164,6 +166,7 @@ end
164166

165167
function mul!(result::Operator{B1,B3},a::LazySum{B1,B2},b::Operator{B2,B3},alpha,beta) where {B1,B2,B3}
166168
if length(a.operators) == 0
169+
_check_mul!_dim_compatibility(size(result), size(a), size(b))
167170
result.data .*= beta
168171
else
169172
mul!(result,a.operators[1],b,alpha*a.factors[1],beta)
@@ -175,6 +178,7 @@ function mul!(result::Operator{B1,B3},a::LazySum{B1,B2},b::Operator{B2,B3},alpha
175178
end
176179
function mul!(result::Operator{B1,B3},a::Operator{B1,B2},b::LazySum{B2,B3},alpha,beta) where {B1,B2,B3}
177180
if length(b.operators) == 0
181+
_check_mul!_dim_compatibility(size(result), size(a), size(b))
178182
result.data .*= beta
179183
else
180184
mul!(result,a,b.operators[1],alpha*b.factors[1],beta)

src/states.jl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@ mutable struct Ket{B,T} <: AbstractKet{B,T}
3030
end
3131
end
3232

33+
Base.zero(x::Bra) = Bra(x.basis, zero(x.data))
34+
Base.zero(x::Ket) = Ket(x.basis, zero(x.data))
3335
eltype(::Type{K}) where {K <: Ket{B,V}} where {B,V} = eltype(V)
3436
eltype(::Type{K}) where {K <: Bra{B,V}} where {B,V} = eltype(V)
3537

test/test_operators_lazysum.jl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,16 @@ xbra1 = Bra(b_l, rand(ComplexF64, length(b_l)))
102102
@test 1e-11 > D((op1+op2)*(x1+0.3*x2), (op1_+op2_)*(x1+0.3*x2))
103103
@test 1e-12 > D(dagger(x1)*dagger(0.3*op2), dagger(x1)*dagger(0.3*op2_))
104104

105+
## Test multiplication with LazySum that has no elements
106+
@test iszero( LazySum(b_r, b_l) * op1a )
107+
@test iszero( op1a * LazySum(b_r, b_l) )
108+
@test iszero( LazySum(b_l, b_r) * x1 )
109+
@test iszero( xbra1 * LazySum(b_l, b_r) )
110+
@test_throws DimensionMismatch LazySum(FockBasis(2), NLevelBasis(2)) * randoperator(NLevelBasis(4), GenericBasis(2)) # save Basis with different size
111+
@test_throws DimensionMismatch randoperator(GenericBasis(1), FockBasis(3)) * LazySum(FockBasis(1), NLevelBasis(2))
112+
@test_throws DimensionMismatch LazySum(FockBasis(2), NLevelBasis(2)) * randstate(NLevelBasis(7))
113+
@test_throws DimensionMismatch randstate(FockBasis(3))' * LazySum(FockBasis(1), NLevelBasis(2))
114+
105115
## multiplication with Operator of AbstractMatrix
106116
LSop = LazySum(randoperator(b1a^2)) # AbstractOperator
107117
LSop_s = LazySum(sparse(randoperator(b1a^2)))

0 commit comments

Comments
 (0)