SciMLOperators.jl icon indicating copy to clipboard operation
SciMLOperators.jl copied to clipboard

How do I use this package to pass analytical jvp?

Open rveltz opened this issue 2 years ago • 26 comments
trafficstars

Hi,

Say I have the following vector field:

f(du,u,p,t) = @. du = -u^2

I know that the jacobian is given by

myjac(out,in,u,p,t) = @. out = -2 * u * in

How do I pass this information to ODEFunction or ODEProblem?

SciMLOperators.FunctionOperator is just asking for the linear op in the form op(out, in, p, t), but where is the information about u?

rveltz avatar Nov 03 '23 07:11 rveltz

@avik-pal you just took a look through this could you comment?

ChrisRackauckas avatar Nov 15 '23 12:11 ChrisRackauckas

myjac(out,in,u,p,t) = @. out = -2 * u * in

What is in? This looks like the JVP / VJP and not the Jacobian itself.

avik-pal avatar Nov 15 '23 17:11 avik-pal

yes that's the jvp

rveltz avatar Nov 15 '23 19:11 rveltz

Right, see how the JacVec operator is defined. Instead of using ad for the internal op, you will have to specify it analytically for every u. The other option is the use the kwargs interface for FunctionOperator and pass in in as a kwarg, for this see the VecJac implementation. Both are in https://github.com/JuliaDiff/SparseDiffTools.jl/blob/master/src/differentiation/jaches_products.jl & https://github.com/JuliaDiff/SparseDiffTools.jl/blob/master/src/differentiation/vecjac_products.jl

avik-pal avatar Nov 15 '23 20:11 avik-pal

I thought DE would provide a built in solution like DiffEqOperator used to.

rveltz avatar Nov 16 '23 07:11 rveltz

This seems like a mistake. You could use parameters here, but it feels off. The function operator is L(u,p,t) so that it defines mul!(y,L,x) to be y = L(u,p,t)*x. The u seems to just be lopped off here. You can do L((u,p),t)*x but that seems like a mistake. input isn't u: you're not necessarily always doing L(u,p,t)*u, so the state of the operator needs to update independent of the vector that is being multiplied.

Wouldn't this make JacVec easier to implement too?

ChrisRackauckas avatar Nov 16 '23 13:11 ChrisRackauckas

We talked, FunctionOperator is just wrong. We need to fix that.

ChrisRackauckas avatar Nov 17 '23 14:11 ChrisRackauckas

👍

rveltz avatar Nov 17 '23 15:11 rveltz

We have come across this issue before when trying to form nonlinear operators eg, f(u) * u, df(u)/du * u, etc with ComposedOperator (https://github.com/SciML/SciMLOperators.jl/issues/159). This seemed like a design constraint for SciMLOperators, and so when writing SparseDiffTools.VecJac, we created the kwarg interface for FunctionOperator (https://github.com/SciML/SciMLOperators.jl/issues/125). That would allow calls to VecJac like L(v, u, p, t; VJP_input = w) which is equivalent to v .= df(w)/dw * u (https://github.com/JuliaDiff/SparseDiffTools.jl/pull/245). This interface wasn't extended to SparseDiffTools.JacVec but maybe it should have. I don't know what the current problem you're facing is, but maybe a similar solution for JacVec could help alleviate the problem?

vpuri3 avatar Nov 18 '23 14:11 vpuri3

That would allow calls to VecJac like L(v, u, p, t; VJP_input = w) which is equivalent to v .= df(w)/dw * u (https://github.com/JuliaDiff/SparseDiffTools.jl/pull/245).

Let's standardize our notation.

w = L(u,p,t)*v

ChrisRackauckas avatar Nov 20 '23 18:11 ChrisRackauckas

The L someone would define here is just L = FunctionOperator((w,v,u,p,t)-> ..., u, p, t), where update_coefficients!(L,u,p,t) updates the internal states.

ChrisRackauckas avatar Nov 20 '23 18:11 ChrisRackauckas

L should have two calls:

  • L(v,u,p,t) out of place
  • L(w,v,u,p,t) in place

ChrisRackauckas avatar Nov 20 '23 18:11 ChrisRackauckas

Let's standardize our notation.

If I understand you well, L(u,p,t) is a linear operator representing the differential of say F(u,p,t) wrt to the first variable at position u.

rveltz avatar Dec 01 '23 17:12 rveltz

How is the progress on this issue?

rveltz avatar Dec 04 '23 10:12 rveltz

I'm tied down with school work at the moment. I have a long flight this weekend when I'm gonna start working on this. although it's a small change it's gonna require releasing v0.4 and subsequent modifications in downstream packages.

vpuri3 avatar Dec 04 '23 11:12 vpuri3

Sorry to be pushy... did you make any progress?

rveltz avatar Dec 20 '23 07:12 rveltz

No. But, CI in a few places has been blocked by https://github.com/bifurcationkit/BifurcationKit.jl/pull/127 so while I have your attention if that can get fixed that would help a lot.

ChrisRackauckas avatar Dec 20 '23 07:12 ChrisRackauckas

bump ;)

rveltz avatar Jan 13 '24 08:01 rveltz

The next release of NonlinearSolve will have a JacobianOperator which could be a reference for the new FunctionOperator re-design https://github.com/SciML/NonlinearSolve.jl/blob/ap/rework_internals/src/internal/operators.jl

avik-pal avatar Jan 13 '24 13:01 avik-pal

Have we made progress on this side? it is still unusable for me.

rveltz avatar Jun 04 '24 06:06 rveltz

I see that you added the operators. Can you show me an example how to solve the current issue please?

rveltz avatar Jun 12 '24 07:06 rveltz

No progress has been made. This is probably the package in the worst state right now. I need to find time for it.

ChrisRackauckas avatar Jun 29 '24 04:06 ChrisRackauckas

I am posting it here because this issue may be related to my following query I want to use matrix-free Newton Krylov to solve the ODE system using implicit methods (for e.g. KenCarp47(linsolve = KrylovJL_GMRES())) https://docs.sciml.ai/DiffEqDocs/stable/tutorials/advanced_ode_example/#Using-Jacobian-Free-Newton-Krylov I want to directly specify user-defined Jacobian vector product (JVP) for my system jvp(Jv,v,u,p,t) The ode function has this user option here https://docs.sciml.ai/DiffEqDocs/stable/types/ode_types/#SciMLBase.ODEFunction

But I don't know how to tell Krylov.jl that its mul! function is defined using above jvp. I am not sure if these options are connected to each other.

HumHongeKamyaab avatar Sep 13 '24 15:09 HumHongeKamyaab

I want to directly specify user-defined Jacobian vector product (JVP) for my system jvp(Jv,v,u,p,t)

Hi @ChrisRackauckas, Is there any update on this issue, or Is there any alternative way without using FunctionalOperator to specify JVP of the system so that Krylov.jl can use it in mul! via DifferencialEquation.jl.

HumHongeKamyaab avatar Sep 30 '24 09:09 HumHongeKamyaab

We now have https://docs.sciml.ai/NonlinearSolve/dev/api/SciMLJacobianOperators/ but currently only has bindings if you specify it is a nonlinearproblem

avik-pal avatar Sep 30 '24 13:09 avik-pal

@avik-pal Thanks. I am not sure if can solve for problem defined using NonlinearSolve.jl during an impilcit ODE step of DifferencialEquation.jl

There is something about it mentioned in docs https://docs.sciml.ai/DiffEqDocs/stable/features/linear_nonlinear/#Nonlinear-Solvers:-nlsolve-Specification but its not using NonlinearSolve.jl

It looks like DifferencialEquation.jl uses their own NonLinearSolve type https://github.com/SciML/OrdinaryDiffEq.jl/blob/90ba736442ce9da6f38f2db907d203cb65f61dc5/lib/OrdinaryDiffEqNonlinearSolve/src/type.jl#L2

HumHongeKamyaab avatar Oct 02 '24 15:10 HumHongeKamyaab