How to deal with the condition $u_i=u_{i+1}$ in B-Spline basis function?
Is this the behaviour you need?
Solution
Unprotect[Power];
Power[0, -1] = 1
Protect[Power]
Examples
0/0
0
Explanation
Revert to normal
Unprotect[Power];
ClearAll[Power];
Protect[Power];
Here is one way to deal with repeated entries in U
. One can define a function to compute the coefficient, using one rule when $u_i = u_j$ and the general formula otherwise. One might put extra conditions on the patterns in coeff
below, but if the function is called only within NBSpline
, then one might assume the conditions are met.
ClearAll[coeff];
coeff[u_, i_, j_, U_] /; U[[i]] == U[[j]] := 0;
coeff[u_, i_, j_, U_] := (u - U[[i]])/(U[[j]] - U[[i]])
Then change the definition of NBSpline
for p != 0
as follows.
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[{
coeff[u, k + 1, k + m + 1, U],
coeff[u, k + m + 2, k + 2, U]},
{k, i, i + Length@# - 2}]]}) &, ini, p]]
Example:
NBSpline[1, 3, u, {1, 2, 2, 4, 5, 7}]
The output of NBSpline[1, 3, u, {1, 2, 3, 4, 5, 7}]
agrees with the output in the question.
P.S. The pattern U : {Sequence[_] ..}?OrderedQ
is equivalent to U_List?OrderedQ
. You might want a check that restricts U
to be a list of numbers, since an ordered list of symbols such as {a, b, c}
passes the OrderedQ
test. The pattern U_?(VectorQ[#, NumericQ] && OrderedQ[#] &)
is one way.