Skip to content

Commit c0336cf

Browse files
amilstedAshley Milsted
andauthored
Lazy identities via FillArrays (#94)
* Have identityoperator return an Eye * Handle Eyes in LazyTensor mul!() * Fix identityoperator semantics. Add a test. * Simpify _tpops_tuple * Add compat entry for FillArrays * Filter out all square eyes. Simplify code. * Try to make Aqua happier * Explicit eye tests * Only turn off ambiguity checking for reshape * Test left action. * Restore more efficient handling of isometries * Remember why we need to distinguish beta==0 * More specific Aqua exclusion * Fix test dependencies. * Handle alpha=0 and beta=0 better. * Managed to munge tests in merge. --------- Co-authored-by: Ashley Milsted <[email protected]>
1 parent 65c0d0a commit c0336cf

12 files changed

+233
-123
lines changed

Project.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ version = "0.3.12"
55
[deps]
66
Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
77
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
8+
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
89
LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637"
910
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
1011
QuantumInterface = "5717a53b-5d69-4fa3-b976-0bf2f97ca1e5"
@@ -16,6 +17,7 @@ UnsafeArrays = "c4a57d5a-5b31-53a6-b365-19f8c011fbd6"
1617
[compat]
1718
Adapt = "1, 2, 3.3"
1819
FFTW = "1.2"
20+
FillArrays = "0.13, 1"
1921
LRUCache = "1"
2022
QuantumInterface = "0.1.0"
2123
Strided = "1, 2"
@@ -27,6 +29,7 @@ Adapt = "79e6a3ab-5dfb-504d-930d-738a2a938a0e"
2729
Aqua = "4c88cf16-eb10-579e-8560-4a9242c79595"
2830
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
2931
FFTW = "7a1cc6ca-52ef-59f5-83cd-3a7055c09341"
32+
FillArrays = "1a297f60-69ca-5386-bcde-b61e274b549b"
3033
JET = "c3a54625-cd67-489e-a8e7-0a5a0ff4e31b"
3134
LRUCache = "8ac3fa9e-de4c-5943-b1dc-09c6b5f20637"
3235
LinearAlgebra = "37e2e46d-f89d-539d-b4ee-838fcccc9c8e"
@@ -37,4 +40,4 @@ Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
3740
UnsafeArrays = "c4a57d5a-5b31-53a6-b365-19f8c011fbd6"
3841

3942
[targets]
40-
test = ["LinearAlgebra", "SparseArrays", "Random", "Test", "Aqua", "JET", "Adapt", "Dates", "FFTW", "LRUCache", "Strided", "UnsafeArrays"]
43+
test = ["LinearAlgebra", "SparseArrays", "Random", "Test", "Aqua", "JET", "Adapt", "Dates", "FFTW", "LRUCache", "Strided", "UnsafeArrays", "FillArrays"]

src/QuantumOpticsBase.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module QuantumOpticsBase
22

3-
using SparseArrays, LinearAlgebra, LRUCache, Strided, UnsafeArrays
3+
using SparseArrays, LinearAlgebra, LRUCache, Strided, UnsafeArrays, FillArrays
44
import LinearAlgebra: mul!, rmul!
55

66
import QuantumInterface: dagger, directsum, , dm, embed, expect, permutesystems,
@@ -17,7 +17,7 @@ export Basis, GenericBasis, CompositeBasis, basis,
1717
#operators_dense
1818
Operator, DenseOperator, DenseOpType, projector, dm,
1919
#operators_sparse
20-
SparseOperator, diagonaloperator, SparseOpType,
20+
SparseOperator, diagonaloperator, SparseOpType, EyeOpType,
2121
#operators_lazysum
2222
LazySum,
2323
#operators_lazyproduct

src/operators.jl

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,6 @@ to be used in the identity matrix.
350350
identityoperator(::Type{T}, ::Type{S}, b1::Basis, b2::Basis) where {T<:AbstractOperator,S} = throw(ArgumentError("Identity operator not defined for operator type $T."))
351351
identityoperator(::Type{T}, ::Type{S}, b::Basis) where {T<:AbstractOperator,S} = identityoperator(T,S,b,b)
352352
identityoperator(::Type{T}, bases::Basis...) where T<:AbstractOperator = identityoperator(T,eltype(T),bases...)
353-
identityoperator(b::Basis) = identityoperator(b,b)
354353
identityoperator(op::T) where {T<:AbstractOperator} = identityoperator(T, op.basis_l, op.basis_r)
355354

356355
# Catch case where eltype cannot be inferred from type; this is a bit hacky

src/operators_lazyproduct.jl

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,7 @@ function tensor(a::LazyProduct{B1, B2, F, T, KTL, BTR},b::Operator{B3,B4}) where
8585
end
8686

8787
function mul!(result::Ket{B1},a::LazyProduct{B1,B2},b::Ket{B2},alpha,beta) where {B1,B2}
88+
iszero(alpha) && (_zero_op_mul!(result.data, beta); return result)
8889
if length(a.operators)==1
8990
mul!(result,a.operators[1],b,a.factor*alpha,beta)
9091
else
@@ -98,6 +99,7 @@ function mul!(result::Ket{B1},a::LazyProduct{B1,B2},b::Ket{B2},alpha,beta) where
9899
end
99100

100101
function mul!(result::Bra{B2},a::Bra{B1},b::LazyProduct{B1,B2},alpha,beta) where {B1,B2}
102+
iszero(alpha) && (_zero_op_mul!(result.data, beta); return result)
101103
if length(b.operators)==1
102104
mul!(result, a, b.operators[1],b.factor*alpha,beta)
103105
else
@@ -111,6 +113,7 @@ function mul!(result::Bra{B2},a::Bra{B1},b::LazyProduct{B1,B2},alpha,beta) where
111113
end
112114

113115
function mul!(result::Operator{B1,B3,T},a::LazyProduct{B1,B2},b::Operator{B2,B3},alpha,beta) where {B1,B2,B3,T}
116+
iszero(alpha) && (_zero_op_mul!(result.data, beta); return result)
114117
if length(a.operators) == 1
115118
mul!(result,a.operators[1],b,a.factor*alpha,beta)
116119
else
@@ -127,6 +130,7 @@ function mul!(result::Operator{B1,B3,T},a::LazyProduct{B1,B2},b::Operator{B2,B3}
127130
end
128131

129132
function mul!(result::Operator{B1,B3,T},a::Operator{B1,B2},b::LazyProduct{B2,B3},alpha,beta) where {B1,B2,B3,T}
133+
iszero(alpha) && (_zero_op_mul!(result.data, beta); return result)
130134
if length(b.operators) == 1
131135
mul!(result, a, b.operators[1],b.factor*alpha,beta)
132136
else

src/operators_lazysum.jl

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -159,11 +159,20 @@ function embed(basis_l::CompositeBasis, basis_r::CompositeBasis, index::Integer,
159159
LazySum(basis_l, basis_r, op.factors, ((embed(basis_l, basis_r, index, o) for o in op.operators)...,)) # dispatch to fast-path single-index `embed`
160160
end
161161

162+
function _zero_op_mul!(data, beta)
163+
if iszero(beta)
164+
fill!(data, zero(eltype(data)))
165+
elseif !isone(beta)
166+
data .*= beta
167+
end
168+
return data
169+
end
170+
162171
# Fast in-place multiplication
163172
function mul!(result::Ket{B1},a::LazySum{B1,B2},b::Ket{B2},alpha,beta) where {B1,B2}
164-
if length(a.operators) == 0
173+
if length(a.operators) == 0 || iszero(alpha)
165174
_check_mul!_dim_compatibility(size(result), size(a), size(b))
166-
result.data .*= beta
175+
_zero_op_mul!(result.data, beta)
167176
else
168177
mul!(result,a.operators[1],b,alpha*a.factors[1],beta)
169178
for i=2:length(a.operators)
@@ -174,9 +183,9 @@ function mul!(result::Ket{B1},a::LazySum{B1,B2},b::Ket{B2},alpha,beta) where {B1
174183
end
175184

176185
function mul!(result::Bra{B2},a::Bra{B1},b::LazySum{B1,B2},alpha,beta) where {B1,B2}
177-
if length(b.operators) == 0
186+
if length(b.operators) == 0 || iszero(alpha)
178187
_check_mul!_dim_compatibility(size(result), reverse(size(b)), size(a))
179-
result.data .*= beta
188+
_zero_op_mul!(result.data, beta)
180189
else
181190
mul!(result,a,b.operators[1],alpha*b.factors[1],beta)
182191
for i=2:length(b.operators)
@@ -187,9 +196,9 @@ function mul!(result::Bra{B2},a::Bra{B1},b::LazySum{B1,B2},alpha,beta) where {B1
187196
end
188197

189198
function mul!(result::Operator{B1,B3},a::LazySum{B1,B2},b::Operator{B2,B3},alpha,beta) where {B1,B2,B3}
190-
if length(a.operators) == 0
199+
if length(a.operators) == 0 || iszero(alpha)
191200
_check_mul!_dim_compatibility(size(result), size(a), size(b))
192-
result.data .*= beta
201+
_zero_op_mul!(result.data, beta)
193202
else
194203
mul!(result,a.operators[1],b,alpha*a.factors[1],beta)
195204
for i=2:length(a.operators)
@@ -199,9 +208,9 @@ function mul!(result::Operator{B1,B3},a::LazySum{B1,B2},b::Operator{B2,B3},alpha
199208
return result
200209
end
201210
function mul!(result::Operator{B1,B3},a::Operator{B1,B2},b::LazySum{B2,B3},alpha,beta) where {B1,B2,B3}
202-
if length(b.operators) == 0
211+
if length(b.operators) == 0 || iszero(alpha)
203212
_check_mul!_dim_compatibility(size(result), size(a), size(b))
204-
result.data .*= beta
213+
_zero_op_mul!(result.data, beta)
205214
else
206215
mul!(result,a,b.operators[1],alpha*b.factors[1],beta)
207216
for i=2:length(b.operators)

0 commit comments

Comments
 (0)