Message Boards Message Boards

1
|
4112 Views
|
9 Replies
|
3 Total Likes
View groups...
Share
Share this post:

A problem of FindRoot with BSplineFunction

Posted 2 years ago

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!

POSTED BY: Jianhua Yang
9 Replies

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:

enter image description here

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

enter image description here

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 BY: Neil Singer

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 BY: Henrik Schachner
Posted 2 years 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 BY: Jianhua Yang
Posted 2 years ago

Thank you! It's a good idea to solve my problem.

POSTED BY: Jianhua Yang

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 BY: Neil Singer
Posted 2 years 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 BY: Jianhua Yang

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`}  *)
POSTED BY: Henrik Schachner

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}]
POSTED BY: Gianluca Gorni
Posted 2 years ago

Interesting implementation, thank you for sharing! Strongly related MMa.SE question with another implementation:

POSTED BY: Alexey Popkov
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract