# Finding Functional Values from the Original Domain Using BSplineFunction

Providing a set of 2D points to BSplineFunction returns a function that requires that the input parameter to the function be between [0,1] no matter what the original domain of the points. In the 2D case that I'm interested in, what is returned from this function are two values: a value in the original units of the domain and its functional value. In other words an x and a y. I am primarily interested in finding the functional value associated with particular domain values. I have seen this before in this forum for example: Does anyone know a better approach than what follows? I have seen essentially a similar question posed before https://mathematica.stackexchange.com/questions/43565/converting-a-bsplinecurve-to-function. The responses to this post do not directly address the person's issue nor mine if I understand them correctly. It seems there is no direct way to provide a domain value and get its functional value. Here's a way to do it but it is slow and computationally expensive:

    (* p = 2D matrix of points*)
(* f = Function returned by BSplineFunction *)
(* bsp = A table of 301 returned values providing f with values from \
[0,1] in increments of 1/300 *)
(* tstf = A function that returns the first of the two values \
returned by f (which is a value in the domain of the points p). *)
(* a= A table of values between [0,1] that minimizes the squared \
difference between the domain value I want and what is output by f. *)
(* xy = 2D matrix containing the domain values I desire in the first \
column and their functional values in the second column. *)

p = {{400, 0}, {428, 0}, {477, 0}, {545, .5}, {596, 0}, {639,0}, {700,0}};
f = BSplineFunction[p];
bsp = Table[f[t], {t, 0, 1, 1/300}];
tstf[t_?NumericQ] := f[t][[1]];
Clear[u]
a = Table[ u /. NMinimize[{(tstf[u] - k)^2, 0 <= u <= 1}, u][[2]], {k,400,700}];
xy = Table[{k + 399, f[a[[k]]][[2]]}, {k, 1, 301}];


Here's a plot of bsp:

Here's a plot of xy:

They look identical but for bsp the x-values are given by f with values determined by using [0,1] stepping from 0 to 1 in equal increments of 1/300. The returned domain values are not the integer values in xy. Does anyone have a better solution than finding those [0,1] values that produce a specific domain value as I am with NMinimize?

• What you have done is essential how it needs to be done. We could probably think of ways to speed it up a bit, but in the end you are finding a lot of roots of cubic polynomials. – george2079 Apr 15 '16 at 20:47

this is essentially the same, but a good bit faster, first tabulate the curve to get good starting values then use FindRoot:

tab = Table[{u, tstf[u]}, {u, 0, 1, .01}];
start = (tab[[# - 1, 1]] &@
First@FirstPosition[tab, {u_, v_ /; v > #}]) & /@
Range[400, 699];
AppendTo[start, 1];
a = Table[(u /. FindRoot[tstf[u] == k, {u, start[[k - 399]]}]),
{k, 400,700}];
ListPlot[f /@ a]


verify we found all the integers:

Max[Abs[(f /@ a)[[All, 1]] - Range[400, 700]]]


1.47793*10^-12