$search
00001 /* 00002 James R. Diebel 00003 Stanford University 00004 00005 Started: 22 November 2004 00006 Last revised: 2004 00007 00008 uspline.cc - implements class defined in uspline.hh 00009 00010 Depends on: 00011 - USpline Class (uspline.hh) 00012 - Matrix inversion routine (matrix.hh) 00013 */ 00014 00015 #include <string.h> 00016 #include <iostream> 00017 #include "bmtk/uspline.hh" 00018 00019 using namespace std; 00020 00021 namespace bmtk { 00022 00023 USpline::USpline(int n_) { 00024 n = n_; 00025 b0 = 0; bn = 0; 00026 xmin = 0; xmax = 1; span = xmax - xmin; 00027 interval = span/float(n-1); 00028 dpdx = float(n-1)/span; 00029 a = new float[4*n]; 00030 y = a; b = a+n; c = b+n; d = c+n; 00031 A = new float *[n]; 00032 for (int i=0;i<n;i++) A[i] = new float[n]; 00033 } 00034 00035 USpline::USpline(int n_,float xmin_, float xmax_, float b0_, float bn_) { 00036 n = n_; 00037 b0 = b0_; bn = bn_; 00038 xmin = xmin_; xmax = xmax_; span = xmax - xmin; 00039 interval = span/float(n-1); 00040 dpdx = float(n-1)/span; 00041 a = new float[4*n]; 00042 y = a; b = a+n; c = b+n; d = c+n; 00043 A = new float *[n]; 00044 for (int i=0;i<n;i++) A[i] = new float[n]; 00045 } 00046 00047 USpline::USpline(float* y_, int n_) { 00048 n = n_; 00049 b0 = 0; bn = 0; 00050 xmin = 0; xmax = 1; span = xmax - xmin; 00051 interval = span/float(n-1); 00052 dpdx = float(n-1)/span; 00053 a = new float[n]; 00054 y = a; b = a+n; c = b+n; d = c+n; 00055 A = new float *[n]; 00056 for (int i=0;i<n;i++) A[i] = new float[n]; 00057 00058 for (int i=0;i<n;i++) { 00059 y[i] = y_[i]; 00060 } 00061 } 00062 00063 USpline::~USpline() { 00064 delete [] a; 00065 for (int i=0;i<n;i++) delete [] A[i]; 00066 delete [] A; 00067 } 00068 00069 00070 void USpline::update() { 00071 for (int i=0;i<n;i++) { 00072 if (i==0) c[i] = b0/dpdx; 00073 else if (i==(n-1)) c[i] = bn/dpdx; 00074 else c[i] = 3*(y[i+1] - y[i-1]); 00075 memset(A[i],0,n*sizeof(float)); 00076 for (int j=i-1;j<=i+1;j++) if (j>=0 && j<n) { 00077 if (i==j) if (i==0 || i==(n-1)) A[i][j] = 1; else A[i][j] = 4; 00078 else if (i!=0 && i!=(n-1)) A[i][j] = 1; 00079 } 00080 } 00081 gelimd2(A,c,b,n); 00082 for (int i=0;i<n;i++) { 00083 if (i<(n-1)) { 00084 c[i] = 3*(a[i+1] - a[i]) - 2*b[i] - b[i+1]; 00085 d[i] = 2*(a[i] - a[i+1]) + b[i] + b[i+1]; 00086 } else { 00087 c[i] = 3*(-a[i]) - 2*b[i]; 00088 d[i] = 2*(a[i]) + b[i]; 00089 } 00090 } 00091 } 00092 00093 float USpline::evalf(float x) { 00094 float p = (x-xmin)/span; 00095 if (p<0) p = 0; 00096 if (p>1) p = 1; 00097 p *= (n-1); 00098 int i = int(p); 00099 p -= float(i); 00100 float pp = p*p; 00101 return a[i] + b[i]*p + c[i]*pp + d[i]*pp*p; 00102 } 00103 00104 float USpline::evaldf(float x) { 00105 float p = (x-xmin)/span; 00106 if (p<0) p = 0; 00107 if (p>1) p = 1; 00108 p *= (n-1); 00109 int i = int(p); 00110 p -= float(i); 00111 return dpdx*(b[i] + 2*c[i]*p + 3*d[i]*p*p); 00112 } 00113 00114 void USpline::print() { 00115 cout << n << " " << xmin << " " << xmax << " " << span << " " << interval 00116 << endl << endl; 00117 for (int i=0;i<n;i++) { 00118 for (int j=0;j<n;j++) { 00119 cout << A[i][j] << " "; 00120 } 00121 cout << " " << a[i] << " " << b[i] << " " << c[i] << " " << d[i] << endl; 00122 } 00123 } 00124 00125 } // namespace bmtk