Open kerimoyle opened 4 years ago
Resets whose test_value coincides with a root or turning point of the test_variable risk missing detection of the reset point.
Unless I'm missing something, this should just say "coincides with a turning point of the" ? I thought a root was any old crossing?
Suggestions for how to structure a model to avoid the "touching not crossing" misuse case.
x = sin(t)
y = 0
reset y to 1 if x == 1
Similar to the conditional reset value situation, the use of conditional statements in the test value may be valid CellML, but should be avoided. TODO why??
I'd reword as
The use of conditional statements in the test value is valid CellML, but should be avoided.
The why is that it's very hard to detect.
In the example, at t=0.999 the test condition is
y == (1 if t == 1 else 0)
, so effectively "when y == 0
", aka "when y - 0
has a root"
At t=1.001 the test condition is
y == (1 if t == 1 else 0)
, so effectively "when y == 0
", aka "when y - 0
has a root"
The "aka" bit is how root-finding algorithms would formulate this: monitor "y - test-value" and see if it changes sign at any point, then zoom in on that area to find the root.
But a program trying to find a change in the sign of y - test-value
= y - (1 if t == 1 else 0)
wouldn't pick this up.
Instead, you'd have to do some kind of symbolical analysis to work out that it's a change at t=1, regardless of the rest of the system.
So it's valid CellML, but unlikely to lead to the correct result in practice. ~A bit like~ Exactly like writing e.g. x = 3e99999 + y - 2e99999 - 1e99999
. It's valid CellML, and mathematically fine, but tools probably won't give you the right result
A more high-level answer to question no 2 would be:
Reset values are intended as a way to encode discontinuities into CellML models in a way that provides information to solvers and other tools for how to deal with them (without doing symbolic interpretation of the equations). So instead of writing "x = 0 if t < 0.5 else 1" and just letting it run, we're explicitly telling the solver "there is a discontinuity when t == 0.5". So if you then take a conditional statement (possibly introducing a continuity), and stick that inside a reset, then you're missing the whole point (or trying to annoy Alan)
So maybe the intro line is
The use of conditional statements in the test value is valid CellML, but should be avoided if those conditional statements introduce discontinuities.
Description/introduction needed for the example use case of a stimulus current with offset. See here.
Many electrophysiology models in PMR contain statements such as
I_stim = stim_amplitude if (time % 1000 < 2) else 0
These statements encode discontinuities directly into the mathematics (at t=0, t=1000, t=2000,... and at t=2, t=1002, t=2002, ...), and so can be replaced by reset statements.
Clarity needed around indirect change of state variables with resets. The example given has some issues ... a) conflicting initial conditions for A and B? b) is the model over-defined or not ... or only not over-defined if B=A is an assignment (not a statement of equality)? And if that's true, why isn't this interpretation (assignment vs equality) applied anywhere else? See here.
The initial condition for B should be dropped so that we have
component: IndirectlyChangeStateVariables
├─ math:
│ ├─ ode(A, t) = 1
│ └─ B = A
│
├─ variable: A initially 1
│
└─ variable: B
└─ reset:
├─ when B == 2
└─ then B = 1
This isn't really "misuse", it's just another edge case we were trying to consider. Again, perfectly valid CellML, perfectly valid maths. But hard to implement. Because when B equals 2, it has to be reset to 1. But because it also holds that "B = A", this would imply that A is reset to 1. So only a very clever solver would pick this up.
The example definitely shouldn't talk about assignment, I think, that was just us trying to work out how you'd implement this in code. (A's value is set by the ODE solver, B's value is set by an assignment statement B := A
, but the cellml equivalence "B = 1" would become something like "Change A in the state vector used by the solver."). The informative spec should just kind of mention that solvers are unlikely to do this right, but without giving the impression that there's a preferred "solution" to our models 😅 So a bit of a tightrope!
The libcellml docs will have some stuff that might be useful here ... not sure where it should live ...
I think we should separate the two entirely. If we had enough resources the libcellml team and the cellml spec writers should be entirely separate teams :D
Suggestions for how to structure a model to avoid the "touching not crossing" misuse case.
x = sin(t) y = 0 reset y to 1 if x == 1
I don't see how the touching-not-crossing issue is avoided if x==1
is the condition still?
Oh sorry. No syntactical way to avoid that!
That I can think of
I needed to merge the examples PR in to development so that other PRs could be worked on, but there are still some outstanding things needed: