@@ -158,25 +158,28 @@ const AdjointFact = isdefined(LinearAlgebra, :AdjointFactorization) ? LinearAlge
158158const TransposeFact = isdefined (LinearAlgebra, :TransposeFactorization ) ? LinearAlgebra. TransposeFactorization : Transpose
159159
160160"""
161- InvertibleOperator(F)
161+ InvertibleOperator(L, F)
162162
163- Like MatrixOperator, but stores a Factorization instead .
164-
165- Supports left division and `ldiv!` when applied to an array .
163+ Stores an operator and its factorization (or inverse operator) .
164+ Supports left division and `ldiv!` via `F`, and operator application
165+ via `L` .
166166"""
167- struct InvertibleOperator{T,FType} <: AbstractSciMLOperator{T}
168- F:: FType
167+ struct InvertibleOperator{T,LT,FT} <: AbstractSciMLOperator{T}
168+ L:: LT
169+ F:: FT
169170
170- function InvertibleOperator (F)
171+ function InvertibleOperator (L, F)
171172 @assert has_ldiv (F) | has_ldiv! (F) " $F is not invertible"
172- new {eltype(F),typeof(F)} (F)
173+ T = promote_type (eltype (L), eltype (F))
174+
175+ new {T,typeof(L),typeof(F)} (L, F)
173176 end
174177end
175178
176179# constructor
177180function LinearAlgebra. factorize (L:: AbstractSciMLOperator )
178181 fact = factorize (convert (AbstractMatrix, L))
179- InvertibleOperator (fact)
182+ InvertibleOperator (L, fact)
180183end
181184
182185for fact in (
@@ -190,40 +193,36 @@ for fact in (
190193 )
191194
192195 @eval LinearAlgebra.$ fact (L:: AbstractSciMLOperator , args... ) =
193- InvertibleOperator ($ fact (convert (AbstractMatrix, L), args... ))
196+ InvertibleOperator (L, $ fact (convert (AbstractMatrix, L), args... ))
194197 @eval LinearAlgebra.$ fact (L:: AbstractSciMLOperator ; kwargs... ) =
195- InvertibleOperator ($ fact (convert (AbstractMatrix, L); kwargs... ))
198+ InvertibleOperator (L, $ fact (convert (AbstractMatrix, L); kwargs... ))
196199end
197200
198201function Base. convert (:: Type{<:Factorization} , L:: InvertibleOperator{T,<:Factorization} ) where {T}
199202 L. F
200203end
201204
202- Base. convert (:: Type{AbstractMatrix} , L:: InvertibleOperator ) =
203- convert (AbstractMatrix, L. F)
204- Base. convert (:: Type{AbstractMatrix} , L:: InvertibleOperator{<:Any,<:Union{Adjoint,AdjointFact}} ) =
205- adjoint (convert (AbstractMatrix, adjoint (L. F)))
206- Base. convert (:: Type{AbstractMatrix} , L:: InvertibleOperator{<:Any,<:Union{Transpose,TransposeFact}} ) =
207- transpose (convert (AbstractMatrix, transpose (L. F)))
205+ Base. convert (:: Type{AbstractMatrix} , L:: InvertibleOperator ) = convert (AbstractMatrix, L. L)
208206
209207# traits
210- Base. size (L:: InvertibleOperator ) = size (L. F )
211- Base. transpose (L:: InvertibleOperator ) = InvertibleOperator (transpose (L. F))
212- Base. adjoint (L:: InvertibleOperator ) = InvertibleOperator (L. F' )
213- Base. conj (L:: InvertibleOperator ) = InvertibleOperator (conj (L. F))
214- Base. resize! (L:: InvertibleOperator , n:: Integer ) = (resize! (L. F, n); L)
208+ Base. size (L:: InvertibleOperator ) = size (L. L )
209+ Base. transpose (L:: InvertibleOperator ) = InvertibleOperator (transpose (L. L), transpose (L . F))
210+ Base. adjoint (L:: InvertibleOperator ) = InvertibleOperator (L. L ' , L . F' )
211+ Base. conj (L:: InvertibleOperator ) = InvertibleOperator (conj (L. L), conj (L . F))
212+ Base. resize! (L:: InvertibleOperator , n:: Integer ) = (resize! (L. L, n); resize! (L . F, n); L)
215213LinearAlgebra. opnorm (L:: InvertibleOperator{T} , p= 2 ) where {T} = one (T) / opnorm (L. F)
216214LinearAlgebra. issuccess (L:: InvertibleOperator ) = issuccess (L. F)
217215
218216function update_coefficients (L:: InvertibleOperator , u, p, t)
217+ @set! L. L = update_coefficients (L. L, u, p, t)
219218 @set! L. F = update_coefficients (L. F, u, p, t)
220219 L
221220end
222221
223- getops (L:: InvertibleOperator ) = (L. F,)
224- islinear (L:: InvertibleOperator ) = islinear (L. F )
222+ getops (L:: InvertibleOperator ) = (L. L, L . F,)
223+ islinear (L:: InvertibleOperator ) = islinear (L. L )
225224
226- @forward InvertibleOperator. F (
225+ @forward InvertibleOperator. L (
227226 # LinearAlgebra
228227 LinearAlgebra. issymmetric,
229228 LinearAlgebra. ishermitian,
@@ -234,15 +233,16 @@ islinear(L::InvertibleOperator) = islinear(L.F)
234233 has_adjoint,
235234 has_mul,
236235 has_mul!,
237- has_ldiv,
238- has_ldiv!,
239236 )
240237
238+ has_ldiv (L:: InvertibleOperator ) = has_mul (L. F)
239+ has_ldiv! (L:: InvertibleOperator ) = has_ldiv! (L. F)
240+
241241# operator application
242- Base.:* (L:: InvertibleOperator , x:: AbstractVecOrMat ) = L. F * x
242+ Base.:* (L:: InvertibleOperator , x:: AbstractVecOrMat ) = L. L * x
243243Base.:\ (L:: InvertibleOperator , x:: AbstractVecOrMat ) = L. F \ x
244- LinearAlgebra. mul! (v:: AbstractVecOrMat , L:: InvertibleOperator , u:: AbstractVecOrMat ) = mul! (v, L. F , u)
245- LinearAlgebra. mul! (v:: AbstractVecOrMat , L:: InvertibleOperator , u:: AbstractVecOrMat ,α, β) = mul! (v, L. F , u, α, β)
244+ LinearAlgebra. mul! (v:: AbstractVecOrMat , L:: InvertibleOperator , u:: AbstractVecOrMat ) = mul! (v, L. L , u)
245+ LinearAlgebra. mul! (v:: AbstractVecOrMat , L:: InvertibleOperator , u:: AbstractVecOrMat ,α, β) = mul! (v, L. L , u, α, β)
246246LinearAlgebra. ldiv! (v:: AbstractVecOrMat , L:: InvertibleOperator , u:: AbstractVecOrMat ) = ldiv! (v, L. F, u)
247247LinearAlgebra. ldiv! (L:: InvertibleOperator , u:: AbstractVecOrMat ) = ldiv! (L. F, u)
248248
0 commit comments