201201
202202for T in SCALINGNUMBERTYPES
203203 @eval function ScaledOperator (λ:: $T , L:: ScaledOperator )
204- λ = ScalarOperator (λ) * L. λ
204+ λ = λ * L. λ
205205 ScaledOperator (λ, L. L)
206206 end
207207
@@ -250,7 +250,7 @@ function update_coefficients!(L::ScaledOperator, u, p, t)
250250 update_coefficients! (L. L, u, p, t)
251251 update_coefficients! (L. λ, u, p, t)
252252
253- L
253+ nothing
254254end
255255
256256getops (L:: ScaledOperator ) = (L. λ, L. L)
@@ -288,13 +288,14 @@ end
288288Base.:* (L:: ScaledOperator , u:: AbstractVecOrMat ) = L. λ * (L. L * u)
289289Base.:\ (L:: ScaledOperator , u:: AbstractVecOrMat ) = L. λ \ (L. L \ u)
290290
291- function LinearAlgebra. mul! (v:: AbstractVecOrMat , L:: ScaledOperator , u:: AbstractVecOrMat )
291+ @inline function LinearAlgebra. mul! (
292+ v:: AbstractVecOrMat , L:: ScaledOperator , u:: AbstractVecOrMat )
292293 iszero (L. λ) && return lmul! (false , v)
293294 a = convert (Number, L. λ)
294295 mul! (v, L. L, u, a, false )
295296end
296297
297- function LinearAlgebra. mul! (v:: AbstractVecOrMat ,
298+ @inline function LinearAlgebra. mul! (v:: AbstractVecOrMat ,
298299 L:: ScaledOperator ,
299300 u:: AbstractVecOrMat ,
300301 α,
@@ -326,22 +327,34 @@ struct AddedOperator{T,
326327
327328 function AddedOperator (ops)
328329 @assert ! isempty (ops)
330+ _check_AddedOperator_sizes (ops)
329331 T = promote_type (eltype .(ops)... )
330332 new {T, typeof(ops)} (ops)
331333 end
332334end
333335
334336function AddedOperator (ops:: AbstractSciMLOperator... )
335- sz = size (first (ops))
336- for op in ops[2 : end ]
337- @assert size (op)== sz " Dimension mismatch: cannot add operators of
338- sizes $(sz) , and $(size (op)) ."
339- end
340337 AddedOperator (ops)
341338end
342339
343340AddedOperator (L:: AbstractSciMLOperator ) = L
344341
342+ @generated function _check_AddedOperator_sizes (ops:: Tuple )
343+ ops_types = ops. parameters
344+ N = length (ops_types)
345+ sz_expr_list = ()
346+ sz_expr = :(sz = size (first (ops)))
347+ for i in 2 : N
348+ sz_expr_list = (sz_expr_list... , :(size (ops[$ i]) == sz))
349+ end
350+
351+ quote
352+ $ sz_expr
353+ @assert all (tuple ($ (sz_expr_list... ))) " Dimension mismatch: cannot add operators of different sizes."
354+ nothing
355+ end
356+ end
357+
345358# constructors
346359Base.:+ (A:: AbstractSciMLOperator , B:: AbstractMatrix ) = A + MatrixOperator (B)
347360Base.:+ (A:: AbstractMatrix , B:: AbstractSciMLOperator ) = MatrixOperator (A) + B
@@ -371,13 +384,15 @@ for op in (:+, :-)
371384 for LT in SCALINGCOMBINETYPES
372385 @eval function Base. $op (L:: $LT , λ:: $T )
373386 @assert issquare (L)
387+ iszero (λ) && return L
374388 N = size (L, 1 )
375389 Id = IdentityOperator (N)
376390 AddedOperator (L, $ op (λ) * Id)
377391 end
378392
379393 @eval function Base. $op (λ:: $T , L:: $LT )
380394 @assert issquare (L)
395+ iszero (λ) && return $ op (L)
381396 N = size (L, 1 )
382397 Id = IdentityOperator (N)
383398 AddedOperator (λ * Id, $ op (L))
@@ -386,6 +401,23 @@ for op in (:+, :-)
386401 end
387402end
388403
404+ for T in SCALINGNUMBERTYPES[2 : end ]
405+ @eval function Base.:* (λ:: $T , L:: AddedOperator )
406+ ops = map (op -> λ * op, L. ops)
407+ AddedOperator (ops)
408+ end
409+
410+ @eval function Base.:* (L:: AddedOperator , λ:: $T )
411+ ops = map (op -> λ * op, L. ops)
412+ AddedOperator (ops)
413+ end
414+
415+ @eval function Base.:/ (L:: AddedOperator , λ:: $T )
416+ ops = map (op -> op / λ, L. ops)
417+ AddedOperator (ops)
418+ end
419+ end
420+
389421function Base. convert (:: Type{AbstractMatrix} , L:: AddedOperator )
390422 sum (op -> convert (AbstractMatrix, op), L. ops)
391423end
@@ -422,16 +454,32 @@ function update_coefficients(L::AddedOperator, u, p, t)
422454 @reset L. ops = ops
423455end
424456
457+ @generated function update_coefficients! (L:: AddedOperator , u, p, t)
458+ ops_types = L. parameters[2 ]. parameters
459+ N = length (ops_types)
460+ quote
461+ Base. @nexprs $ N i-> begin
462+ update_coefficients! (L. ops[i], u, p, t)
463+ end
464+
465+ nothing
466+ end
467+ end
468+
425469getops (L:: AddedOperator ) = L. ops
426470islinear (L:: AddedOperator ) = all (islinear, getops (L))
427471Base. iszero (L:: AddedOperator ) = all (iszero, getops (L))
428472has_adjoint (L:: AddedOperator ) = all (has_adjoint, L. ops)
429473
430- function cache_internals (L:: AddedOperator , u:: AbstractVecOrMat )
431- for i in 1 : length (L. ops)
432- @reset L. ops[i] = cache_operator (L. ops[i], u)
474+ @generated function cache_internals (L:: AddedOperator , u:: AbstractVecOrMat )
475+ ops_types = L. parameters[2 ]. parameters
476+ N = length (ops_types)
477+ quote
478+ Base. @nexprs $ N i-> begin
479+ @reset L. ops[i] = cache_operator (L. ops[i], u)
480+ end
481+ L
433482 end
434- L
435483end
436484
437485getindex (L:: AddedOperator , i:: Int ) = sum (op -> op[i], L. ops)
@@ -441,26 +489,33 @@ function Base.:*(L::AddedOperator, u::AbstractVecOrMat)
441489 sum (op -> iszero (op) ? zero (u) : op * u, L. ops)
442490end
443491
444- function LinearAlgebra. mul! (v:: AbstractVecOrMat , L:: AddedOperator , u:: AbstractVecOrMat )
445- mul! (v, first (L. ops), u)
446- for op in L. ops[2 : end ]
447- iszero (op) && continue
448- mul! (v, op, u, true , true )
492+ @generated function LinearAlgebra. mul! (
493+ v:: AbstractVecOrMat , L:: AddedOperator , u:: AbstractVecOrMat )
494+ ops_types = L. parameters[2 ]. parameters
495+ N = length (ops_types)
496+ quote
497+ mul! (v, L. ops[1 ], u)
498+ Base. @nexprs $ (N - 1 ) i-> begin
499+ mul! (v, L. ops[i + 1 ], u, true , true )
500+ end
501+ v
449502 end
450- v
451503end
452504
453- function LinearAlgebra. mul! (v:: AbstractVecOrMat ,
505+ @generated function LinearAlgebra. mul! (v:: AbstractVecOrMat ,
454506 L:: AddedOperator ,
455507 u:: AbstractVecOrMat ,
456508 α,
457509 β)
458- lmul! (β, v)
459- for op in L. ops
460- iszero (op) && continue
461- mul! (v, op, u, α, true )
510+ ops_types = L. parameters[2 ]. parameters
511+ N = length (ops_types)
512+ quote
513+ lmul! (β, v)
514+ Base. @nexprs $ (N) i-> begin
515+ mul! (v, L. ops[i], u, α, true )
516+ end
517+ v
462518 end
463- v
464519end
465520
466521"""
0 commit comments