-
-
Notifications
You must be signed in to change notification settings - Fork 104
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
fix: fix remake with u0 dependent on Symbol
parameter
#837
Conversation
be53827
to
4d06d79
Compare
I have verified that this passes the tests in https://github.com/SciML/Catalyst.jl/blob/0b4092e7b6992440b07fc0d58516ad2340b0f88e/test/upstream/mtk_problem_inputs.jl#L1-L176 |
4d06d79
to
cd7753b
Compare
So the default here ( I am running the full set of Catalyst tests against this PR locally and will report back. (The stability computation tests were also failing after the remake changes yesterday.) |
I'm now getting a failure: https://github.com/SciML/Catalyst.jl/blob/0b4092e7b6992440b07fc0d58516ad2340b0f88e/test/network_analysis/conservation_laws.jl#L265 locally. I'll upcap SciMLBase on master so this PR can test against it. |
OK, it is uncapped so hopefully downstream here will just run against it. It was passing tests fine last night when restricted to 2.71.1 so any failures are likely due to this and/or the previous PR. If we need to update a test due to incorrectly assumed behavior please let me know. I probably won't have any time free today, but can take a look tonight or tomorrow morning. |
So the main failure here is MTK and it's a very annoying one @variables x(t) y(t)
@parameters p q
@mtkbuild sys = ODESystem(
[D(x) ~ x, p ~ x + y], t; defaults = [p => missing], guesses = [x => 0.0, p => 0.0])
prob = ODEProblem(sys, [x => 1.0, y => 1.0], (0.0, 1.0))
prob2 = remake(prob; u0 = [x => 1.0, y => 2x + exp(t)]) this is the code that gets run. The |
The best solution I have right now is to make |
Yeah, that sounds a bit messy. But if it fixes this issue it is a starting point at least that can hopefully be improved in the future. |
This failure is also annoying. How remake works is it builds dictionaries mapping unknowns/parameters to values. It ends up with the dictionaries My solution would be to make it populate observed variables in |
I could also not put observed variables in the On a sidenote, this is why we have initialization systems 😅 regardless of what remake does here, initialization will do the right thing. |
This is what I keep saying. It's inherently an implicit system the moment any simplification is made. Cycling substitutions to a fixed point is just fixed point iteration of the nonlinear system in a slow way. We should not do this since it's not robust and it can be really really slow (like hours 😅). I know someone will look at this and say "well I as a human would first substitute this into this and then get this, then calculate..." I know you would! How do we come up with that algorithm? That algorithm for the proper order to do the substations in order to best resolve the system is So this is why I'm saying it's just not a fruitful path. At its core, we're saying, can we avoid structural simplify and the initialization system by instead substituting the right values? Okay, how do we substitute that right? Well, we just need to detect where the cycles are in the graph, perform tearing, ... congrats, that's just structural simplify again with extra steps 😅. If you do want to enforce some kind of partial solve correctness, then what you could do is just have some way of doing a no-solve solve on the initialization problem (i.e. an algorithm that takes |
The problematic part of this PR is the direct result of the decision at the end of #832 to re-evaluate symbolic defaults... I don't see how we can have it both ways. |
It's also why I mentioned that this is why initialization exists 😅 we're trying too hard to make |
Sorry this is such a mess. From the perspective of someone that doesn't know the difference between what If you all want to go back to the old
We can use |
The core of the problem is that the |
But every problem now wraps a SciMLFunction that wraps a system when coming from MTK right? Can't this then be dispatched to have a custom MTK I would think there may be other cases in the future where we'd want to exploit information that only an MTK system might have to improve In any case, it sounds like this has become too complicated to handle via |
We already have been speicalizing remake for awhile for other reasons https://github.com/SciML/SciMLBase.jl/blob/master/src/remake.jl#L109-L204 |
Not every problem. People still use the non-MTK interface. We also can't assume it comes from MTK, since people can both build their own systems or have an alternative DSL that hooks into this interface. I know of at least one such non-MTK project, though it isn't public. MTK also doesn't codegen to every SciMLFunction, and some SciMLFunctions don't wrap a system. MTK also can't solve the circular substitute problem above, its solution is to create the initialization system. The problem is that the intent is not immediately clear from the values passed to remake because remake allows you to pass an incomplete problem specification. You both want to retain old values that you haven't touched, and update ones that depend on the variables you provided new values for. The algorithm that figures out exactly how to update everything is |
@AayushSabharwal, a problem passed to remake, and which stores a SciMLFunction that stores an People who store non- In any case, that is tangential to the bigger issue. The conclusions I've come to from all our discussion is this can't currently be done at the level of remake, requires initialization with how the parameter/u0 modification process is being envisioned here, but initialization is only supported for ODEs currently (and even for ODEs, we might have to tell users to do non-standard stuff with remake or problem construction like passing So it seems like the most immediate solution is adding a wrapper in Catalyst where we can exploit the additional knowledge we have there. I'm happy to consider alternative solutions, but I'd like a solution we can implement immediately and include in Catalyst 15 (which I want to release soon as it has at least one dramatic performance fix). Something that requires waiting an indeterminate amount of time for functionality to be added across all possible solvers Catalyst targets isn't a useful solution right now (but of course would be great long-term). |
Sure, but that dispatch won't be able to do much more than what we do here in SciMLBase anyway for the reasons mentioned previously. In fact, I'm not sure what new thing it'll do anyway.
Passing
I think so, yeah. In Catalyst you assume that the problem always contains the final value of |
684dd45
to
95c7fff
Compare
Except the many examples I put in the rebuild issue show that is not currently happening? The only time solutions were correct was when building a new problem directly (i.e. calling ODEProblem), or when explicitly passing a value for gamma to remake. The ODE solutions were wrong with every variant of
Sure, but that is a potential issue even when not using the conservation law functionality (i.e. a user could define initial conditions and parameters to introduce a circular dependency). Right now, that will impact all non-ODE problems anyways since they also don't include initialization. |
I don't think those cases had a guess for |
That is correct. |
Checklist
contributor guidelines, in particular the SciML Style Guide and
COLPRAC.
Additional context
Add any other context about the problem here.