4
$\begingroup$

I have a Spline function defined as follows.

Points = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};

bsf = BSplineFunction[Points, SplineDegree -> 1];

A Parametric Plot look like this:

ParametricPlot[bsf[r], {r, 0, 1}]

enter image description here

But when I try to do NIntegrate, I get for the first component

NIntegrate[bsf[t][[1]], {t, 0, 1}] 

An output of 0.5 as it should be, but for the second component

NIntegrate[bsf[t][[2]], {t, 0, 1}]

I get as an output

enter image description here

I still get the correct output though. But If I just type

NIntegrate[bsf[t], {t, 0, 1}]

I just get error

enter image description here

enter image description here

Why is this and how can I fix this?

Thanks in advance!

$\endgroup$
2
  • $\begingroup$ You should look at InputForm[bsf] to see what you are extracting with your part specifications. I don't think you are getting what you intend. Also, I think we are running in circles here because you haven't disclosed your true goal. From your previous question, for what purpose do you want a parametric representation of those lines? If you are trying to get the area enclosed by some points there are other more direct ways. Please explain your underlying problem (perhaps in a new question) and we may be able to help you better. $\endgroup$
    – MarcoB
    Commented Jan 6, 2023 at 17:18
  • $\begingroup$ Define a new function that only accepts numerical arguments: gg[t_?NumericQ, index_] := bsf[t][[index]]. Then you can feed this to NIntegrate, e.g. NIntegrate[gg[t, 2], {t, 0, 1}] yields 0.5. The issue is that bsf[t] doesn't evaluate to a list of two elements until after you have entered a numerical value for t. I haven't figured out yet if there's a way to extract the two component functions. $\endgroup$
    – march
    Commented Jan 6, 2023 at 21:06

2 Answers 2

5
$\begingroup$

Indexed.

NIntegrate[Indexed[bsf[t], 1], {t, 0, 1}]
NIntegrate[Indexed[bsf[t], 2], {t, 0, 1}]

0.5.

0.5.

$\endgroup$
3
$\begingroup$

There are two options I could come up with here. The first is to define your bsf function to only accept numerical inputs. That is,

Points = {{0, 0}, {0, 1}, {1, 1}, {1, 0}, {0, 0}};
bsf = BSplineFunction[Points, SplineDegree -> 1];
bsfNum[t_?NumericQ, index_] := bsf[t][[index]]

Then,

NIntegrate[gg[t, 1], {t, 0, 1}]
NIntegrate[gg[t, 2], {t, 0, 1}]
(* 0.5 *)
(* 0.5 *)

The issue is that bsf[t] doesn't evaluate to a list of two elements until after you have entered a numerical value for t, and this forces Mathematica to define a numerical function instead.

Alternatively, we can construct the B-spline functions from the BSplineBasis functions, using the knots generated internally by BSplineFunction. We define,

bsfKnot[t_] = Sum[
   Points[[j + 1]] BSplineBasis[{1, Rationalize@First@bsf["Knots"]}, j, t],
   {j, 0, Length@Points - 1}
  ];

Then, this seems to be the right function:

ParametricPlot[bsfKnot[t], {t, 0, 1}]

enter image description here

In addition, we can use Integrate or NIntegrate:

Integrate[bsfKnot[t][[2]], {t, 0, 1}]
NIntegrate[bsfKnot[t][[2]], {t, 0, 1}]
(* 1/2 *)
(* 0.5 *)
$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.