Skip to content

Commit 9810db4

Browse files
authored
Fix type instability for liouvillian (#318)
* add type stability tests for liouvillian * fix type instability and reduce memory alloc in `liouvillian` * fix type instability * minor changes * update changelog
1 parent 276522a commit 9810db4

File tree

3 files changed

+16
-5
lines changed

3 files changed

+16
-5
lines changed

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
## Unreleased
99

1010
- Change the parameters structure of `sesolve`, `mesolve` and `mcsolve` functions to possibly support automatic differentiation. ([#311])
11+
- Fix type instability and reduce extra memory allocation in `liouvillian`. ([#315], [#318])
1112

1213

1314
## [v0.21.5] (2024-11-15)
@@ -27,3 +28,5 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
2728
[#306]: https://github.com/qutip/QuantumToolbox.jl/issues/306
2829
[#309]: https://github.com/qutip/QuantumToolbox.jl/issues/309
2930
[#311]: https://github.com/qutip/QuantumToolbox.jl/issues/311
31+
[#315]: https://github.com/qutip/QuantumToolbox.jl/issues/315
32+
[#318]: https://github.com/qutip/QuantumToolbox.jl/issues/318

src/qobj/superoperators.jl

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,15 @@ end
2424
## the rest of the SciMLOperators will just use lazy tensor (and prompt a warning)
2525
_spre(A::MatrixOperator, Id::AbstractMatrix) = MatrixOperator(_spre(A.A, Id))
2626
_spre(A::ScaledOperator, Id::AbstractMatrix) = ScaledOperator(A.λ, _spre(A.L, Id))
27-
_spre(A::AddedOperator, Id::AbstractMatrix) = mapreduce(op -> _spre(op, Id), +, A.ops)
27+
_spre(A::AddedOperator, Id::AbstractMatrix) = AddedOperator(map(op -> _spre(op, Id), A.ops))
2828
function _spre(A::AbstractSciMLOperator, Id::AbstractMatrix)
2929
_lazy_tensor_warning("spre", A)
3030
return kron(Id, A)
3131
end
3232

3333
_spost(B::MatrixOperator, Id::AbstractMatrix) = MatrixOperator(_spost(B.A, Id))
3434
_spost(B::ScaledOperator, Id::AbstractMatrix) = ScaledOperator(B.λ, _spost(B.L, Id))
35-
_spost(B::AddedOperator, Id::AbstractMatrix) = mapreduce(op -> _spost(op, Id), +, B.ops)
35+
_spost(B::AddedOperator, Id::AbstractMatrix) = AddedOperator(map(op -> _spost(op, Id), B.ops))
3636
function _spost(B::AbstractSciMLOperator, Id::AbstractMatrix)
3737
_lazy_tensor_warning("spost", B)
3838
return kron(transpose(B), Id)
@@ -43,7 +43,7 @@ _liouvillian(H::MT, Id::AbstractMatrix) where {MT<:Union{AbstractMatrix,Abstract
4343
-1im * (_spre(H, Id) - _spost(H, Id))
4444
_liouvillian(H::MatrixOperator, Id::AbstractMatrix) = MatrixOperator(_liouvillian(H.A, Id))
4545
_liouvillian(H::ScaledOperator, Id::AbstractMatrix) = ScaledOperator(H.λ, _liouvillian(H.L, Id))
46-
_liouvillian(H::AddedOperator, Id::AbstractMatrix) = mapreduce(op -> _liouvillian(op, Id), +, H.ops)
46+
_liouvillian(H::AddedOperator, Id::AbstractMatrix) = AddedOperator(map(op -> _liouvillian(op, Id), H.ops))
4747

4848
# intrinsic lindblad_dissipator
4949
function _lindblad_dissipator(O::MT, Id::AbstractMatrix) where {MT<:Union{AbstractMatrix,AbstractSciMLOperator}}
@@ -166,7 +166,7 @@ function liouvillian(
166166
) where {DT,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}}
167167
L = liouvillian(H, Id_cache)
168168
if !(c_ops isa Nothing)
169-
# sum all the Qobj first
169+
# sum all the (time-independent) c_ops first
170170
c_ops_ti = filter(op -> isa(op, QuantumObject), c_ops)
171171
if !isempty(c_ops_ti)
172172
L += mapreduce(op -> lindblad_dissipator(op, Id_cache), +, c_ops_ti)

test/core-test/quantum_objects_evo.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -213,7 +213,15 @@
213213
@test_throws ArgumentError cache_operator(L_td, ψ)
214214

215215
@testset "Type Inference" begin
216-
@inferred liouvillian(H_td, (a, QobjEvo(a', coef1)))
216+
# we use destroy and create here because they somehow causes type instability before
217+
H_td2 = H_td + QobjEvo(destroy(N) + create(N), coef3)
218+
c_ops1 = (destroy(N), create(N))
219+
c_ops2 = (destroy(N), QobjEvo(create(N), coef1))
220+
221+
@inferred liouvillian(H_td, c_ops1)
222+
@inferred liouvillian(H_td, c_ops2)
223+
@inferred liouvillian(H_td2, c_ops1)
224+
@inferred liouvillian(H_td2, c_ops2)
217225
end
218226
end
219227
end

0 commit comments

Comments
 (0)