Description
For ComposedOperator
the present update_coeffs(L, u, p, t)
interface will update each op in L.ops
with u
, which is not it's input.
SciMLOperators.jl/src/interface.jl
Lines 22 to 27 in 31275d4
For example, with
N = 4
A = DiagonalOperator(rand(N); update_func = (d, u, p, t) -> copy!(d, u)) # A * u == u .^2
B = DiagonalOperator(rand(N); update_func = (d, u, p, t) -> copy!(d, u)) # A * u == u .^2
C = DiagonalOperator(rand(N); update_func = (d, u, p, t) -> copy!(d, u)) # A * u == u .^2
L = A ∘ B ∘ C
u = 0.1 * ones(N)
v = L(u, nothing, 0.0)
julia> v = L(u, nothing, 0.0)
4-element Vector{Float64}:
0.00010000000000000003
0.00010000000000000003
0.00010000000000000003
0.00010000000000000003
In this case, what we want to get by composing three squaring operations is u .^ 8
, but we will get u .^ 4
because A,B,C
will be updated by u, u, u
, not u, u^2, u^4
respectively. What we want is to update C
with u
, B
with its input C * u = u .^ 2
, and A
with B * C * u = u .^ 4
. The operator update procedure must necessarily be interlaced with multiplication.
function (L::ComposedOperator)(u, p, t)
v = u
for op in reverse(L.ops)
update_coefficients!(op, v, p, t)
v = op * v
end
v
end
So we need to overload update-coeffs and operator application for ComposedOperator
. It would be wise to take a second look at other composite operators to ensure such a thing isn't happening anywhere else. Maybe we need to define update_coeffs
overload for AdjointOperator, TransposedOperator
to pass in u'
. Should also take a second look at FunctionOperator.