Skip to content

Commit f0eb5c0

Browse files
Merge pull request #135 from gaurav-arya/ag-inverse
Initial implementation of InvertedScalarOperator
2 parents b5f09b9 + 95ded0f commit f0eb5c0

File tree

2 files changed

+56
-1
lines changed

2 files changed

+56
-1
lines changed

src/scalar.jl

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ Base.iszero(α::ScalarOperator) = iszero(α.val)
133133

134134
getops::ScalarOperator) =.val,)
135135
isconstant::ScalarOperator) = α.update_func == DEFAULT_UPDATE_FUNC
136-
has_ldiv::ScalarOperator) = iszero.val)
136+
has_ldiv::ScalarOperator) = !iszero.val)
137137
has_ldiv!::ScalarOperator) = has_ldiv(α)
138138

139139
update_coefficients!(L::ScalarOperator,u,p,t) = (L.val = L.update_func(L.val,u,p,t); nothing)
@@ -224,4 +224,50 @@ Base.:-(α::AbstractSciMLScalarOperator{T}) where{T} = (-one(T)) * α
224224
getops::ComposedScalarOperator) = α.ops
225225
has_ldiv::ComposedScalarOperator) = all(has_ldiv, α.ops)
226226
has_ldiv!::ComposedScalarOperator) = all(has_ldiv!, α.ops)
227+
228+
"""
229+
Lazy inversion of Scalar Operators
230+
"""
231+
#=
232+
Keeping with the style, we avoid use of the generic InvertedOperator and instead
233+
have a specialized type for this purpose that subtypes AbstractSciMLScalarOperator.
234+
=#
235+
struct InvertedScalarOperator{T,λType} <: AbstractSciMLScalarOperator{T}
236+
λ::λType
237+
238+
function InvertedScalarOperator::AbstractSciMLScalarOperator{T}) where {T}
239+
new{T,typeof(λ)}(λ)
240+
end
241+
end
242+
Base.inv(L::AbstractSciMLScalarOperator) = InvertedScalarOperator(L)
243+
244+
for op in (
245+
:/,
246+
)
247+
for T in SCALINGNUMBERTYPES[2:end]
248+
@eval Base.$op::AbstractSciMLScalarOperator, x::$T) = α * inv(ScalarOperator(x))
249+
@eval Base.$op(x::$T, α::AbstractSciMLScalarOperator) = ScalarOperator(x) * inv(α)
250+
@eval Base.$op::AbstractSciMLScalarOperator, β::AbstractSciMLScalarOperator) = α * inv(β)
251+
end
252+
end
253+
254+
for op in (
255+
:\,
256+
)
257+
for T in SCALINGNUMBERTYPES[2:end]
258+
@eval Base.$op::AbstractSciMLScalarOperator, x::$T) = inv(α) * ScalarOperator(x)
259+
@eval Base.$op(x::$T, α::AbstractSciMLScalarOperator) = inv(ScalarOperator(x)) * α
260+
@eval Base.$op::AbstractSciMLScalarOperator, β::AbstractSciMLScalarOperator) = inv(α) * β
261+
end
262+
end
263+
264+
function Base.convert(::Type{Number}, α::InvertedScalarOperator{T}) where{T}
265+
return inv(convert(Number, α.λ))
266+
end
267+
268+
Base.conj(L::InvertedScalarOperator) = InvertedScalarOperator(conj(L.λ))
269+
270+
getops::InvertedScalarOperator) =.λ,)
271+
has_ldiv::InvertedScalarOperator) = has_mul.λ)
272+
has_ldiv!::InvertedScalarOperator) = has_ldiv(α)
227273
#

test/scalar.jl

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,22 @@ K = 12
3636
+ α) * u x * u + x * u
3737
@test α * α isa SciMLOperators.ComposedScalarOperator
3838
* α) * u x * x * u
39+
@test inv(α) isa SciMLOperators.InvertedScalarOperator
40+
inv(α) * u 1/x * u
41+
@test α * inv(α) isa SciMLOperators.ComposedScalarOperator
42+
α * inv(α) * u u
43+
@test α / α isa SciMLOperators.ComposedScalarOperator
44+
α * α * u u
3945

4046
# Test combination with other operators
4147
for op in (MatrixOperator(rand(N, N)), SciMLOperators.IdentityOperator{N}())
4248
@test α + op isa SciMLOperators.AddedOperator
4349
@test+ op) * u x * u + op * u
4450
@test α * op isa SciMLOperators.ScaledOperator
4551
@test* op) * u x * (op * u)
52+
@test all(map(T -> (T isa SciMLOperators.ScaledOperator), (α / op, op / α, op \ α, α \ op)))
53+
@test/ op) * u (op \ α) * u α * (op \ u)
54+
@test (op / α) * u \ op) * u 1/α * op * u
4655
end
4756
end
4857

0 commit comments

Comments
 (0)