Skip to content

Overload operator application for ComposedOperator #159

Closed
@vpuri3

Description

@vpuri3

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.

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.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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions