Mathematical Principles for Scientific Computing and Visualization  
http://www.farinhansford.com/books/scv
by Gerald Farin and Dianne Hansford


This notebook illustrates B-spline basis functions as illustrated in Figures 8.8 and 8.9.
A recursive definition of B-spline basis function is used. This is defined in Eqn (8.10-11).

Input: 
The degree n (set to 3 here)
The knot vector u -- see how it is set below.

Output:
Plots of the 6 basis function for the knot vector we have selected.

The plots are hard-coded for the five functions we wanted to illustrate here. You can improve the code by making this more flexible for an arbitrary  input knot vector.

See Chapter 8: Data Fitting for details.

Updated May 2008

(SetDirectory[ToFileName[Extract["FileName"/.NotebookInformation[EvaluationNotebook[]],{1},FrontEnd`FileName]]];) 

(* Define a zero tolerance *)
eps=5.0^-9;

(* Define functions building the piecewise polynomials *)
(* If a knot interval is not zero-length, then calculate the relative position of the insertion point within the given interval *)

spanleft[n_,knots_,i_,x_]:=
If[Abs[knots[[i+n+1]]-knots[[i+1]]]<eps,0,((x-knots[[i+1]])/(knots[[i+n+1]]-knots[[i+1]]))];

spanright[n_,knots_,i_,x_]:=
If[Abs[knots[[i+n+2]]-knots[[i+2]]]<eps,0,((knots[[i+n+2]]-x)/(knots[[i+n+2]]-knots[[i+2]]))];

(* Recursive definition of a B-spline *)

bspline[n_,knots_,i_,x_]:=If[x≥knots[[i+1]]&&x<knots[[i+2]],1,0];

bspline[n_,knots_,i_,x_]:=spanleft[n,knots,i,x] bspline[n-1,knots,i,x]+spanright[n,knots,i,x] bspline[n-1,knots,i+1,x]/;n>0;

(* Here are two know vectors -- from Figures 8.8 and 8.9 *)
(*
(u={0,0,0,0,1.333`,1.7`,2.`,2.`,2.`,2.1`};) 
*)

(u={0,0,0,0,0.6666`,1.3333`,2.`,2.`,2.`,2.1`};) 


(* Establish some relationships between the degree of the polynomials, the number of knot intervals and the number of polynomials *)
n=3;

(* k is really a function of the degree -- hard coded to three here *)
k=Length[u]-3;

(* Compute number of basis functions -- there are l+1 of them *)
l=k-n+1;

Print["Input  "] 
Print["knot vector = ",u] 
Print["degree n=",n] 
Print["knots u_0, ... ,u_k  where k=",k] 
Print["basis fcts N_0, ... N_l where l=",l] 

(* Plot each of the B-spline functions *)
(* For our example above, we know that there are 0 ...5 of them *)

fct0=Plot[bspline[n,u,0,x],{x,u[[2]],u[[Length[u]-1]]},
PlotRange->{{0,u[[Length[u]-1]]},{0,1}},
AspectRatio->Automatic,PlotStyle->Thickness[0.01`],BaseStyle->{"FontFamily"->"Helvetica","FontSize"->11}]

fct1=Plot[bspline[n,u,1,x],{x,u[[2]],u[[Length[u]-1]]},
PlotRange->{{0,u[[Length[u]-1]]},{0,1}},
AspectRatio->Automatic,PlotStyle->Thickness[0.01`],BaseStyle->{"FontFamily"->"Helvetica","FontSize"->11}]

fct2=Plot[bspline[n,u,2,x],{x,u[[2]],u[[Length[u]-1]]},
PlotRange->{{0,u[[Length[u]-1]]},{0,1}},AspectRatio->Automatic,PlotStyle->Thickness[0.01`],BaseStyle->{"FontFamily"->"Helvetica","FontSize"->11}]

fct3=Plot[bspline[n,u,3,x],{x,u[[2]],u[[Length[u]-1]]},
PlotRange->{{0,u[[Length[u]-1]]},{0,1}},AspectRatio->Automatic,PlotStyle->Thickness[0.01`],BaseStyle->{"FontFamily"->"Helvetica","FontSize"->11}]

fct4=Plot[bspline[n,u,4,x],{x,u[[2]],u[[Length[u]-1]]},
PlotRange->{{0,u[[Length[u]-1]]},{0,1}},
AspectRatio->Automatic,PlotStyle->Thickness[0.01`],BaseStyle->{"FontFamily"->"Helvetica","FontSize"->11}]

fct5=Plot[bspline[n,u,5,x],{x,u[[2]],u[[Length[u]-1]]},
PlotRange->{{0,u[[Length[u]-1]]},{0,1}},
AspectRatio->Automatic,PlotStyle->Thickness[0.01`],BaseStyle->{"FontFamily"->"Helvetica","FontSize"->11}]

(* Plot them all together *)
plt=Show[{fct0,fct1,fct2,fct3,fct4,fct5}] 

Export["bspls_uniform.eps",plt];