6
$\begingroup$

This question already has an answer here:

Take a simple BSplineFunction and evaluate it at 0.25.

pts = {{1, 1}, {2, 3}, {3, -1}, {4, 1}, {5, 0}};
f = BSplineFunction[pts];
f[0.25]

and you get:

{2.1875, 1.6875}

Now try the reverse: find a value for the parameter whose result is closest to the line x==2.1875?

FindMinimum[(f[t][[1]]-2.1875)^2,t]

and you get:

{0., {t -> 2.1875}}

The minimum may be correct, but the parameter value is wrong. Plotting the expression clearly shows a minimum at 0.25.

Plot[(f[t][[1]] - 2.1875)^2, {t,0,1}]

Plot of the square of the difference of the first part of the B-spline function at t and 2.1875 as t goes from 0 to 1.  A parabolic-looking function with a clear minimum at 0.25

$\endgroup$

marked as duplicate by Mr.Wizard Aug 13 '16 at 14:23

This question has been asked before and already has an answer. If those answers do not fully address your question, please ask a new question.

  • 1
    $\begingroup$ BSplineFunction[] does not do well when all you need is one component for optimization or root-finding. If need be, you can reconstruct the expression in terms of BSplineBasis[], as was done here. $\endgroup$ – J. M. will be back soon Aug 13 '16 at 2:41
  • 2
    $\begingroup$ f[t][[1]] evaluates to t, so the FindMinimum expression in the question really is FindMinimum[(t - 2.1875)^2, t], which is satisfied by {0., {t -> 2.1875}}. $\endgroup$ – bbgodfrey Aug 13 '16 at 4:43
  • $\begingroup$ See specifically: (26037). Also related: (14645), (21662) $\endgroup$ – Mr.Wizard Aug 13 '16 at 14:23
5
$\begingroup$

Define

g[t_?NumericQ] := BSplineFunction[pts][t][[1]]

Then,

Minimize[(g[t] - 2.1875)^2, t]
(* {0., {t -> 0.25}} *)

which is the desired result. (NMinimize[(g[t] - 2.1875)^2, t] and FindMinimum[{(g[t] - 2.1875)^2, 0 <= t <= 1}, t] // Chop also give the desired result.)

Why this works while

FindMinimum[(f[t][[1]] - 2.1875)^2, t]
(* {0., {t -> 2.1875}} *)

does not can be seen from the FindMinimum documentation (Details and Options section):

FindMinimum first localizes the values of all variables, then evaluates f with the variables being symbolic, and then repeatedly evaluates the result numerically.

In other words, FindMinimum first converts (f[t][[1]] - 2.1875)^2 to (t - 2.1875)^2 and then minimizes the latter expression. The function g prevents this from happening by blocking symbolic evaluation.

Incidentally, Plot does not first do symbolic evaluation and so does not create this problem. Forcing it to perform symbolic evaluation first yields a curve different from that in the question.

Plot[Evaluate[(f[t][[1]] - 2.1875)^2], {t, 0, 3}]

enter image description here

which does have a minimum at t == 2.1875, as expected.

$\endgroup$

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