/* Copyright (C) 1998 Jürgen Hochwald Copyright (C) 2003 Charles Samuels This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Library General Public License for more details. You should have received a copy of the GNU General Public License along with this library; see the file COPYING. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include "spline.h" const bool Spline::natural=false; Spline::Spline() { yp1=0.0; ypn=0.0; mRecalc = true; } Spline::Spline(const Spline ©) { operator=(copy); } Spline &Spline::operator =(const Spline ©) { mPoints = copy.mPoints; mRecalc = copy.mRecalc; yp1 = copy.yp1; ypn = copy.ypn; return *this; } Spline::~Spline() { } void Spline::add(double x, double y) { Group g = { x, y, 0.0 }; mPoints.push_back(g); mRecalc=true; } std::vector Spline::points(int count) const { std::vector points; if (count == numPoints()) { for (int i=0; i < count; ++i) { points.push_back(mPoints[i].y); } } else { double min = mPoints[0].x; double max = mPoints[numPoints()-1].x; double dcount = double(count); for (int i=0; i=0; i--) { mPoints[i].y2 = mPoints[i].y2 * mPoints[i+1].y2+u[i]; } mRecalc = false; delete [] u; } double Spline::spline(double xarg) const { if (numPoints()==0) return 0.0; if (numPoints()==1) return mPoints[0].y; if (mRecalc) calcSpline(); int klo=0; int khi=numPoints()-1; int k; while (khi-klo > 1) { k = khi+klo; if (k % 2) k = (k+1) / 2; else k = k/2; if (mPoints[k].x > xarg) khi=k; else klo=k; } double h = mPoints[khi].x - mPoints[klo].x; if (h==0) { // failed return 0.0; } double a = (mPoints[khi].x - xarg) / h; double b = (xarg - mPoints[klo].x) / h; return a * mPoints[klo].y + b*mPoints[khi].y + ((a*a*a-a) * mPoints[klo].y2 + (b*b*b-b) * mPoints[khi].y2) * (h*h) / 6.0; } double Spline::x(int num) const { if (numPoints()