Take the 2-minute tour ×
Mathematica Stack Exchange is a question and answer site for users of Mathematica. It's 100% free, no registration required.

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?

share|improve this question
    
Even weirder: try WhenEvent[Null;Abs[x[t]]>1&&x[t]>2,{x'[t]->-3x'[t]}].. –  Silvia Dec 24 '13 at 18:28
    
@Silvia That's crazy. Perhaps the WhenEvent[ ] thing isn't mature enough –  belisarius Dec 24 '13 at 19:25

1 Answer 1

up vote 5 down vote accepted

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 froms 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.

share|improve this answer
1  
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 –  belisarius Dec 25 '13 at 4:23
    
@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. –  Michael E2 Dec 25 '13 at 4:42
1  
@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. –  Michael E2 Dec 25 '13 at 5:01
1  
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." –  belisarius Dec 25 '13 at 5:13
1  
@belisarius I didn't mean that either. I just meant I don't think my friends will understand it. :) –  Michael E2 Dec 25 '13 at 5:16

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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