/* B-spline package (based on DeBoor's FORTRAN package) test problem: fit sin ( pi*x) for 0<=x<=1 with constraints that the function has zero derivatives at the endpoints the test problem uses the linear system solution routines of Chapter 2 to solve for the coefficients of the fit. the fundamental B-spline routines do not use the linear system solver themselves from Handbook of C tools for scientists and engineers by L. Baker DEPENDENCIES: linear systems solver from Chapter 3 */ /*#include "libc.h" #include "math.h" */ #define DOFOR(i,to) for(i=0;i(b)? (a):(b)) /* determines which interval (between knots) the location x is uses binary search */ interv(t,nbk,x,left,mflag) int nbk,*left,*mflag; float x,t[]; { int i,n,top,btm; float below,above; n=nbk-1;/*index of last value in t[]*/ if(x=t[n]) {*mflag=1;*left=n;} else { *mflag=0; /*search*/ /* binary search*/ btm=0;top=n; while(1){ i=(top+btm)>>1; below=t[i];above=t[i+1]; /*printf(" top,btm,i %d %d %d\n",top,btm,i);*/ if( below<=x) { if(x=above*/ btm=i; } else{ /* xnb )jshift=nb-k+1; bsplvd(t,k,x,ilft,work,vnikx,1); DOFOR(j,k) { it=jshift-1+j; cm INDEC(i+1,it,nb)= vnikx INDEC(j,0,k); /*if (!j)printf(" first it=%d\n",it);*/ r[i+1]=yi[i]; } } /*left limits of last two eqns*/ nderiv=3;/*second derivative b.c.*/ jshift=nb-km1; bsplvd(t,k,xi[nm1],ilft,work,vnikx,nderiv); DOFOR(j,k) { it=jshift+j-1; /*if(!j)printf(" first it=%d\n",it);*/ cm INDEC(nb-2,it,nb)= vnikx INDEC(j,0,k); cm INDEC(nb-1,it,nb)= vnikx INDEC(j,2,k); } r[nb-2]=yi[nm1]; r[nb-1]=0.;/*second deriv.=0*/ /* lufact backsub solve system cm x= r*/ printm(cm,nb,nb,nb,nb); lufact(cm,nb,nb,pivot,&info); if(info!=0)printf(" info=%d\n",info); DOFOR(i,nb)printf("data r=%e\n",r[i]); backsub(cm,nb,nb,pivot,r); DOFOR(i,nb)printf("solution=%e\n",r[i]); DOFOR(i,20) { x=i*.05; y=bvalue(t,r,nb,k,x,0); z=bvalue(t,r,nb,k,x,1)/3.14159265358979;/* deriv of sin=cos*/ printf(" x=%f sin=%f exact=%f cos=%f\n",x,y,sin(x*3.14159265),z); } } /* bvalue returns the jderiv-th derivative of a function represented by a bspline, at any point x within the range of the fitted function. uses interv() */ float bvalue(t,bcoef,n,k,x,jderiv) int n,k,jderiv; float t[],bcoef[],x; { int i,ilo,nmi,imk,j,jc,jcmin,jcmax,jj,kmj,km1,mflag,nm1; float fkmj,aj[jmax],dl[jmax],dr[jmax]; if(jderiv>=k)return (0.); interv(t,n+k,x,&i,&mflag); if(mflag)return(0.); km1=k-1; if(km1<=0)return(bcoef[0]); jcmin=0; imk=i-k; /*printf(" i %d,k %d,imk %d\n",i,k,imk);*/ if(imk<-1) { jcmin=-1-imk; DOFOR(j,i+1)dl[j]=x-t[i-j]; for(j=i;j