Skip to content

Commit

Permalink
Improve c_ops handling (qutip#216)
Browse files Browse the repository at this point in the history
  • Loading branch information
albertomercurio committed Sep 27, 2024
1 parent 8039910 commit 57e6e55
Show file tree
Hide file tree
Showing 6 changed files with 63 additions and 86 deletions.
18 changes: 8 additions & 10 deletions src/correlations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ ExponentialSeries(; tol = 1e-14, calc_steadystate = false) = ExponentialSeries(t
A::QuantumObject,
B::QuantumObject,
C::QuantumObject,
c_ops::AbstractVector=[];
c_ops::Union{Nothing,AbstractVector}=nothing;
kwargs...)
Returns the two-times correlation function of three operators ``\hat{A}``, ``\hat{B}`` and ``\hat{C}``: ``\expval{\hat{A}(t) \hat{B}(t + \tau) \hat{C}(t)}``
Expand All @@ -35,7 +35,7 @@ function correlation_3op_2t(
A::QuantumObject{<:AbstractArray{T3},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T4},OperatorQuantumObject},
C::QuantumObject{<:AbstractArray{T5},OperatorQuantumObject},
c_ops::AbstractVector = [];
c_ops::Union{Nothing,AbstractVector} = nothing;
kwargs...,
) where {
T1,
Expand Down Expand Up @@ -65,7 +65,7 @@ end
τ_l::AbstractVector,
A::QuantumObject,
B::QuantumObject,
c_ops::AbstractVector=[];
c_ops::Union{Nothing,AbstractVector}=nothing;
reverse::Bool=false,
kwargs...)
Expand All @@ -81,7 +81,7 @@ function correlation_2op_2t(
τ_l::AbstractVector,
A::QuantumObject{<:AbstractArray{T3},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T4},OperatorQuantumObject},
c_ops::AbstractVector = [];
c_ops::Union{Nothing,AbstractVector} = nothing;
reverse::Bool = false,
kwargs...,
) where {
Expand All @@ -108,7 +108,7 @@ end
τ_l::AbstractVector,
A::QuantumObject,
B::QuantumObject,
c_ops::AbstractVector=[];
c_ops::Union{Nothing,AbstractVector}=nothing;
reverse::Bool=false,
kwargs...)
Expand All @@ -122,7 +122,7 @@ function correlation_2op_1t(
τ_l::AbstractVector,
A::QuantumObject{<:AbstractArray{T3},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T4},OperatorQuantumObject},
c_ops::AbstractVector = [];
c_ops::Union{Nothing,AbstractVector} = nothing;
reverse::Bool = false,
kwargs...,
) where {
Expand All @@ -143,7 +143,7 @@ end
ω_list::AbstractVector,
A::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T3},OperatorQuantumObject},
c_ops::AbstractVector=[];
c_ops::Union{Nothing,AbstractVector}=nothing;
solver::MySolver=ExponentialSeries(),
kwargs...)
Expand All @@ -158,16 +158,14 @@ function spectrum(
ω_list::AbstractVector,
A::QuantumObject{<:AbstractArray{T2},OperatorQuantumObject},
B::QuantumObject{<:AbstractArray{T3},OperatorQuantumObject},
c_ops::Vector{QuantumObject{MT2,COpType}} = Vector{QuantumObject{MT1,HOpType}}([]);
c_ops::Union{Nothing,AbstractVector} = nothing;
solver::MySolver = ExponentialSeries(),
kwargs...,
) where {
MT1<:AbstractMatrix,
MT2<:AbstractMatrix,
T2,
T3,
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
COpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
MySolver<:SpectrumSolver,
}
return _spectrum(H, ω_list, A, B, c_ops, solver; kwargs...)
Expand Down
13 changes: 4 additions & 9 deletions src/qobj/eigsolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -438,7 +438,7 @@ end

@doc raw"""
eigsolve_al(H::QuantumObject,
T::Real, c_ops::AbstractVector=[];
T::Real, c_ops::Union{Nothing,AbstractVector}=nothing;
alg::OrdinaryDiffEqAlgorithm=Tsit5(),
H_t::Union{Nothing,Function}=nothing,
params::NamedTuple=NamedTuple(),
Expand All @@ -454,7 +454,7 @@ Solve the eigenvalue problem for a Liouvillian superoperator `L` using the Arnol
# Arguments
- `H`: The Hamiltonian (or directly the Liouvillian) of the system.
- `T`: The time at which to evaluate the time evolution
- `c_ops`: A vector of collapse operators
- `c_ops`: A vector of collapse operators. Default is `nothing` meaning the system is closed.
- `alg`: The differential equation solver algorithm
- `H_t`: A function `H_t(t)` that returns the additional term at time `t`
- `params`: A dictionary of additional parameters
Expand All @@ -476,7 +476,7 @@ and Floquet open quantum systems. Quantum, 6, 649.
function eigsolve_al(
H::QuantumObject{MT1,HOpType},
T::Real,
c_ops::Vector{QuantumObject{MT2,COpType}} = Vector{QuantumObject{MT1,HOpType}}([]);
c_ops::Union{Nothing,AbstractVector} = nothing;
alg::OrdinaryDiffEqAlgorithm = Tsit5(),
H_t::Union{Nothing,Function} = nothing,
params::NamedTuple = NamedTuple(),
Expand All @@ -486,12 +486,7 @@ function eigsolve_al(
maxiter::Int = 200,
eigstol::Real = 1e-6,
kwargs...,
) where {
MT1<:AbstractMatrix,
MT2<:AbstractMatrix,
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
COpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
}
) where {MT1<:AbstractMatrix,HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}}
L = liouvillian(H, c_ops)
prob = mesolveProblem(
L,
Expand Down
28 changes: 9 additions & 19 deletions src/steadystate.jl
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ end
H::QuantumObject{MT1,HOpType},
ψ0::QuantumObject{<:AbstractArray{T2},StateOpType},
tspan::Real = Inf,
c_ops::Vector{QuantumObject{Tc,COpType}} = QuantumObject{MT1,HOpType}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
solver::SteadyStateODESolver = SteadyStateODESolver(),
reltol::Real = 1.0e-8,
abstol::Real = 1.0e-10,
Expand All @@ -68,7 +68,7 @@ or
- `H::QuantumObject`: The Hamiltonian or the Liouvillian of the system.
- `ψ0::QuantumObject`: The initial state of the system.
- `tspan::Real=Inf`: The final time step for the steady state problem.
- `c_ops::AbstractVector=[]`: The list of the collapse operators.
- `c_ops::Union{Nothing,AbstractVector}=nothing`: The list of the collapse operators.
- `solver::SteadyStateODESolver=SteadyStateODESolver()`: see [`SteadyStateODESolver`](@ref) for more details.
- `reltol::Real=1.0e-8`: Relative tolerance in steady state terminate condition and solver adaptive timestepping.
- `abstol::Real=1.0e-10`: Absolute tolerance in steady state terminate condition and solver adaptive timestepping.
Expand All @@ -78,18 +78,16 @@ function steadystate(
H::QuantumObject{MT1,HOpType},
ψ0::QuantumObject{<:AbstractArray{T2},StateOpType},
tspan::Real = Inf,
c_ops::Vector{QuantumObject{Tc,COpType}} = QuantumObject{MT1,HOpType}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
solver::SteadyStateODESolver = SteadyStateODESolver(),
reltol::Real = 1.0e-8,
abstol::Real = 1.0e-10,
kwargs...,
) where {
MT1<:AbstractMatrix,
T2,
Tc<:AbstractMatrix,
HOpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
StateOpType<:Union{KetQuantumObject,OperatorQuantumObject},
COpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject},
}
(H.dims != ψ0.dims) && throw(DimensionMismatch("The two quantum objects are not of the same Hilbert dimension."))

Expand Down Expand Up @@ -125,22 +123,14 @@ function _steadystate_ode_condition(integrator, abstol, reltol, min_t)
end

function steadystate(
L::QuantumObject{<:AbstractArray{T},SuperOperatorQuantumObject};
H::QuantumObject{<:AbstractArray,OpType},
c_ops::Union{Nothing,AbstractVector} = nothing;
solver::SteadyStateSolver = SteadyStateDirectSolver(),
kwargs...,
) where {T}
return _steadystate(L, solver; kwargs...)
end

function steadystate(
H::QuantumObject{<:AbstractArray{T},OpType},
c_ops::AbstractVector;
solver::SteadyStateSolver = SteadyStateDirectSolver(),
kwargs...,
) where {T,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}}
) where {OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}}
L = liouvillian(H, c_ops)

return steadystate(L; solver = solver, kwargs...)
return _steadystate(L, solver; kwargs...)
end

function _steadystate(
Expand Down Expand Up @@ -232,7 +222,7 @@ end
H_p::QuantumObject{<:AbstractArray,OpType2},
H_m::QuantumObject{<:AbstractArray,OpType3},
ωd::Number,
c_ops::AbstractVector = QuantumObject{MT,OpType1}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
n_max::Integer = 2,
tol::R = 1e-8,
solver::FSolver = SSFloquetLinearSystem,
Expand Down Expand Up @@ -310,7 +300,7 @@ function steadystate_floquet(
H_p::QuantumObject{<:AbstractArray,OpType2},
H_m::QuantumObject{<:AbstractArray,OpType3},
ωd::Number,
c_ops::AbstractVector = QuantumObject{MT,OpType1}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
n_max::Integer = 2,
tol::R = 1e-8,
solver::FSolver = SSFloquetLinearSystem(),
Expand Down
49 changes: 26 additions & 23 deletions src/time_evolution/mcsolve.jl
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ end
mcsolveProblem(H::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
tlist::AbstractVector,
c_ops::Vector{QuantumObject{Tc, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[];
c_ops::Union{Nothing,AbstractVector}=nothing;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Union{Nothing,AbstractVector}=nothing,
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
Expand Down Expand Up @@ -148,7 +148,7 @@ If the environmental measurements register a quantum jump, the wave function und
- `H::QuantumObject`: Hamiltonian of the system ``\hat{H}``.
- `ψ0::QuantumObject`: Initial state of the system ``|\psi(0)\rangle``.
- `tlist::AbstractVector`: List of times at which to save the state of the system.
- `c_ops::Vector`: List of collapse operators ``\{\hat{C}_n\}_n``.
- `c_ops::Union{Nothing,AbstractVector}`: List of collapse operators ``\{\hat{C}_n\}_n``.
- `alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm`: Algorithm to use for the time evolution.
- `e_ops::Union{Nothing,AbstractVector}`: List of operators for which to calculate expectation values.
- `H_t::Union{Nothing,Function,TimeDependentOperatorSum}`: Time-dependent part of the Hamiltonian.
Expand All @@ -170,25 +170,28 @@ If the environmental measurements register a quantum jump, the wave function und
"""
function mcsolveProblem(
H::QuantumObject{MT1,OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
ψ0::QuantumObject{<:AbstractArray,KetQuantumObject},
tlist::AbstractVector,
c_ops::Vector{QuantumObject{Tc,OperatorQuantumObject}} = QuantumObject{MT1,OperatorQuantumObject}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm = Tsit5(),
e_ops::Union{Nothing,AbstractVector} = nothing,
H_t::Union{Nothing,Function,TimeDependentOperatorSum} = nothing,
params::NamedTuple = NamedTuple(),
seeds::Union{Nothing,Vector{Int}} = nothing,
jump_callback::TJC = ContinuousLindbladJumpCallback(),
kwargs...,
) where {MT1<:AbstractMatrix,T2,Tc<:AbstractMatrix,TJC<:LindbladJumpCallbackType}
) where {MT1<:AbstractMatrix,TJC<:LindbladJumpCallbackType}
H.dims != ψ0.dims && throw(DimensionMismatch("The two quantum objects are not of the same Hilbert dimension."))

haskey(kwargs, :save_idxs) &&
throw(ArgumentError("The keyword argument \"save_idxs\" is not supported in QuantumToolbox."))

c_ops isa Nothing &&
throw(ArgumentError("The list of collapse operators must be provided. Use sesolveProblem instead."))

t_l = convert(Vector{Float64}, tlist) # Convert it into Float64 to avoid type instabilities for OrdinaryDiffEq.jl

H_eff = H - T2(0.5im) * mapreduce(op -> op' * op, +, c_ops)
H_eff = H - 1im * mapreduce(op -> op' * op, +, c_ops) / 2

if e_ops isa Nothing
expvals = Array{ComplexF64}(undef, 0, length(t_l))
Expand Down Expand Up @@ -254,15 +257,15 @@ function mcsolveProblem(
end

function mcsolveProblem(
H_eff::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
H_eff::QuantumObject{<:AbstractArray,OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray,KetQuantumObject},
t_l::AbstractVector,
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm,
H_t::Union{Nothing,Function,TimeDependentOperatorSum},
params::NamedTuple,
jump_callback::ContinuousLindbladJumpCallback;
kwargs...,
) where {T1,T2}
)
cb1 = ContinuousCallback(
LindbladJumpContinuousCondition,
LindbladJumpAffect!,
Expand All @@ -283,9 +286,9 @@ end
mcsolveEnsembleProblem(H::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
tlist::AbstractVector,
c_ops::Vector{QuantumObject{Tc, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[];
c_ops::Union{Nothing,AbstractVector}=nothing;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Vector{QuantumObject{Te, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[],
e_ops::Union{Nothing,AbstractVector}=nothing,
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
jump_callback::TJC=ContinuousLindbladJumpCallback(),
Expand Down Expand Up @@ -332,9 +335,9 @@ If the environmental measurements register a quantum jump, the wave function und
- `H::QuantumObject`: Hamiltonian of the system ``\hat{H}``.
- `ψ0::QuantumObject`: Initial state of the system ``|\psi(0)\rangle``.
- `tlist::AbstractVector`: List of times at which to save the state of the system.
- `c_ops::Vector`: List of collapse operators ``\{\hat{C}_n\}_n``.
- `c_ops::Union{Nothing,AbstractVector}`: List of collapse operators ``\{\hat{C}_n\}_n``.
- `alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm`: Algorithm to use for the time evolution.
- `e_ops::Vector`: List of operators for which to calculate expectation values.
- `e_ops::Union{Nothing,AbstractVector}`: List of operators for which to calculate expectation values.
- `H_t::Union{Nothing,Function,TimeDependentOperatorSum}`: Time-dependent part of the Hamiltonian.
- `params::NamedTuple`: Dictionary of parameters to pass to the solver.
- `seeds::Union{Nothing, Vector{Int}}`: List of seeds for the random number generator. Length must be equal to the number of trajectories provided.
Expand All @@ -358,17 +361,17 @@ function mcsolveEnsembleProblem(
H::QuantumObject{MT1,OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
tlist::AbstractVector,
c_ops::Vector{QuantumObject{Tc,OperatorQuantumObject}} = QuantumObject{MT1,OperatorQuantumObject}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm = Tsit5(),
e_ops::Vector{QuantumObject{Te,OperatorQuantumObject}} = QuantumObject{MT1,OperatorQuantumObject}[],
e_ops::Union{Nothing,AbstractVector} = nothing,
H_t::Union{Nothing,Function,TimeDependentOperatorSum} = nothing,
params::NamedTuple = NamedTuple(),
jump_callback::TJC = ContinuousLindbladJumpCallback(),
seeds::Union{Nothing,Vector{Int}} = nothing,
prob_func::Function = _mcsolve_prob_func,
output_func::Function = _mcsolve_output_func,
kwargs...,
) where {MT1<:AbstractMatrix,T2,Tc<:AbstractMatrix,Te<:AbstractMatrix,TJC<:LindbladJumpCallbackType}
) where {MT1<:AbstractMatrix,T2,TJC<:LindbladJumpCallbackType}
prob_mc = mcsolveProblem(
H,
ψ0,
Expand All @@ -392,9 +395,9 @@ end
mcsolve(H::QuantumObject{<:AbstractArray{T1},OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
tlist::AbstractVector,
c_ops::Vector{QuantumObject{Tc, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[];
c_ops::Union{Nothing,AbstractVector}=nothing;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm=Tsit5(),
e_ops::Vector{QuantumObject{Te, OperatorQuantumObject}}=QuantumObject{Matrix, OperatorQuantumObject}[],
e_ops::Union{Nothing,AbstractVector}=nothing,
H_t::Union{Nothing,Function,TimeDependentOperatorSum}=nothing,
params::NamedTuple=NamedTuple(),
n_traj::Int=1,
Expand Down Expand Up @@ -441,9 +444,9 @@ If the environmental measurements register a quantum jump, the wave function und
- `H::QuantumObject`: Hamiltonian of the system ``\hat{H}``.
- `ψ0::QuantumObject`: Initial state of the system ``|\psi(0)\rangle``.
- `tlist::AbstractVector`: List of times at which to save the state of the system.
- `c_ops::Vector`: List of collapse operators ``\{\hat{C}_n\}_n``.
- `c_ops::Union{Nothing,AbstractVector}`: List of collapse operators ``\{\hat{C}_n\}_n``.
- `alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm`: Algorithm to use for the time evolution.
- `e_ops::Vector`: List of operators for which to calculate expectation values.
- `e_ops::Union{Nothing,AbstractVector}`: List of operators for which to calculate expectation values.
- `H_t::Union{Nothing,Function,TimeDependentOperatorSum}`: Time-dependent part of the Hamiltonian.
- `params::NamedTuple`: Dictionary of parameters to pass to the solver.
- `seeds::Union{Nothing, Vector{Int}}`: List of seeds for the random number generator. Length must be equal to the number of trajectories provided.
Expand All @@ -470,9 +473,9 @@ function mcsolve(
H::QuantumObject{MT1,OperatorQuantumObject},
ψ0::QuantumObject{<:AbstractArray{T2},KetQuantumObject},
tlist::AbstractVector,
c_ops::Vector{QuantumObject{Tc,OperatorQuantumObject}} = QuantumObject{MT1,OperatorQuantumObject}[];
c_ops::Union{Nothing,AbstractVector} = nothing;
alg::OrdinaryDiffEq.OrdinaryDiffEqAlgorithm = Tsit5(),
e_ops::Vector{QuantumObject{Te,OperatorQuantumObject}} = QuantumObject{MT1,OperatorQuantumObject}[],
e_ops::Union{Nothing,AbstractVector} = nothing,
H_t::Union{Nothing,Function,TimeDependentOperatorSum} = nothing,
params::NamedTuple = NamedTuple(),
seeds::Union{Nothing,Vector{Int}} = nothing,
Expand All @@ -482,7 +485,7 @@ function mcsolve(
prob_func::Function = _mcsolve_prob_func,
output_func::Function = _mcsolve_output_func,
kwargs...,
) where {MT1<:AbstractMatrix,T2,Tc<:AbstractMatrix,Te<:AbstractMatrix,TJC<:LindbladJumpCallbackType}
) where {MT1<:AbstractMatrix,T2,TJC<:LindbladJumpCallbackType}
if !isnothing(seeds) && length(seeds) != n_traj
throw(ArgumentError("Length of seeds must match n_traj ($n_traj), but got $(length(seeds))"))
end
Expand Down
Loading

0 comments on commit 57e6e55

Please sign in to comment.