Skip to content

Commit fde3be5

Browse files
committed
improve QobjEvo construction
1 parent e4ccef5 commit fde3be5

File tree

2 files changed

+19
-3
lines changed

2 files changed

+19
-3
lines changed

src/qobj/quantum_object_evo.jl

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -180,8 +180,12 @@ function QuantumObjectEvolution(
180180
return QuantumObjectEvolution(data, type, dims)
181181
end
182182

183-
QuantumObjectEvolution(op::QuantumObject, f::Function; type::Union{Nothing,QuantumObjectType} = nothing) =
184-
QuantumObjectEvolution(((op, f),); type = type)
183+
# this is a extra method if user accidentally specify `QuantumObjectEvolution( (op, func) )` or `QuantumObjectEvolution( ((op, func)) )`
184+
QuantumObjectEvolution(op_func::Tuple{QuantumObject,Function}, α::Union{Nothing,Number} = nothing; type::Union{Nothing,QuantumObjectType} = nothing) =
185+
QuantumObjectEvolution((op_func,), α; type = type)
186+
187+
QuantumObjectEvolution(op::QuantumObject, f::Function, α::Union{Nothing,Number} = nothing; type::Union{Nothing,QuantumObjectType} = nothing) =
188+
QuantumObjectEvolution(((op, f),), α; type = type)
185189

186190
function QuantumObjectEvolution(
187191
op::QuantumObject,
@@ -229,13 +233,15 @@ Parse the `op_func_list` and generate the data for the `QuantumObjectEvolution`
229233
N = length(op_func_list_types)
230234

231235
dims_expr = ()
236+
func_methods_expr = ()
232237
first_op = nothing
233238
data_expr = :(0)
234239
qobj_expr_const = :(0)
235240

236241
for i in 1:N
237242
op_func_type = op_func_list_types[i]
238243
if op_func_type <: Tuple
244+
# check the structure of the tuple
239245
length(op_func_type.parameters) == 2 || throw(ArgumentError("The tuple must have two elements."))
240246
op_type = op_func_type.parameters[1]
241247
func_type = op_func_type.parameters[2]
@@ -248,6 +254,7 @@ Parse the `op_func_list` and generate the data for the `QuantumObjectEvolution`
248254
op = :(op_func_list[$i][1])
249255
data_type = op_type.parameters[1]
250256
dims_expr = (dims_expr..., :($op.dims))
257+
func_methods_expr = (func_methods_expr..., :(methods(op_func_list[$i][2], [Any, Real]))) # [Any, Real] means each func must accept 2 arguments
251258
if i == 1
252259
first_op = :($op)
253260
end
@@ -267,10 +274,16 @@ Parse the `op_func_list` and generate the data for the `QuantumObjectEvolution`
267274
end
268275

269276
quote
277+
# check the dims of the operators
270278
dims = tuple($(dims_expr...))
271-
272279
allequal(dims) || throw(ArgumentError("The dimensions of the operators must be the same."))
273280

281+
# check if each func accepts 2 arguments
282+
func_methods = tuple($(func_methods_expr...))
283+
for f_method in func_methods
284+
length(f_method.ms) == 0 && throw(ArgumentError("The following function must accept two arguments: `$(f_method.mt.name)(p, t)` with t<:Real"))
285+
end
286+
274287
data_expr_const = $qobj_expr_const isa Integer ? $qobj_expr_const : _make_SciMLOperator($qobj_expr_const, α)
275288

276289
data_expr = data_expr_const + $data_expr

test/core-test/quantum_objects_evo.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,7 @@
182182
@test isconstant(H_td) == false
183183
@test isconstant(QobjEvo(a)) == true
184184
@test isoper(H_td) == true
185+
@test QobjEvo(a, coef1) == QobjEvo((a, coef1))
185186

186187
# SuperOperator
187188
X = a * a'
@@ -205,7 +206,9 @@
205206
@test isconstant(L_td) == false
206207
@test issuper(L_td) == true
207208

209+
coef_wrong(t) = exp(-t)
208210
@test_logs (:warn,) (:warn,) liouvillian(H_td * H_td) # warnings from lazy tensor
211+
@test_throws ArgumentError QobjEvo(a, coef_wrong)
209212
@test_throws MethodError QobjEvo([[a, coef1], a' * a, [a', coef2]])
210213
@test_throws ArgumentError H_td(ρvec, p, t)
211214
@test_throws ArgumentError cache_operator(H_td, ρvec)

0 commit comments

Comments
 (0)