00001 // QMcBeaver 00002 // 00003 // Constructed by 00004 // 00005 // Michael Todd Feldmann 00006 // and 00007 // David Randall "Chip" Kent IV 00008 // 00009 // Copyright 2000. All rights reserved. 00010 // 00011 // drkent@users.sourceforge.net mtfeldmann@users.sourceforge.net 00012 00013 #include "LinearSpline.h" 00014 00015 void LinearSpline::operator=( const LinearSpline & rhs ) 00016 { 00017 n=rhs.n; 00018 f=rhs.f; 00019 00020 x_list=rhs.x_list; 00021 y_list=rhs.y_list; 00022 a0_list=rhs.a0_list; 00023 a1_list=rhs.a1_list; 00024 } 00025 00026 00027 void LinearSpline::initializeWithFunctionValues(Array1D<double> &x_input, 00028 Array1D<double> &y_input) 00029 { 00030 //initialize the spline tables of values 00031 00032 n=x_input.dim1(); 00033 00034 x_list.allocate(n); 00035 y_list.allocate(n); 00036 a0_list.allocate(n-1); 00037 a1_list.allocate(n-1); 00038 00039 for(int i=0;i<n;i++) 00040 { 00041 x_list(i)=x_input(i); 00042 y_list(i)=y_input(i); 00043 } 00044 00045 for(int i=0;i<n-1;i++) 00046 { 00047 a0_list(i)=0.0; 00048 a1_list(i)=0.0; 00049 } 00050 00051 //if we look at the intervals xj-1,xj,xj+1 00052 //xj-1 <---h---> xj <---d---> xj+1 are the spacings 00053 00054 //The spline function, s(x) has this form in each interval: 00055 //sj(x)=a0+a1(x-xj) 00056 //with a different set of a0 and a1 coeff for each interval 00057 00058 //To get the coeff lists values we need to evaluate the following 00059 //a0=fj 00060 //a1=f'j 00061 00062 double d,fj,fj1; 00063 00064 //coeff(i) is good for the interval i to i+1 00065 for(int i=0;i<n-1;i++) 00066 { 00067 d = x_list(i+1)-x_list(i); 00068 fj = y_list(i); 00069 fj1 = y_list(i+1); 00070 a0_list(i)=fj; 00071 a1_list(i)=(fj1-fj)/d; 00072 } 00073 } 00074 00075 00076 void LinearSpline::evaluate(double x) 00077 { 00078 //find which index in the table by means of bisection 00079 int klo,khi,k; 00080 00081 //push any value outside the spline range into the last value of the spline 00082 00083 if(x>=x_list(n-1)) 00084 { 00085 x=x_list(n-1); 00086 } 00087 else if(x<=x_list(0)) 00088 { 00089 x=x_list(0); 00090 } 00091 00092 klo=0; 00093 khi=n-1; 00094 00095 while (khi-klo > 1) 00096 { 00097 k=(khi+klo) >> 1; 00098 if (x_list(k) > x) khi=k; 00099 else klo=k; 00100 } 00101 00102 if(khi>n || khi<1 || klo>(n-1) || klo<0) 00103 { 00104 cerr<<"bad values for klo and khi"<<endl; 00105 cerr<<"klo= "<<klo<<"\tkhi= "<<khi<<endl; 00106 cerr<<"x= "<<x<<endl; 00107 exit(1); 00108 } 00109 00110 double r,a0,a1; 00111 00112 r=x-x_list(klo); 00113 a0=a0_list(klo); 00114 a1=a1_list(klo); 00115 00116 f = a0+a1*r; 00117 df = a1; 00118 } 00119 00120 double LinearSpline::getFunctionValue() 00121 { 00122 return f; 00123 } 00124 00125 double LinearSpline::getFirstDerivativeValue() 00126 { 00127 return df; 00128 } 00129 00130 double LinearSpline::getSecondDerivativeValue() 00131 { 00132 return 0.0; 00133 } 00134 00135