Skip to content

Commit c6d537c

Browse files
Merge pull request #44 from SebastianM-C/move_scale
Move `DiffEqScaledOperator`
2 parents 5e417c6 + b27e061 commit c6d537c

File tree

3 files changed

+61
-7
lines changed

3 files changed

+61
-7
lines changed

src/SciMLBase.jl

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,6 +442,11 @@ $(TYPEDEF)
442442
"""
443443
abstract type AbstractDiffEqLinearOperator{T} <: AbstractDiffEqOperator{T} end
444444

445+
"""
446+
$(TYPEDEF)
447+
"""
448+
abstract type AbstractDiffEqCompositeOperator{T} <: AbstractDiffEqLinearOperator{T} end
449+
445450
"""
446451
$(TYPEDEF)
447452
@@ -488,9 +493,9 @@ include("scimlfunctions.jl")
488493
include("alg_traits.jl")
489494

490495
include("operators/operators.jl")
496+
include("operators/basic_operators.jl")
491497
include("operators/diffeq_operator.jl")
492498
include("operators/common_defaults.jl")
493-
include("operators/basic_operators.jl")
494499

495500
include("problems/problem_utils.jl")
496501
include("problems/discrete_problems.jl")
@@ -573,7 +578,7 @@ export EnsembleAnalysis, EnsembleSummary
573578

574579
export tuples, intervals, TimeChoiceIterator
575580

576-
export AffineDiffEqOperator
581+
export AffineDiffEqOperator, DiffEqScaledOperator
577582

578583
export DiffEqScalar, DiffEqArrayOperator, DiffEqIdentity
579584

src/operators/common_defaults.jl

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,16 @@ LinearAlgebra.opnorm(L::AbstractDiffEqLinearOperator, p::Real=2) = opnorm(conver
1010
Base.@propagate_inbounds Base.getindex(L::AbstractDiffEqLinearOperator, I::Vararg{Any,N}) where {N} = convert(AbstractMatrix,L)[I...]
1111
Base.getindex(L::AbstractDiffEqLinearOperator, I::Vararg{Int, N}) where {N} =
1212
convert(AbstractMatrix,L)[I...]
13-
for op in (:*, :/, :\), T in (:AbstractArray, :Number)
14-
@eval Base.$op(L::AbstractDiffEqLinearOperator, x::$T) = $op(convert(AbstractMatrix,L), x)
15-
@eval Base.$op(x::$T, L::AbstractDiffEqLinearOperator) = $op(x, convert(AbstractMatrix,L))
13+
for op in (:*, :/, :\)
14+
@eval Base.$op(L::AbstractDiffEqLinearOperator, x::AbstractArray) = $op(convert(AbstractMatrix,L), x)
15+
@eval Base.$op(x::AbstractArray, L::AbstractDiffEqLinearOperator) = $op(x, convert(AbstractMatrix,L))
16+
@eval Base.$op(L::DiffEqArrayOperator, x::Number) = $op(convert(AbstractMatrix,L), x)
17+
@eval Base.$op(x::Number, L::DiffEqArrayOperator) = $op(x, convert(AbstractMatrix,L))
1618
end
1719
LinearAlgebra.mul!(Y::AbstractArray, L::AbstractDiffEqLinearOperator, B::AbstractArray) =
1820
mul!(Y, convert(AbstractMatrix,L), B)
1921
LinearAlgebra.mul!(Y::AbstractArray, L::AbstractDiffEqLinearOperator, B::AbstractArray, α::Number, β::Number) =
2022
mul!(Y, convert(AbstractMatrix,L), B, α, β)
21-
LinearAlgebra.ldiv!(Y::AbstractVecOrMat, L::AbstractDiffEqLinearOperator, B::AbstractVecOrMat) =
22-
ldiv!(Y, convert(AbstractMatrix,L), B)
2323
for pred in (:isreal, :issymmetric, :ishermitian, :isposdef)
2424
@eval LinearAlgebra.$pred(L::AbstractDiffEqLinearOperator) = $pred(convert(AbstractArray, L))
2525
end

src/operators/diffeq_operator.jl

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,3 +74,52 @@ function update_coefficients!(L::AffineDiffEqOperator,u,p,t)
7474
end
7575

7676
@deprecate is_constant(L::AbstractDiffEqOperator) isconstant(L)
77+
78+
# Scaled operator (α * A)
79+
struct DiffEqScaledOperator{T,F,OpType<:AbstractDiffEqLinearOperator{T}} <: AbstractDiffEqCompositeOperator{T}
80+
coeff::DiffEqScalar{T,F}
81+
op::OpType
82+
end
83+
84+
# Recursive routines that use `getops`
85+
function update_coefficients!(L::AbstractDiffEqCompositeOperator,u,p,t)
86+
for op in getops(L)
87+
update_coefficients!(op,u,p,t)
88+
end
89+
L
90+
end
91+
92+
Base.:*::DiffEqScalar{T,F}, L::AbstractDiffEqLinearOperator{T}) where {T,F} = DiffEqScaledOperator(α, L)
93+
Base.:*::Number, L::AbstractDiffEqLinearOperator{T}) where T = DiffEqScaledOperator(DiffEqScalar(convert(T,α)), L)
94+
Base.:-(L::AbstractDiffEqLinearOperator{T}) where {T} = DiffEqScalar(-one(T)) * L
95+
getops(L::DiffEqScaledOperator) = (L.coeff, L.op)
96+
Base.Matrix(L::DiffEqScaledOperator) = L.coeff * Matrix(L.op)
97+
Base.convert(::Type{AbstractMatrix}, L::DiffEqScaledOperator) = L.coeff * convert(AbstractMatrix, L.op)
98+
99+
Base.size(L::DiffEqScaledOperator, args...) = size(L.op, args...)
100+
LinearAlgebra.opnorm(L::DiffEqScaledOperator, p::Real=2) = abs(L.coeff) * opnorm(L.op, p)
101+
Base.getindex(L::DiffEqScaledOperator, i::Int) = L.coeff * L.op[i]
102+
Base.getindex(L::DiffEqScaledOperator, I::Vararg{Int, N}) where {N} =
103+
L.coeff * L.op[I...]
104+
Base.:*(L::DiffEqScaledOperator, x::AbstractArray) = L.coeff * (L.op * x)
105+
Base.:*(x::AbstractArray, L::DiffEqScaledOperator) = (L.op * x) * L.coeff
106+
Base.:/(L::DiffEqScaledOperator, x::AbstractArray) = L.coeff * (L.op / x)
107+
Base.:/(x::AbstractArray, L::DiffEqScaledOperator) = 1/L.coeff * (x / L.op)
108+
Base.:\(L::DiffEqScaledOperator, x::AbstractArray) = 1/L.coeff * (L.op \ x)
109+
Base.:\(x::AbstractArray, L::DiffEqScaledOperator) = L.coeff * (x \ L)
110+
for N in (2,3)
111+
@eval begin
112+
LinearAlgebra.mul!(Y::AbstractArray{T,$N}, L::DiffEqScaledOperator{T}, B::AbstractArray{T,$N}) where {T} =
113+
LinearAlgebra.lmul!(Y, L.coeff, mul!(Y, L.op, B))
114+
end
115+
end
116+
LinearAlgebra.ldiv!(Y::AbstractArray, L::DiffEqScaledOperator, B::AbstractArray) =
117+
lmul!(1/L.coeff, ldiv!(Y, L.op, B))
118+
LinearAlgebra.factorize(L::DiffEqScaledOperator) = L.coeff * factorize(L.op)
119+
for fact in (:lu, :lu!, :qr, :qr!, :cholesky, :cholesky!, :ldlt, :ldlt!,
120+
:bunchkaufman, :bunchkaufman!, :lq, :lq!, :svd, :svd!)
121+
@eval LinearAlgebra.$fact(L::DiffEqScaledOperator, args...) =
122+
L.coeff * fact(L.op, args...)
123+
end
124+
125+
isconstant(L::AbstractDiffEqCompositeOperator) = all(isconstant, getops(L))

0 commit comments

Comments
 (0)