# A problem of FindRoot with BSplineFunction

Posted 13 days ago
273 Views
|
9 Replies
|
3 Total Likes
|
 Hi! I have a problem like the following, data={{-1,2.9},{0.5,3.6},{1.0,5.5},{1.5,-4.2},{2.0,3.5}}; f=BSplineFunction[data]; FindRoot[f[t][[1]]==0,{t,0,0.2}] However, FindRoot firstly wokes like f[t][[1]]=t, but not to find the root of the first argument of f[t]. How can I get the root which one I wanted? Thanks!
9 Replies
Sort By:
Posted 13 days ago
 BSplineFunction returns a parameterized function with a domain that goes from 0 to 1. You need to find your root in the region between 0 and 1 and then use the function to get an {x,y} pair. Secondly, you can't use Part ([[]]) until the value is numeric because it will try to rip apart your spline function. Show[Graphics[{Red, Point[data], Green, Line[data]}, Axes -> True], ParametricPlot[f[t], {t, 0, 1}]] will plot your spline with the control points and show you the parametric function:To find a root when the y value of the parametric plot crosses zero, you need to force Part to wait until the value of the function is numeric. g[t_?NumberQ] := Last[f[t]] or g[t_?NumberQ] := f[t][[2]] g returns the y value of the parametric function, f.you can test it Plot[{t, g[t]}, {t, 0, 1}] You plot from 0 to 1 and get the x values (a line) and the y values.You can now get both roots: In[24]:= r1 = FindRoot[g[t], {t, 0.4, 0.2, 1}] Out[24]= {t -> 0.687292} In[25]:= f[t] /. r1 Out[25]= {1.29408, 2.498*10^-16} In[26]:= r2 = FindRoot[g[t], {t, 0.9, 0.2, 1}] Out[26]= {t -> 0.885562} In[27]:= f[t] /. r2 Out[27]= {1.69298, 1.55431*10^-15} Regards,Neil
Posted 13 days ago
 Thank you very much, Neil Singer! The problem is that I don't know how to make FindRoot calculate f[t] at some point of division before giving the part of f[t]. Your direction is help me a lot.
Posted 13 days ago
 Here is one more solution - for me it is the first time I can make use of FunctionInterpolation: fi = FunctionInterpolation[First[f[t]], {t, 0, 1}]; FindRoot[fi[t], {t, .2}] 
Posted 13 days ago
 Thank you! It's a good idea to solve my problem.
Posted 13 days ago
 I may have misunderstood which root you were trying to find. If you want to find the crossing of the x axis, as Henrik understood, then similarly you need to use First instead of Last in the g function above (or use Henrik's approach).Regards.
Posted 13 days ago
 It's not important. You two gave me some good ideas to deal with the problem. The key problem is how to find the root of any one component of BSplineFunction such as f[t] with FindRoot. f[t] is a two components function in some sense. Thank you again.Best regards!
Posted 13 days ago
 The key problem is how to find the root of any one component of BSplineFunction ... Well, you could look for roots of the product of the components: fi = FunctionInterpolation[Times @@ f[t], {t, 0, 1}] (Somehow I could not avoid using FunctionInterpolation!) For finding (sort of) all roots in the interval [0, 1] you could try something (ugly) like this: DeleteDuplicates[N@Round[\[FormalT] /. Quiet@FindRoot[fi[\[FormalT]], {\[FormalT], #}], 1*^-7] & /@ Range[0, 1, .2]] (* Out: {0.1412204,0.6872917,0.8855624} *) 
 I have made my own implementation of BSplineFunction, to make it more usable: BSplineCurveFunction[pts_?MatrixQ] := Module[{knots, deg}, knots = Rationalize@BSplineFunction[pts][[6, 1]]; deg = BSplineFunction[pts][[3, 1]]; Apply[Function, List@ Sum[ pts[[i + 1]] BSplineBasis[{deg, knots}, i, #], {i, 0, Length[pts] - 1}]]]; data = {{-1, 2.9}, {0.5, 3.6}, {1.0, 5.5}, {1.5, -4.2}, {2.0, 3.5}}; g[t_] = BSplineCurveFunction[data][t][[1]] FindRoot[g[t] == 0, {t, 0, 0.2}] `