-
-
Notifications
You must be signed in to change notification settings - Fork 15
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
| function update_coefficients!(L::AbstractSciMLOperator, u, p, t) | |
| for op in getops(L) | |
| update_coefficients!(op, u, p, t) | |
| end | |
| nothing | |
| end |
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.00010000000000000003In 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
endSo 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.