0

I am currently experiencing a problem when I try to use FindRoot with an interpolating function that outputs a vector. I have constructed a minimal example that illustrates the problem.

Consider the following function, that parametrizes a circle in the plane.

circle[t_] := {Cos[t], Sin[t]};

Suppose you want to find the point at which the x coordinate of the circle equals one half.

FindRoot[ circle[t][[1]] - 0.5, {t, 0.1, 0, Pi/2}]

Of course, FindRoot finds the root:

{t -> 1.0472}

However, sometimes you do not have an exact function, and you need to use an InterpolatingFunction instead. The function circleInterpol is an interpolation of $100$ points sampled from the circle. Although the interpolation of lists of the type { t, {x,y}} is not considered in the reference, Mathematica does not issue any warnings and plotting using ParametricPlot works fine.

circleInterpol = Interpolation[ Table[{t, circle[t]}, {t, 0, Pi/2, Pi/200}]]
ParametricPlot[{circle[t], circleInterpol[t]}, {t, 0, Pi/2}]

However, when I try to use FindRoot in the same way as before:

FindRoot[circleInterpol[t][[1]] - 0.5, {t, 0.1, 0, Pi/2}]

but with circle replaced by circleInterpol, I get a completely different (and obviously wrong) result:

{t -> 0.5}

FindRoot does not issue any warnings at this point.

Changing the syntax to (I realize that {0.5, 0.1} is not a point on the circle, but since you take the first part anyway, this should not matter.)

FindRoot[(circleInterpol[t] - {0.5, 0.1})[[1]], {t, 0.1, 0, Pi/2}]

issues the warning:

FindRoot::nveq: The number of equations does not match the number of variables in
FindRoot[(circleInterpol[t] - {0.5, 0.1})[[1]], { t, 0.1, 0, Pi/2}]. >>

Replacing the interpolating function by the exact function still gives the correct result.

So it seems to me that something is going wrong with the combination of FindRoot and InterpolatingFunction. An obvious solution to the problem is to construct two interpolating functions; one for each coordinate (x and y). Although this would solve the problem, I do not understand why this extra step is necessary.

Could someone help me to understand what is going wrong here?

Artes
  • 57,212
  • 12
  • 157
  • 245
Koen
  • 198
  • 4
  • Try evaluating circleInterpol[t] and circleInterpol[t][[1]] and you'll see what's going wrong. It won't give you the result you expect if t is a symbol, only if t is a number. Solution: define fun[t_?NumericQ] := circleInterpol[t][[1]] and use that. Side note: don't build the interpolating function from exact numbers if you need good performance. Please read this too: http://support.wolfram.com/kb/3820 and http://mathematica.stackexchange.com/a/26037/12 – Szabolcs Feb 20 '14 at 17:11
  • @Szabolcs: Thanks for the quick reply and for recognizing the question as a duplicate. I understand that the problem is in the function evaluation. Because of this, it seems that the extra option Evaluated -> False in FindRoot also works. – Koen Feb 20 '14 at 21:49

0 Answers0