Message Boards Message Boards

0
|
5554 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

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 *)
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.

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