# Why don't optimization functions like FindMinimum work with functions like BSplineFunction? [duplicate]

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}]


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

• 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. – J. M. will be back soon Aug 13 '16 at 2:41
• 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}}. – bbgodfrey Aug 13 '16 at 4:43
• See specifically: (26037). Also related: (14645), (21662) – Mr.Wizard Aug 13 '16 at 14:23

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}]


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