-
-
Notifications
You must be signed in to change notification settings - Fork 231
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Defining a Parameter/Structures Interface #881
Comments
I would like to emphasize a requirement (that is somewhat hidden in the list above): If people do not use something like sensitivity analysis, they should not need to care about this and can still use everything they have used before. For example, we pass our semidiscretization as |
Yes important point, added to the list. |
These also seem related: |
Note that FlexibleFunctors is now part of Functors.jl. See also the monster discussion in JuliaGaussianProcesses/ParameterHandling.jl#43. TL;DR this is fiendishly complex to do in general, but it would be amazing to have more standardization around interfaces. |
We don't have to be too general, just have an interface which provides everything SciML needs, and update it as SciML needs more. |
Suggestion: Add https://github.com/paschermayr/ModelWrappers.jl to the guiding designs? |
I talked with @YingboMa and the approach we're going to go with is to prefer canonicalization, i.e. the internals to the solvers won't need any |
Does that have any potential (performance?) impacts on using parameter objects with mixed types (i.e. including a mix of functions, floats, ints, etc in a type-stable manner)? Or would this only be enforced in places where having a fixed type for parameters is needed anyways for the problem being solved to make sense? |
It should be more efficient. We plan to have a non-allocating restructure!/destructure! |
Edit: Thought this was under ModelingToolkit. Making a separate issue over there instead. |
All, We are redesigning the operator interface to SciML.ai in https://github.com/SciML/SciMLOperators.jl. This issue has come up in discussions on how to pass in parameters to function objects. The problem here, as I see it, is that there are two kinds of parameters we want to pass to functions/operators:
The former can in most cases be cast as an SciML/SciMLOperators.jl#143 is solving this problem by allowing users pass the two types of parameters separately. The proposed design would allow you to pass array-like AD parameters in # Test scalar operator which expects keyword argument to update, modeled in the style of a DiffEq W-operator.
γ = ScalarOperator(0.0; update_func=(args...; dtgamma) -> dtgamma, accepted_kwarg_fields=(:dtgamma,))
dtgamma = rand()
@test γ(u,p,t; dtgamma) ≈ dtgamma * u |
https://github.com/SciML/SciMLStructures.jl is the solution. |
Guiding issues:
Guiding designs:
For a long time we were able to get away with just "let
p
be any struct", though an edge case came up, and then a second one, and then a third one, etc. until it became clear we need to at least have an interface defined for "what can be done withp
". Similarly, we have allowed a loose definition ofu0
as "anything that can broadcast effectively, and if required can do linear algebra", but this has become limiting.The main issue really started cropping up with adjoint sensitivity analysis. In that case, one might want to extend the differential equation to include
p
, e.g.[u0;p]
forInterpolatingAdjoint
, which then means thatp
needs to be able to "act" like au0
. If that's the case, then if we assumeu0
needs to be able to broadcast and do linear algebra, suddenly this requirement is also onp
. While this works for "most"p
's that people use in practice, it does impose a limitation where using say a tuple of arrays for parameters works for "standard" equation solving, but fails with adjoints.This then requires that we ask the question: what is "the" SciML parameters or structure interface? Currently it has been essentially
AbstractArray
, sinceAbstractArray
is the only thing that effectively defines linear algebra, with extensions allowed with extra functionality is not used. However, it's probably more than overdue to both tighten and enlarge this interface by directly defining what it's actions should be.If we do this right, then people should be able to use weird structures everywhere and have things "just work", or tell them which functions to define in order for things to just work. How do we get there?
What should a SciML Parameters interface do?
p
's still need to work in the solvers: e.g. only the places that need more control should checkisscimlstructure
(and if false, throw an error that this is required).Ideas from Other Libraries / Do we need a separate library for this? Can we use another one?
Questions
Do we extend the solvers to allow for a SciML Structure/Parameter for
u0
or always flatten?This is potentially a considerable amount of work, but with a potentially considerable amount of gain. It would be an interesting solution to the adjoint sensitivity problem: if
[u0,p]
"just works" because arrays of arrays just work because arrays of arrays are supported in the structure interface, then some code becomes easier. But other things, like how to define mass matrices, become 😕. Maybe all matrices need to only be defined on the flattened form, and then LinearSolve.jl can do the restructure/destructure to make it all work nicely?Supporting this in OrdinaryDiffEq.jl is probably not "too" hard. Every
2 * k1
would need to be like afmap(*,k1,2)
. It would probably be best to just define that as an operator2 ⊗ k1
or something so the code is easier to read, but that would up the barrier to entry. For the broadcast operations, it would just require that we specialize@..
effectively, which would probably be the hardest part (ifall(isSciMLStructure,vals)
-> special dispatches?).@..
would no longer just be "Fast Broadcast" anymore though, since it would have a different definition/operation on things like arrays of arrays (but then would allow their support without requiring a RecursiveArrayTools.VectorOfArray wrapper, which groups like DynamicalSystems.jl have been asking for years).For other solvers, we'd have to do destructure/restructure in the wrapper code so it just presents as arrays to the underlying solver. To not have a performance hit, we will need (6) to hold.
I think we should do it, but it will be a challenge.
Do we provide a tables interface for reading/writing to data?
I can see this as very valuable for people working with CSVs and the such. https://github.com/rafaqz/ModelParameters.jl showed it's possible.
The text was updated successfully, but these errors were encountered: