Skip to content

Commit f58a263

Browse files
First working runtests
1 parent ffb3194 commit f58a263

File tree

8 files changed

+321
-82
lines changed

8 files changed

+321
-82
lines changed

src/qobj/arithmetic_and_attributes.jl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,8 @@ function LinearAlgebra.:(*)(
108108
end
109109

110110
LinearAlgebra.:(^)(A::QuantumObject{DT}, n::T) where {DT,T<:Number} = QuantumObject(^(A.data, n), A.type, A.dims)
111-
LinearAlgebra.:(/)(A::QuantumObject{DT}, n::T) where {DT,T<:Number} = QuantumObject(/(A.data, n), A.type, A.dims)
111+
LinearAlgebra.:(/)(A::AbstractQuantumObject{DT}, n::T) where {DT,T<:Number} =
112+
get_typename_wrapper(A)(A.data / n, A.type, A.dims)
112113

113114
@doc raw"""
114115
dot(A::QuantumObject, B::QuantumObject)

src/qobj/quantum_object.jl

Lines changed: 0 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -112,57 +112,6 @@ function QuantumObject(
112112
throw(DomainError(size(A), "The size of the array is not compatible with vector or matrix."))
113113
end
114114

115-
function _check_dims(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<:Integer,N}
116-
_non_static_array_warning("dims", dims)
117-
return (all(>(0), dims) && length(dims) > 0) ||
118-
throw(DomainError(dims, "The argument dims must be of non-zero length and contain only positive integers."))
119-
end
120-
_check_dims(dims::Any) = throw(
121-
ArgumentError(
122-
"The argument dims must be a Tuple or a StaticVector of non-zero length and contain only positive integers.",
123-
),
124-
)
125-
126-
function _check_QuantumObject(type::KetQuantumObject, dims, m::Int, n::Int)
127-
(n != 1) && throw(DomainError((m, n), "The size of the array is not compatible with Ket"))
128-
(prod(dims) != m) && throw(DimensionMismatch("Ket with dims = $(dims) does not fit the array size = $((m, n))."))
129-
return nothing
130-
end
131-
132-
function _check_QuantumObject(type::BraQuantumObject, dims, m::Int, n::Int)
133-
(m != 1) && throw(DomainError((m, n), "The size of the array is not compatible with Bra"))
134-
(prod(dims) != n) && throw(DimensionMismatch("Bra with dims = $(dims) does not fit the array size = $((m, n))."))
135-
return nothing
136-
end
137-
138-
function _check_QuantumObject(type::OperatorQuantumObject, dims, m::Int, n::Int)
139-
(m != n) && throw(DomainError((m, n), "The size of the array is not compatible with Operator"))
140-
(prod(dims) != m) &&
141-
throw(DimensionMismatch("Operator with dims = $(dims) does not fit the array size = $((m, n))."))
142-
return nothing
143-
end
144-
145-
function _check_QuantumObject(type::SuperOperatorQuantumObject, dims, m::Int, n::Int)
146-
(m != n) && throw(DomainError((m, n), "The size of the array is not compatible with SuperOperator"))
147-
(prod(dims) != sqrt(m)) &&
148-
throw(DimensionMismatch("SuperOperator with dims = $(dims) does not fit the array size = $((m, n))."))
149-
return nothing
150-
end
151-
152-
function _check_QuantumObject(type::OperatorKetQuantumObject, dims, m::Int, n::Int)
153-
(n != 1) && throw(DomainError((m, n), "The size of the array is not compatible with OperatorKet"))
154-
(prod(dims) != sqrt(m)) &&
155-
throw(DimensionMismatch("OperatorKet with dims = $(dims) does not fit the array size = $((m, n))."))
156-
return nothing
157-
end
158-
159-
function _check_QuantumObject(type::OperatorBraQuantumObject, dims, m::Int, n::Int)
160-
(m != 1) && throw(DomainError((m, n), "The size of the array is not compatible with OperatorBra"))
161-
(prod(dims) != sqrt(n)) &&
162-
throw(DimensionMismatch("OperatorBra with dims = $(dims) does not fit the array size = $((m, n))."))
163-
return nothing
164-
end
165-
166115
function QuantumObject(
167116
A::QuantumObject{<:AbstractArray{T,N}};
168117
type::ObjType = A.type,

src/qobj/quantum_object_base.jl

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,57 @@ function check_dims(A::AbstractQuantumObject, B::AbstractQuantumObject)
152152
return nothing
153153
end
154154

155+
function _check_dims(dims::Union{AbstractVector{T},NTuple{N,T}}) where {T<:Integer,N}
156+
_non_static_array_warning("dims", dims)
157+
return (all(>(0), dims) && length(dims) > 0) ||
158+
throw(DomainError(dims, "The argument dims must be of non-zero length and contain only positive integers."))
159+
end
160+
_check_dims(dims::Any) = throw(
161+
ArgumentError(
162+
"The argument dims must be a Tuple or a StaticVector of non-zero length and contain only positive integers.",
163+
),
164+
)
165+
166+
function _check_QuantumObject(type::KetQuantumObject, dims, m::Int, n::Int)
167+
(n != 1) && throw(DomainError((m, n), "The size of the array is not compatible with Ket"))
168+
(prod(dims) != m) && throw(DimensionMismatch("Ket with dims = $(dims) does not fit the array size = $((m, n))."))
169+
return nothing
170+
end
171+
172+
function _check_QuantumObject(type::BraQuantumObject, dims, m::Int, n::Int)
173+
(m != 1) && throw(DomainError((m, n), "The size of the array is not compatible with Bra"))
174+
(prod(dims) != n) && throw(DimensionMismatch("Bra with dims = $(dims) does not fit the array size = $((m, n))."))
175+
return nothing
176+
end
177+
178+
function _check_QuantumObject(type::OperatorQuantumObject, dims, m::Int, n::Int)
179+
(m != n) && throw(DomainError((m, n), "The size of the array is not compatible with Operator"))
180+
(prod(dims) != m) &&
181+
throw(DimensionMismatch("Operator with dims = $(dims) does not fit the array size = $((m, n))."))
182+
return nothing
183+
end
184+
185+
function _check_QuantumObject(type::SuperOperatorQuantumObject, dims, m::Int, n::Int)
186+
(m != n) && throw(DomainError((m, n), "The size of the array is not compatible with SuperOperator"))
187+
(prod(dims) != sqrt(m)) &&
188+
throw(DimensionMismatch("SuperOperator with dims = $(dims) does not fit the array size = $((m, n))."))
189+
return nothing
190+
end
191+
192+
function _check_QuantumObject(type::OperatorKetQuantumObject, dims, m::Int, n::Int)
193+
(n != 1) && throw(DomainError((m, n), "The size of the array is not compatible with OperatorKet"))
194+
(prod(dims) != sqrt(m)) &&
195+
throw(DimensionMismatch("OperatorKet with dims = $(dims) does not fit the array size = $((m, n))."))
196+
return nothing
197+
end
198+
199+
function _check_QuantumObject(type::OperatorBraQuantumObject, dims, m::Int, n::Int)
200+
(m != 1) && throw(DomainError((m, n), "The size of the array is not compatible with OperatorBra"))
201+
(prod(dims) != sqrt(n)) &&
202+
throw(DimensionMismatch("OperatorBra with dims = $(dims) does not fit the array size = $((m, n))."))
203+
return nothing
204+
end
205+
155206
get_typename_wrapper(A::AbstractQuantumObject) = Base.typename(typeof(A)).wrapper
156207

157208
# functions for getting Float or Complex element type

src/qobj/quantum_object_evo.jl

Lines changed: 81 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -92,13 +92,61 @@ struct QuantumObjectEvolution{
9292
data::DT
9393
type::ObjType
9494
dims::SVector{N,Int}
95+
96+
function QuantumObjectEvolution(
97+
data::DT,
98+
type::ObjType,
99+
dims,
100+
) where {DT<:AbstractSciMLOperator,ObjType<:QuantumObjectType}
101+
(type == Operator || type == SuperOperator) ||
102+
throw(ArgumentError("The type $type is not supported for QuantumObjectEvolution."))
103+
104+
_check_dims(dims)
105+
106+
_size = _get_size(data)
107+
_check_QuantumObject(type, dims, _size[1], _size[2])
108+
109+
N = length(dims)
110+
111+
return new{DT,ObjType,N}(data, type, SVector{N,Int}(dims))
112+
end
113+
end
114+
115+
function QuantumObjectEvolution(data::AbstractSciMLOperator, type::QuantumObjectType, dims::Integer)
116+
return QuantumObjectEvolution(data, type, SVector{1,Int}(dims))
117+
end
118+
119+
"""
120+
QuantumObjectEvolution(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing)
121+
122+
Generate a [`QuantumObjectEvolution`](@ref) object from a [`SciMLOperator`](https://github.com/SciML/SciMLOperators.jl), in the same way as [`QuantumObject`](@ref) for `AbstractArray` inputs.
123+
"""
124+
function QuantumObjectEvolution(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing)
125+
_size = _get_size(data)
126+
127+
if dims isa Nothing
128+
if type == Operator
129+
dims = SVector{1,Int}(_size[2])
130+
elseif type == SuperOperator
131+
dims = SVector{1,Int}(isqrt(_size[2]))
132+
end
133+
end
134+
135+
return QuantumObjectEvolution(data, type, dims)
95136
end
96137

97138
# Make the QuantumObjectEvolution, with the option to pre-multiply by a scalar
98-
function QuantumObjectEvolution(op_func_list::Tuple, α::Union{Nothing,Number} = nothing; f::Function = identity)
139+
function QuantumObjectEvolution(
140+
op_func_list::Tuple,
141+
α::Union{Nothing,Number} = nothing;
142+
type::Union{Nothing,QuantumObjectType} = nothing,
143+
f::Function = identity,
144+
)
99145
op, data = _QobjEvo_generate_data(op_func_list, α; f = f)
100146
dims = op.dims
101-
type = op.type
147+
if type isa Nothing
148+
type = op.type
149+
end
102150

103151
# Preallocate the SciMLOperator cache using a dense vector as a reference
104152
v0 = sparse_to_dense(similar(op.data, size(op, 1)))
@@ -107,15 +155,38 @@ function QuantumObjectEvolution(op_func_list::Tuple, α::Union{Nothing,Number} =
107155
return QuantumObjectEvolution(data, type, dims)
108156
end
109157

110-
QuantumObjectEvolution(op::QuantumObject, α::Union{Nothing,Number} = nothing; f::Function = identity) =
111-
QuantumObjectEvolution(_make_SciMLOperator(op, α), op.type, op.dims)
158+
function QuantumObjectEvolution(
159+
op::QuantumObject,
160+
α::Union{Nothing,Number} = nothing;
161+
type::Union{Nothing,QuantumObjectType} = nothing,
162+
f::Function = identity,
163+
)
164+
if type isa Nothing
165+
type = op.type
166+
end
167+
return QuantumObjectEvolution(_make_SciMLOperator(op, α, f = f), type, op.dims)
168+
end
112169

113-
function QuantumObjectEvolution(op::QuantumObjectEvolution, α::Union{Nothing,Number} = nothing; f::Function = identity)
170+
function QuantumObjectEvolution(
171+
op::QuantumObjectEvolution,
172+
α::Union{Nothing,Number} = nothing;
173+
type::Union{Nothing,QuantumObjectType} = nothing,
174+
f::Function = identity,
175+
)
114176
f !== identity && throw(ArgumentError("The function `f` is not supported for QuantumObjectEvolution inputs."))
177+
if type isa Nothing
178+
type = op.type
179+
else
180+
throw(
181+
ArgumentError(
182+
"The type of the QuantumObjectEvolution object cannot be changed when using another QuantumObjectEvolution object as input.",
183+
),
184+
)
185+
end
115186
if α isa Nothing
116-
return QuantumObjectEvolution(op.data, op.type, op.dims)
187+
return QuantumObjectEvolution(op.data, type, op.dims)
117188
end
118-
return QuantumObjectEvolution* op.data, op.type, op.dims)
189+
return QuantumObjectEvolution* op.data, type, op.dims)
119190
end
120191

121192
#=
@@ -170,14 +241,14 @@ Parse the `op_func_list` and generate the data for the `QuantumObjectEvolution`
170241
end
171242
end
172243

173-
data_expr_const = :(_make_SciMLOperator($qobj_expr_const, α))
174-
175244
quote
176245
dims = tuple($(dims_expr...))
177246

178247
length(unique(dims)) == 1 || throw(ArgumentError("The dimensions of the operators must be the same."))
179248

180-
data_expr = $data_expr_const + $data_expr
249+
data_expr_const = $qobj_expr_const isa Integer ? $qobj_expr_const : _make_SciMLOperator($qobj_expr_const, α)
250+
251+
data_expr = data_expr_const + $data_expr
181252

182253
return $first_op, data_expr
183254
end

src/qobj/synonyms.jl

Lines changed: 32 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ Note that this functions is same as `QuantumObject(A; type=type, dims=dims)`.
1818
Qobj(A; kwargs...) = QuantumObject(A; kwargs...)
1919

2020
@doc raw"""
21-
QobjEvo(op_func_list::Union{Tuple,AbstractQuantumObject}, α::Union{Nothing,Number}=nothing; f::Function=identity)
21+
QobjEvo(op_func_list::Union{Tuple,AbstractQuantumObject}, α::Union{Nothing,Number}=nothing; type::Union{Nothing, QuantumObjectType}=nothing, f::Function=identity)
2222
2323
Generate [`QuantumObjectEvolution`](@ref)
2424
25-
Note that this functions is same as `QuantumObjectEvolution(op_func_list)`. If `α` is provided, all the operators in `op_func_list` will be pre-multiplied by `α`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators.
25+
Note that this functions is same as `QuantumObjectEvolution(op_func_list)`. If `α` is provided, all the operators in `op_func_list` will be pre-multiplied by `α`. The `type` parameter is used to specify the type of the [`QuantumObject`](@ref), either `Operator` or `SuperOperator`. The `f` parameter is used to pre-apply a function to the operators before converting them to SciML operators.
2626
2727
# Arguments
2828
- `op_func_list::Union{Tuple,AbstractQuantumObject}`: A tuple of tuples or operators.
@@ -101,46 +101,60 @@ Quantum Object: type=Operator dims=[10, 2] size=(20, 20) ishermitian=fal
101101
⎣⠀⠀⠀⠀⠀⠀⠀⠀⠂⡑⎦
102102
````
103103
"""
104-
QobjEvo(op_func_list::Union{Tuple,AbstractQuantumObject}, α::Union{Nothing,Number} = nothing; f::Function = identity) =
105-
QuantumObjectEvolution(op_func_list, α; f = f)
104+
QobjEvo(
105+
op_func_list::Union{Tuple,AbstractQuantumObject},
106+
α::Union{Nothing,Number} = nothing;
107+
type::Union{Nothing,QuantumObjectType} = nothing,
108+
f::Function = identity,
109+
) = QuantumObjectEvolution(op_func_list, α; type = type, f = f)
110+
111+
QobjEvo(data::AbstractSciMLOperator, type::QuantumObjectType, dims::Integer) =
112+
QuantumObjectEvolution(data, type, SVector{1,Int}(dims))
113+
114+
"""
115+
QobjEvo(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing)
116+
117+
Synonym of [`QuantumObjectEvolution`](@ref) object from a [`SciMLOperator`](https://github.com/SciML/SciMLOperators.jl). See the documentation for [`QuantumObjectEvolution`](@ref) for more information.
118+
"""
119+
QobjEvo(data::AbstractSciMLOperator; type::QuantumObjectType = Operator, dims = nothing) =
120+
QuantumObjectEvolution(data; type = type, dims = dims)
106121

107122
@doc raw"""
108-
shape(A::QuantumObject)
123+
shape(A::AbstractQuantumObject)
109124
110-
Returns a tuple containing each dimensions of the array in the [`QuantumObject`](@ref).
125+
Returns a tuple containing each dimensions of the array in the [`AbstractQuantumObject`](@ref).
111126
112127
Note that this function is same as `size(A)`.
113128
"""
114-
shape(A::QuantumObject{<:AbstractArray{T}}) where {T} = size(A.data)
129+
shape(A::AbstractQuantumObject) = size(A.data)
115130

116131
@doc raw"""
117-
isherm(A::QuantumObject)
132+
isherm(A::AbstractQuantumObject)
118133
119-
Test whether the [`QuantumObject`](@ref) is Hermitian.
134+
Test whether the [`AbstractQuantumObject`](@ref) is Hermitian.
120135
121136
Note that this functions is same as `ishermitian(A)`.
122137
"""
123-
isherm(A::QuantumObject{<:AbstractArray{T}}) where {T} = ishermitian(A)
138+
isherm(A::AbstractQuantumObject) = ishermitian(A)
124139

125140
@doc raw"""
126-
trans(A::QuantumObject)
141+
trans(A::AbstractQuantumObject)
127142
128-
Lazy matrix transpose of the [`QuantumObject`](@ref).
143+
Lazy matrix transpose of the [`AbstractQuantumObject`](@ref).
129144
130145
Note that this function is same as `transpose(A)`.
131146
"""
132-
trans(
133-
A::QuantumObject{<:AbstractArray{T},OpType},
134-
) where {T,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} = transpose(A)
147+
trans(A::AbstractQuantumObject{DT,OpType}) where {DT,OpType<:Union{OperatorQuantumObject,SuperOperatorQuantumObject}} =
148+
transpose(A)
135149

136150
@doc raw"""
137-
dag(A::QuantumObject)
151+
dag(A::AbstractQuantumObject)
138152
139-
Lazy adjoint (conjugate transposition) of the [`QuantumObject`](@ref)
153+
Lazy adjoint (conjugate transposition) of the [`AbstractQuantumObject`](@ref)
140154
141155
Note that this function is same as `adjoint(A)`.
142156
"""
143-
dag(A::QuantumObject{<:AbstractArray{T}}) where {T} = adjoint(A)
157+
dag(A::AbstractQuantumObject) = adjoint(A)
144158

145159
@doc raw"""
146160
matrix_element(i::QuantumObject, A::QuantumObject j::QuantumObject)

src/time_evolution/mesolve.jl

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,10 +41,10 @@ function _generate_mesolve_kwargs(e_ops, progress_bar::Val{false}, tlist, kwargs
4141
return _generate_mesolve_kwargs_with_callback(tlist, kwargs)
4242
end
4343

44-
_mesolve_make_L_QobjEvo(H::QuantumObject, c_ops) = QobjEvo(liouvillian(H, c_ops))
44+
_mesolve_make_L_QobjEvo(H::QuantumObject, c_ops) = QobjEvo(liouvillian(H, c_ops); type = SuperOperator)
4545
function _mesolve_make_L_QobjEvo(H::Tuple, c_ops)
4646
c_ops isa Nothing && return QobjEvo(H)
47-
return QobjEvo((H..., mapreduce(op -> lindblad_dissipator(op), +, c_ops)); f = liouvillian)
47+
return QobjEvo((H..., mapreduce(op -> lindblad_dissipator(op), +, c_ops)); type = SuperOperator, f = liouvillian)
4848
end
4949
# TODO: Add support for Operator type QobEvo
5050
function _mesolve_make_L_QobjEvo(H::QuantumObjectEvolution, c_ops)

src/utilities.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,7 @@ getVal(x) = x # getVal for any other type
141141

142142
_get_size(A::AbstractMatrix) = size(A)
143143
_get_size(A::AbstractVector) = (length(A), 1)
144+
_get_size(A::AbstractSciMLOperator) = size(A)
144145

145146
_non_static_array_warning(argname, arg::Tuple{}) =
146147
throw(ArgumentError("The argument $argname must be a Tuple or a StaticVector of non-zero length."))

0 commit comments

Comments
 (0)