Message Boards Message Boards

0
|
5495 Views
|
4 Replies
|
0 Total Likes
View groups...
Share
Share this post:

Integration along BSpline

Posted 10 years ago

I need to integrate along a parametric space curve defined by some data points. Here is a simple example that works in Version 10.

circle = Table[{Cos[ \[Pi] t ], Sin[  \[Pi] t ]}, {t, 0, 1, .1}];
interp[u_] := {
   ListInterpolation[circle[[All, 1]], {{0, 1}}][u], 
   ListInterpolation[circle[[All, 2]], {{0, 1}}][u]};
Show[Graphics[Point[circle]], ParametricPlot[interp[x], {x, 0, 1}]]
NIntegrate[
  interp[x], {x, 0, 1}]  (* returns {0,1/Pi} as expected *)

However, if I repeat this example with BSplineFunction providing the interpolation, the integration fails, because it thinks BSplineFunction is not numeric.

circle = Table[{Cos[\[Pi] t ], Sin[\[Pi] t ]}, {t, 0, 1, .1}];
Show[Graphics[Point[circle]], 
 ParametricPlot[BSplineFunction[circle][t], {t, 0, 1}]]
 NIntegrate[ 
 BSplineFunction[circle][t], {t, 0, 
  1}]  (* fails with NIntegrate::inum *)

I have tried my usual bag of tricks on this without any luck. Any hints on getting integration to work along a BSpline would be appreciated.

4 Replies
In[3]:= circle = Table[{Cos[\[Pi] t], Sin[\[Pi] t]}, {t, 0, 1, .1}];
        bsplinefunction = BSplineFunction[circle];
        int1[t_?NumericQ] := First[bsplinefunction[t]];
        int2[t_?NumericQ] := Last[bsplinefunction[t]];
        NIntegrate[{int1[t], int2[t]}, {t, 0, 1}, AccuracyGoal -> 10]

Out[7]= {2.77556*10^-17, 0.713855}
POSTED BY: Ilian Gachevski

My earliest failed attempt was:

circle = Table[{Cos[\[Pi] t], Sin[\[Pi] t]}, {t, 0, 1, .1}];
splat[t_?NumericQ] := BSplineFunction[circle][t];
NIntegrate[splat[t], {t, 0, 1}]  

So your ingenious splitting into parts was not something I would have tried. Well done.

This behavior of BSplineFunction is not as elegant as it could be.

Have you seen this post? - Computing arch length of a spline curve

POSTED BY: Vitaliy Kaurov

Yes and it suggested I could use NIntegrate along the BSpline. The post contains the code (simplified, by removing the derivative):

pts = {{1, 1}, {2, -1}, {3, 0}, {2, 1}, {1, 0}};
f = BSplineFunction[pts];
NIntegrate[Norm[f[t]], {t, 0, 1}]    (* works *)

but a further simplification (to a vector integrand), fails;

 NIntegrate[ 
     f[t], {t, 0, 1}] (* fails with NIntegrate::inum *)  

NIntegrate can handle vector integrands, so NIntegrate must not know that the head BSplineFunction can return a vector. When the BSpline is working on one dimensional data, NIntegrate works fine.

pts = { 1, 2, 3, 2, 1};
f = BSplineFunction[pts];
NIntegrate[f[t], {t, 0, 1}] (* works *)
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