The defintion of B-Spline basis function as shown below:
Let $\vec{U}=\{u_0,u_1,\ldots,u_m\}$ a nondecreasing sequence of real numbers,i.e, $u_i\leq u_{i+1}\quad i=0,1,2\ldots m-1$
$$N_{i,0}(u)= \begin{cases} 1 & u_i\leq u<u_{i+1}\\ 0 & otherwise \end{cases} $$ $$N_{i,p}(u)=\frac{u-u_i}{u_{i+p}-u_i}N_{i,p-1}(u)+\frac{u_{i+p+1}-u}{u_{i+p+1}-u_{i+1}}N_{i+1,p-1}(u) $$
Although I know that Mathematica owns a built-in function BSplineBasis
,
however, I would like to write my auxiliay function $N_{i,p}(u)$ to learn the NURBS
theory and Mathematica programming.
NBSpline
Alogrithm:
(*=======================Caculate N[i,0](u)================================*)
NBSpline[i_Integer, 0, u_Symbol, U : {Sequence[_] ..}] /;
i <= Length[U] - 2 :=
Piecewise[
{{1, U[[i + 1]] <= u < U[[i + 2]]},
{0, u < U[[i + 1]] || u >= U[[i + 2]]}}]
(*=======================Caculate N[i,p](u)================================*)
NBSpline[i_Integer, p_Integer, u_Symbol, U : {Sequence[_] ..}?OrderedQ] /;
p > 0 && i + p <= Length[U] - 2 :=
Module[{ini},
ini = Table[NBSpline[j, 0, u, U], {j, i, i + p}];
First@Simplify@
Nest[
Dot @@@
(Thread@
{Partition[#, 2, 1],
With[{m = i + p - Length@# + 1},
Table[
{(u - U[[k + 1]])/(U[[k + m + 1]] - U[[k + 1]]),
(U[[k + m + 2]] - u)/(U[[k + m + 2]] - U[[k + 2]])}, {k, i, i + Length@# - 2}]]}) &,
ini, p]
]
Test
NBSpline[1, 3, u, {1, 2, 3, 4, 5, 7}] // TraditionalForm
In my function NBSpline
I avoid the condition $u_i=u_{i+1}$, because it will occured the case $\frac{0}{0}$
In the book "The NURBS book", it defines this quotient $\frac{0}{0}$ to be zero.
Question
How to deal with the condition $\frac{0}{0}$ that I sometimes need to set it to 0 ? Namely, How to deal with the condition $u_i=u_{i+1}$ in B-Spline basis function?
Quiet@Block[{Indeterminate = 0}, 0/0]
$\endgroup$NBSpline[1, 3, u, {1, 1, 3, 4, 5, 7}]
give a result without warning, however,NBSpline[1, 3, u, {1, 1, 1, 4, 5, 7}]
andNBSpline[1, 3, u, {1, 1, 2, 2, 5, 7}]
give the warning informtionPower::infy: Infinite expression 1/0 encountered. >>
$\endgroup$0/0
is not the only way, and, given your comment, it's probably not a good way. $\endgroup$