I'm working on a cops & robbers game, and there is one single event that is very very important, the event of catching someone. I'm trying to do when any robber is catched, delete it from the robbers array. I think it must be done with WhenEvent

A cop catches a robber if the circles that define them are touching.

A visual representation can be seen here.

There is an array showing the initial positions of all (let's say cops=5 and robbers=3) the cops & robbers

The arrays are like this (the 0 is the time):

cops = 5; robbers = 3;
Array[c[#][0] &, cops]
Array[r[#][0] &, robbers]

The NDSolve looks like this:

   r[i]'[t] == v[r[i][t], b[r[i][t]]~Join~Array[c[#][t] &, cops], 2],
   {i, robbers}
   c[i]'[t] == -v[c[i][t], Array[r[#][t] &, robbers], 4],
   {i, cops}
  (*initial positions*)
   Array[r[#][0] &, robbers] == {{1,2},{3,4},{5,6}}
   Array[c[#][0] &, cops] == {{6,5},{4,3},{2,1}}
 Array[c, cops]~Join~Array[r, robbers],
 {t, 0, 10},
 FilterRules[{opts}, Options[NDSolve]],
 Method -> {"EquationSimplification" -> "Solve"}

I'm guessing to put something like:

        Array[r[#][t] &, robbers]->
            Array[r[#][t] &, robbers],

But doesn't work, I'm guessing because NDSolve can't calculate with this method lists of functions that vary with time.


1 Answer 1


I can't make NDSolve let you change the length of the solution vector either, but I can suggest a workaround. Placing the action "StopIntegration" in your WhenEvent can halt NDSolve at a critical event. You can then restart the integration after changing the equations however you like. Here's an example for a linear system that loses a dimension and changes its behavior when the first variable crosses zero.

f[x_?VectorQ, A_] := A.x;
T = \[Pi];
x0 = {1, 0};
stop = 0;
  A = Switch[i, 1, {{0, 1}, {-1, 0}}, 2, {{-1}}];
  sol[i] = First@NDSolve[{
      x'[t] == f[x[t], A],
      x[stop] == x0, 
      WhenEvent[x[t][[1]] == 0, stop = t; "StopIntegration"]}, 
     x, {t, stop, T}];
  x0 = x[stop] /. sol[i];
  x0 = Rest[x0],{i,2}];
Show @@ Table[
  Plot[x[t] /. sol[i], Evaluate[Join[{t}, sol[i][[1, 2, 1, 1]]]],
   PlotRange -> {{0, T}, {-1, 1}}], {i, 2}]

Sorry, that last line is not very elegant. Also note, in this example I let the variable x[t] be a vector, rather than supplying several variables x[i][t]. The only trick to making this work is the conditional definition for f, which prevents symbolic evaluation of the integrand.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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