7
$\begingroup$

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$
3
  • 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$ Aug 13, 2016 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, 2016 at 4:43
  • $\begingroup$ See specifically: (26037). Also related: (14645), (21662) $\endgroup$
    – Mr.Wizard
    Aug 13, 2016 at 14:23

1 Answer 1

6
$\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.