00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include <cassert>
00014 #include "spline.h"
00015
00016 namespace NR {
00017
00018 using namespace std;
00019
00020 void spline(const vector<double>& x,
00021 const vector<double>& y,
00022 const double yp1,
00023 const double ypn,
00024 vector<double>& y2)
00025 {
00026 const double y_thresh = 0.99e30;
00027
00028 unsigned int n = x.size();
00029 assert(y.size() == n);
00030 y2.resize(n);
00031
00032 double p, qn, sig, un;
00033 vector<double> u(n-1);
00034 if (yp1 > y_thresh)
00035 y2[0] = u[0] = 0.0;
00036 else {
00037 y2[0] = -0.5;
00038 u[0] = (3.0/(x[1]-x[0]))*((y[1]-y[0])/(x[1]-x[0])-yp1);
00039 }
00040 for (unsigned int i = 1; i < n-1; ++ i) {
00041 sig = (x[i]-x[i-1])/(x[i+1]-x[i-1]);
00042 p = sig*y2[i-1] + 2.0;
00043 y2[i] = (sig - 1.0)/p;
00044 u[i] = (y[i+1]-y[i])/(x[i+1]-x[i]) - (y[i]-y[i-1])/(x[i]-x[i-1]);
00045 u[i] = (6.0*u[i]/(x[i+1]-x[i-1]) - sig*u[i-1])/p;
00046 }
00047 if (ypn > y_thresh)
00048 qn = un = 0.0;
00049 else {
00050 qn = -0.5;
00051 un = (3.0/(x[n-1]-x[n-2]))*(ypn-(y[n-1]-y[n-2])/(x[n-1]-x[n-2]));
00052 }
00053 y2[n-1] = (un-qn*u[n-2])/(qn*y2[n-2]+1.0);
00054 for (int k = n-2; k >= 0; -- k)
00055 y2[k] = y2[k]*y2[k+1] + u[k];
00056 }
00057
00058 void splint(const vector<double>& xa,
00059 const vector<double>& ya,
00060 const vector<double>& y2a,
00061 const double x,
00062 double& y)
00063 {
00064 int k;
00065 double h, b, a;
00066
00067 unsigned int n = xa.size();
00068 assert(ya.size() == n);
00069 assert(y2a.size() == n);
00070
00071
00072 int klo = 0;
00073 int khi = n-1;
00074 while (khi - klo > 1) {
00075 k = (khi + klo) >> 1;
00076 if (xa[k] > x)
00077 khi = k;
00078 else
00079 klo = k;
00080 }
00081
00082 h = xa[khi]-xa[klo];
00083 assert(h > 0.0);
00084 a = (xa[khi] - x)/h;
00085 b = (x - xa[klo])/h;
00086 y = a*ya[klo] + b*ya[khi] + ((a*a*a - a)*y2a[klo] + (b*b*b - b)*y2a[khi])*(h*h)/6.0;
00087 }
00088
00089 }