9292
9393# Make the QuantumObjectEvolution, with the option to pre-multiply by a scalar
9494function QuantumObjectEvolution (op_func_list:: Tuple , α = true )
95- op = _get_op_func_first (op_func_list)
95+ op, data = _generate_data (op_func_list, α )
9696 dims = op. dims
9797 type = op. type
98- T = eltype (op)
99-
100- data = _generate_data (T, op_func_list, α)
10198
10299 # Preallocate the SciMLOperator cache using a dense vector as a reference
103100 v0 = sparse_to_dense (similar (op. data, size (op, 1 )))
@@ -109,12 +106,14 @@ end
109106QuantumObjectEvolution (op:: QuantumObject , α = true ) =
110107 QuantumObjectEvolution (MatrixOperator (α * op. data), op. type, op. dims)
111108
112- @generated function _get_op_func_first (op_func_list:: Tuple )
109+ @generated function _generate_data (op_func_list:: Tuple , α )
113110 op_func_list_types = op_func_list. parameters
114111 N = length (op_func_list_types)
115- T = ()
112+
116113 dims_expr = ()
117114 first_op = nothing
115+ data_expr = :(0 )
116+
118117 for i in 1 : N
119118 op_func_type = op_func_list_types[i]
120119 if op_func_type <: Tuple
@@ -126,8 +125,8 @@ QuantumObjectEvolution(op::QuantumObject, α = true) =
126125 " The first element must be a Operator or SuperOperator, and the second element must be a function." ,
127126 ),
128127 )
128+
129129 data_type = op_type. parameters[1 ]
130- T = (T... , eltype (data_type))
131130 dims_expr = (dims_expr... , :(op_func_list[$ i][1 ]. dims))
132131 if i == 1
133132 first_op = :(op_func_list[$ i][1 ])
@@ -136,47 +135,34 @@ QuantumObjectEvolution(op::QuantumObject, α = true) =
136135 op_type = op_func_type
137136 (isoper (op_type) || issuper (op_type)) ||
138137 throw (ArgumentError (" The element must be a Operator or SuperOperator." ))
138+
139139 data_type = op_type. parameters[1 ]
140- T = (T... , eltype (data_type))
141140 dims_expr = (dims_expr... , :(op_func_list[$ i]. dims))
141+
142142 if i == 1
143143 first_op = :(op_func_list[$ i])
144144 end
145145 end
146+ data_expr = :($ data_expr + _make_SciMLOperator (op_func_list[$ i], α))
146147 end
147148
148- length (unique (T)) == 1 || throw (ArgumentError (" The types of the operators must be the same." ))
149-
150149 quote
151150 dims = tuple ($ (dims_expr... ))
152151
153152 length (unique (dims)) == 1 || throw (ArgumentError (" The dimensions of the operators must be the same." ))
154153
155- return $ first_op
154+ return $ first_op, $ data_expr
156155 end
157156end
158157
159- @generated function _generate_data (T, op_func_list:: Tuple , α)
160- op_func_list_types = op_func_list. parameters
161- N = length (op_func_list_types)
162- data_expr = :(0 )
163- for i in 1 : N
164- op_func_type = op_func_list_types[i]
165- if op_func_type <: Tuple
166- data_expr = :(
167- $ data_expr +
168- ScalarOperator (zero (T), op_func_list[$ i][2 ]) * MatrixOperator (α * op_func_list[$ i][1 ]. data)
169- )
170- else
171- data_expr = :($ data_expr + MatrixOperator (α * op_func_list[$ i]. data))
172- end
173- end
174-
175- quote
176- return $ data_expr
177- end
158+ function _make_SciMLOperator (op_func:: Tuple , α)
159+ T = eltype (op_func[1 ])
160+ update_func = (a, u, p, t) -> op_func[2 ](p, t)
161+ return ScalarOperator (zero (T), update_func) * MatrixOperator (α * op_func[1 ]. data)
178162end
179163
164+ _make_SciMLOperator (op:: QuantumObject , α) = MatrixOperator (α * op. data)
165+
180166function (QO:: QuantumObjectEvolution )(p, t)
181167 # We put 0 in the place of `u` because the time-dependence doesn't depend on the state
182168 update_coefficients! (QO. data, 0 , p, t)
0 commit comments