Message Boards Message Boards

FindMinimum problem with Interpolated curve

Posted 8 months ago

Here's is a simple example.

If the curve is defined as c[t], interpolating 2D points, FindMinimum doesn't work. If it is defined as {c1[t],c2[t]}, where c1 interpolates the x-values, and c2 interpolates the value, it works. Is there some reason I should expect this, from some (deeper than I understand) nature of Mathematica, or should we call this (gasp!) a bug?

POSTED BY: David Golber
9 Replies
Posted 8 months ago

OK ... if instead of

FindMinimum[dsq[c[t],q],{t,.3,.301}]

we define

f[t_?NumberQ] := dsq[c[t], q];

Then

FindMinimum[f[t], {t, .3,.301}];

works.

I can't say that i understand why it shouldn't work in the original. But I guess

f[t_?NumberQ] 

for the function to be minimized avoids all sorts of stuff I don't understand. It just tells FindMinimum "Just do the numbers". ... and we both understand numbers in the same way.

POSTED BY: David Golber

The problem is that when faced with c[t] - {2, -1} symbolically, it treats c[t] as a number, so that the result is {c[t]-2,c[t]+1}.

POSTED BY: Gianluca Gorni
Posted 8 months ago

Well,, thanks for the reply. But why "it treats c[t] as a number,"? when it should know that c[t] is a 2-list, since it was generated that way. As I said, too deep for me. My conclusion: just make the argument of FindMinimum a function that only takes numerical arguments and returns a numerical result, and mysterious "treats as" questions go away...

POSTED BY: David Golber

Yes, this indeed seems a bit strange! On my system (13.3.0 for Linux x86 (64-bit) (June 3, 2023)) this does work:

FindMinimum[dsq[c[t], q], {t, .3}]
(*  Out:    {9.487787469526271`,{t\[Rule]0.5303065649428684`}}  *)

but this answer is wrong!

Based on the good catch of @Gianluca Gorni consequently a correct result can be obtained like so:

FindMinimum[dsq[Threaded@c[t], q], {t, .3}]

As an aside: A completely different approach could use regions and friends:

paramReg = DiscretizeGraphics[ParametricPlot[c[t], {t, 0, 1}]];
rnst = RegionNearest[paramReg, q];
ParametricPlot[c[t], {t, 0, 1}, Epilog -> {Red, PointSize[Large], Point[q], Green, Line[{q, rnst}]}, 
 PlotRange -> {Automatic, {-1.1, Automatic}}]

enter image description here

POSTED BY: Henrik Schachner
Posted 8 months ago

I think (the Mathematica priests will say) that c is a function whose values are 2-lists. It is not two functions. As i say, this is too subtle for me ...

POSTED BY: David Golber
Posted 8 months ago

Thanks again. I am running Mathematica 12. It does not have "Threaded", but it does have "Thread".

POSTED BY: David Golber

I wouldn't call myself a priest of Mathematica, and you surely have exposed a pitfall in the system, into which I could have fallen myself. I am just trying to explain the reasons behind the problem. Your symbolic expression c[t] has an InterpolatingFunction object as Head; it only becomes a List when t is a number. When faced with c[t]+{a,b}, the c[t] is not treated as a list. Yes, I suppose that Mathematica could be programmed to check if c[t] could become a list of length 2 when t is numeric, but this would imply messing with addition, and making it slower in many other circumstances (maybe, I am just guessing). So, until Wolfram changes the behaviour of Plus, the creator of a vector-valued InterpolatingFunction must take care of its creature. The same pitfall holds for other constructs, for example

a[t_] := Piecewise[{{{t, t}, t > 0}}, {0, 0}]

This is meant to be a vactor-valued function, but try what happens with a[t]+{1,2}.

Your solution to define f[t_?NumberQ] := dsq[c[t], q]is perfectly valid, because this way the expressions c[t]-q and c[t]+q will only be evaluated when t is a number, and there is no symbolic pre-processing. Another solution could be to restrict the definition of dst to explicit lists:

Clear[dst];
dst[p_List, q_List] := (p - q) . (p - q);
FindMinimum[dst[c[t], q], {t, .3, .301}]
POSTED BY: Gianluca Gorni

Update: Henrik's suggestion to use Threaded is also a good solution. Perhaps contrary to its name, Threaded prevents the threading of Plus in such cases as Threaded[a] + {1, 2}, when a is not a list. Threaded was introduced in version 13.1 and is stille experimental.

This is rather subtle stuff.

POSTED BY: Gianluca Gorni
Posted 8 months ago

Thanks for this. I think I am beginning to understand this.

POSTED BY: David Golber
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract