1

I've got a physics simulation that uses NDSolve and returns a vector-valued InterpolationFunction, by which I mean that the InterpolationFunction takes one scalar variable representing time and returns a list of two scalar numbers representing x and y coordinates:

r[0.1]
(* ==> {0.809018, 0.587785} *)

It's easy to extract just one component of the function's return value:

r[0.1][[1]]
(* ==> 0.809018 *)

Now, the problem. I'm trying to find the time at which one particular coordinate is maximal. If I had a normal, single-valued function for the x-coordinate, I'd just do this:

FindMaximum[x[t],{t,0.95}]
(* ==> {6.28315, {t -> 1.00003}} *)

However, I can't figure out how to make FindMaximum pay attention to just one component of the vector function. This fails:

FindMaximum[v[t][[2]], {t, 0.95}]
(* ==> Part 2 of InterpolatingFunction[...][t] does not exist. *)

So does this, and every similar variant I've tried:

FindMaximum[v[#][[2]] &, {t, 0.95}]
(* ==> FindMaximum::nrnum: The function value -(v[#1][[2]]&) is not a real number at {t} = {0.95}. *)

FindMaximum[(v[#] &)[[2]], {t, 0.95}]
(* ==> Part 2 of v[#1]& does not exist. *)

It seems that Part is being applied before the function is evaluated, no matter what I do. Can I change that?

Update: A more general, and probably more useful question, is: How can I separate a vector-valued (list-returning) InterpolationFunction into separate single-valued functions, which I could then use with FindMaximum or other Mathematica functions that require a single-valued function for an argument?

J. M.'s missing motivation
  • 124,525
  • 11
  • 401
  • 574
ibeatty
  • 2,533
  • 11
  • 22
  • Maybe Evaluate[v[t][[2]]]? – corey979 Oct 03 '16 at 16:43
  • 2
    Why not define x[t_?NumericQ] := r[t][[1]] and maximize that? Or... since you're using NDSolve[], why not use event detection to get the maximum as a side effect of solving your DE? – J. M.'s missing motivation Oct 03 '16 at 16:52
  • I don't use event detection because I'm generating some solution trajectories and then doing a whole range of after-the-fact exploratory investigation of the solutions, of which finding minima and maxima are only one small part. – ibeatty Oct 03 '16 at 16:57
  • 1
    @J.M. your x[t_?NumericQ] fixes the error. Can you please explain why is it needed at all? The _NumericQ is essential. – BlacKow Oct 03 '16 at 17:00
  • I also thought of defining x[t_] := r[t][[1]] and maximize that, but it also fails for a reason I don't fully understand. I'll post that as an update to the original question. Including ?NumericQ doesn't make it work for me. – ibeatty Oct 03 '16 at 17:03
  • 2
  • @ibeatty, can you come up with a (hopefully minimal) example where the inclusion of ?NumericQ does not work? – J. M.'s missing motivation Oct 03 '16 at 17:05
  • @J.M. Thank you! – BlacKow Oct 03 '16 at 17:06
  • @J.M. Okay, x[t_?NumericQ] does in fact work for me. Apparently I had a stale definition of x[t_] hanging around mucking things up, but when I did Clear[x], your solution started working for me. (Thanks!) I'll read up on why NumericQ does what it does... – ibeatty Oct 03 '16 at 17:21
  • 1
    For anybody interested in the question of how to fillet a vector-valued InterpolatingFunction[] into its components, this might be useful. – J. M.'s missing motivation Oct 03 '16 at 17:25

0 Answers0