18
$\begingroup$

Consider the following simple example:

sol = NDSolve[ {x''[t] == 1, x'[0] == 0, x[0] == 0,
               WhenEvent[Abs[x[t]] > 1 && x[t] > 2, {x'[t] -> -3 x'[t]}]}, 
               x[t], {t, 0, 4}];
Plot[x[t] /. sol[[1]], {t, 0, 4}]

Mathematica graphics

Clearly WhenEvent[] is missing the x[t] > 2 occurrence. This may happens (my interpretation) if the event detection routine checks for the occurrence of the first part of the AND clause and then for the other AND components, instead of checking them as an OR event trigger. As the Abs[x[t]] > 1 event isn't fired again between 1 and 2, the rest of the AND clause doesn't get tested again.

In testing this interpretation, we can reverse the clause:

sol = NDSolve[{x''[t] == 1, x'[0] == 0, x[0] == 0,
              WhenEvent[x[t] > 2 && Abs[x[t]] > 1, {x'[t] -> -3 x'[t]}]}, 
               x[t], {t, 0, 4}];
Plot[x[t] /. sol[[1]], {t, 0, 4}]

Mathematica graphics

which now works as expected. Of course this isn't a proof.

But the strange thing is that reverting to the first version, but encapsulating the clause in a function, also works as expected:

clause[p_] := Abs[p] > 1 && p > 2
sol = NDSolve[{x''[t] == 1, x'[0] == 0, x[0] == 0,
              WhenEvent[clause[x[t]], {x'[t] -> -3 x'[t]}]}, x[t], {t, 0, 4}];
Plot[x[t] /. sol[[1]], {t, 0, 4}]

Mathematica graphics

So, what is the moral? Always put your WhenEvent[] clause as a function?

$\endgroup$
2
  • 1
    $\begingroup$ Even weirder: try WhenEvent[Null;Abs[x[t]]>1&&x[t]>2,{x'[t]->-3x'[t]}].. $\endgroup$
    – Silvia
    Dec 24 '13 at 18:28
  • $\begingroup$ @Silvia That's crazy. Perhaps the WhenEvent[ ] thing isn't mature enough $\endgroup$ Dec 24 '13 at 19:25
13
$\begingroup$

From WhenEvent:

Examples of events and how $t_a$ is determined include:
...
f == 0 && pred -- f crosses zero and pred is True

I believe that the same special case is applied to And for forms f > 0 && pred, etc.

So

WhenEvent[Abs[x[t]] > 1 && x[t] > 2, {x'[t] -> -3 x'[t]}]

means the event will be triggered when Abs[x[t]] crosses 1 and x[t] > 2, which is never.

Next,

 WhenEvent[x[t] > 2 && Abs[x[t]] > 1, {x'[t] -> -3 x'[t]}]

means the event will be triggered when x[t] crosses 2 and Abs[x[t]] > 1, which will be whenever x[t] crosses 2.

Finally, both

WhenEvent[clause[x[t]], {x'[t] -> -3 x'[t]}]
WhenEvent[Null; Abs[x[t]] > 1 && x[t] > 2, {x'[t] -> -3x'[t]}]

do not have the head And, so the special case is not applied; they will trigger an event whenever they change from False to True.

$\endgroup$
15
  • 2
    $\begingroup$ I've read the docs, but I understood them as a simple application of logic. Your interpretation (probably correct) seems dangerous because you have to be sure to cover all the possible timelines with OR clauses ... or just encapsulate the whole thing as a function which is probably worse from the performance POV $\endgroup$ Dec 25 '13 at 4:23
  • 1
    $\begingroup$ @belisarius It could be that only crossings, such as f == 0, were meant to be special-cased, and you've found a bug. Clearly f == 0 has to be a special case, and one would want to allow conditions to be placed on which crossings trigger events. But && here seems to behave logically like "when", and that's unintuitive. $\endgroup$
    – Michael E2
    Dec 25 '13 at 4:42
  • 1
    $\begingroup$ @belisarius Practically speaking, the Equal statements are never true. The solver looks for a change in sign (or a crossing). Try it with clause[p_] := p == 2 && Abs[p] > 1. $\endgroup$
    – Michael E2
    Dec 25 '13 at 5:01
  • 1
    $\begingroup$ There is a saying in Spanish. I don't really know if it makes sense in English "Among firefighters we will not step on the hose." $\endgroup$ Dec 25 '13 at 5:13
  • 2
    $\begingroup$ @belisarius I didn't mean that either. I just meant I don't think my friends will understand it. :) $\endgroup$
    – Michael E2
    Dec 25 '13 at 5:16

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.