/* From: "COMPUTATIONAL PHYSICS, 2nd Ed" by RH Landau, MJ Paez, and CC Bordeianu Copyright Wiley-VCH, 2007. Electronic Materials copyright: R Landau, Oregon State Univ, 2007; MJ Paez, Univ Antioquia, 2007; & CC Bordeianu, Univ Bucharest, 2007 Support by National Science Foundation */ /* SplineAppl.c Cubic Spline fit to data, based on Press et al input array x[n], y[n] = tabulation function y(x),x0 < x1, output yout for given xout yp1 and ypn: 1st derivs at endpoints, evaluated internally, y2[n]: array of 2nd derivatives (setting yp1 or ypn >0.99e30 produces natural spline) */ #include #include #define n 9 #define np 15 #define Nfit 3000 // enter the desired number of points to fit main() { FILE *output1, *output2; output1 = fopen("Spline.dat","w"); // save data in Spline.dat output2 = fopen("Input.dat","w"); // input data, enter your own data here! double x[] = {0., 0.12, 0.25, 0.37, 0.5, 0.62, 0.75, 0.87, 0.99}; double y[] = {108.6, 16.,845.,883.5,52.8, 19.9, 10.8, 88.25, 84.7}; double xout, yout; double y2[9]; int i, klo,khi,k ; double h,b,a,p,qn,sig,un,yp1,ypn, u[n]; // input for (i = 0;i 0.99e30) y2[0]= u[0]= 0.0; else { y2[0] = (-0.5); u[0] = (3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yp1); } // decomposition loop; for (i = 1; i<= n-2; i++) { sig = (x[i]-x[i-1])/(x[i+1]-x[i-1]); p = sig*y2[i-1]+2.0; y2[i] = (sig-1.0)/p; u[i] = (y[i+1]-y[i])/(x[i+1]-x[i])-(y[i]-y[i-1])/(x[i]-x[i-1]); u[i] = (6.0*u[i]/(x[i+1]-x[i-1])-sig*u[i-1])/p; } // test for natural if (ypn > 0.99e30) qn = un = 0.0; else { // else evaluate second derivative qn = 0.5; un = ((3.0)/(x[n-1]-x[n-2])) *(ypn-(y[n-1]-y[n-2])/(x[n-1]-x[n-2])); } y2[n-1] = (un-qn*u[n-2])/(qn*y2[n-2]+1.0); for (k= n-2;k>= 0;k--) { y2[k] = y2[k]*y2[k+1]+u[k]; } // splint (initialization) ends, Begin *spline* fit for ( i = 1; i<= Nfit; i++ ) { // loop over xout values xout = x[0] + (x[n-1]-x[0])*(i-1)/(Nfit); klo = 0; // Bisection algor to find place in table khi = n-1; // klo, khi bracket xout value while (khi-klo > 1) { k = (khi+klo) >> 1; if (x[k] > xout) khi = k; else klo= k; } h = x[khi]-x[klo]; if (x[k] > xout) khi= k; else klo= k; h = x[khi]-x[klo]; a = (x[khi]-xout)/h; b = (xout-x[klo])/h; yout = (a*y[klo]+b*y[khi]+((a*a*a-a)*y2[klo] +(b*b*b-b)*y2[khi])*(h*h)/6.0); fprintf (output1,"%f\t%f\n",xout,yout); // gnuplot 3D format } fclose(output1); fclose(output2); printf("data stored in Spline.dat"); }