/* This file is part of Lemma, a geophysical modelling and inversion API. * More information is available at http://lemmasoftware.org */ /* This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ /** * @file * @date 02/07/2014 12:50:52 PM * @version $Id$ * @author Trevor Irons (ti) * @email Trevor.Irons@lemmasoftware.org * @copyright Copyright (c) 2014,2018 Trevor Irons */ #include "CubicSplineInterpolator.h" #include #include #include #include #include namespace Lemma { // ==================== FRIEND METHODS ===================== std::ostream &operator << (std::ostream &stream, const CubicSplineInterpolator &ob) { stream << ob.Serialize() << "\n---\n"; // End of doc --- return stream; } // ==================== LIFECYCLE ======================= //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: CubicSplineInterpolator // Description: constructor (locked with ctor_key) //-------------------------------------------------------------------------------------- CubicSplineInterpolator::CubicSplineInterpolator ( const ctor_key& key ) : LemmaObject( key ) { } // ----- end of method CubicSplineInterpolator::CubicSplineInterpolator (constructor) ----- //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: CubicSplineInterpolator // Description: DeSerializing constructor (locked with ctor_key) //-------------------------------------------------------------------------------------- CubicSplineInterpolator::CubicSplineInterpolator (const YAML::Node& node, const ctor_key& key ) : LemmaObject(node, key) { } // ----- end of method CubicSplineInterpolator::CubicSplineInterpolator (constructor) ----- //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: NewSP() // Description: public constructor //-------------------------------------------------------------------------------------- std::shared_ptr CubicSplineInterpolator::NewSP() { return std::make_shared( ctor_key() ); } //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: Serialize //-------------------------------------------------------------------------------------- YAML::Node CubicSplineInterpolator::Serialize ( ) const { YAML::Node node = LemmaObject::Serialize();; node.SetTag( GetName() ); // FILL IN CLASS SPECIFICS HERE return node; } // ----- end of method CubicSplineInterpolator::Serialize ----- //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: DeSerialize //-------------------------------------------------------------------------------------- std::shared_ptr CubicSplineInterpolator::DeSerialize ( const YAML::Node& node ) { if (node.Tag() != "CubicSplineInterpolator") { throw DeSerializeTypeMismatch( "CubicSplineInterpolator", node.Tag()); } return std::make_shared( node, ctor_key() ); } //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: ~CubicSplineInterpolator // Description: destructor (protected) //-------------------------------------------------------------------------------------- CubicSplineInterpolator::~CubicSplineInterpolator () { } // ----- end of method CubicSplineInterpolator::~CubicSplineInterpolator (destructor) ----- // ==================== OPERATIONS ======================= //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: SetKnots //-------------------------------------------------------------------------------------- void CubicSplineInterpolator::SetKnots ( const VectorXr& x, const VectorXr& y ) { //int n = x.size()-1; Index n = x.size()-1; Spline = SplineSet(n); Spline.a = y; Spline.x = x; VectorXr h = VectorXr::Zero(n); for(Index i=0; i= 0; --j) { Spline.c[j] = z[j] - mu[j] * Spline.c[j+1]; Spline.b[j] = (Spline.a[j+1]-Spline.a[j])/h[j]-h[j]*(Spline.c[j+1]+2*Spline.c[j])/3; Spline.d[j] = (Spline.c[j+1]-Spline.c[j])/3/h[j]; } // On OSX, this causes a strange bug 'sometimes', alignment? //Spline.c = Spline.c.head(n); return; } // ----- end of method CubicSplineInterpolator::SetKnots ----- //-------------------------------------------------------------------------------------- // Class: CubicSplineInterplator // Method: ResetKnotOrdinate //-------------------------------------------------------------------------------------- void CubicSplineInterpolator::ResetKnotOrdinate ( const VectorXr& y ) { VectorXr x = Spline.x; SetKnots(x, y); return ; } // ----- end of method CubicSplineInterplator::ResetKnotOrdinate ----- //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: InterpolateOrderedSet //-------------------------------------------------------------------------------------- VectorXr CubicSplineInterpolator::InterpolateOrderedSet ( const VectorXr& x ) { VectorXr y = VectorXr::Zero(x.size()); int ii = 0; for (int iy=0; iy Spline.x[i] ) { // std::cout << "DOOM in interplate\t x=" << x << "\ti=" << i << "\tSpline.x[i]=" << Spline.x[i] << std::endl; // std::cout <<"Spline.x.size()" << Spline.x.size() << std::endl; // std::cout << "Spline.x" << Spline.x.transpose() << std::endl; // //throw std::runtime_error("CubicSplineInterpolator::Interpolate ATTEMPT TO INTERPOLATE PAST LAST KNOT"); // } return Spline.a[i] + Spline.b[i]*(x-Spline.x[i]) + Spline.c[i]*((x-Spline.x[i])*(x-Spline.x[i])) + Spline.d[i]*((x-Spline.x[i])*(x-Spline.x[i])*(x-Spline.x[i]) ); } // ----- end of method CubicSplineInterpolator::Interpolate ----- //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: Interpolate //-------------------------------------------------------------------------------------- Real CubicSplineInterpolator::Interpolate ( const Real& x ) { int ii(0); return Interpolate(x, ii); } //-------------------------------------------------------------------------------------- // Class: CubicSplineInterpolator // Method: Integrate //-------------------------------------------------------------------------------------- Real CubicSplineInterpolator::Integrate ( const Real& x0, const Real& x1, const int& n ) { assert(n > 0); // force n to be even? //n += (n % 2); Real S = Interpolate(x0) + Interpolate(x1); Real h = (x1 - x0) / Real(n); int ik = 0; for (int i=1; i i0) { for (Index i=i0; i= Spline.x(nx)) { mflag = 1; return nx; } mflag = 0; if (ilo >= nx) ilo = nx-1; Index ihi = ilo+1; // if x is already in the interval if ( x= Spline.x(ilo) ) { //std::cout << "TRIVIAL INTERVAL " << Spline.x(ilo) << "\t" << x << "\t" << Spline.x(ihi) << std::endl; return ilo; } if (x <= Spline.x(ilo)) { // decrease ilo to capture Index istep = 1; for (Index ix=1; ix= Spline.x(ilo) || ilo == 1) break; istep *= 2; } } else if (x >= Spline.x(ihi)) { // increase ihi to capture Index istep = 1; for (Index ix=1; ix Narrow the interval. //std::cout << "WIDE INTERVAL " << Spline.x(ilo) << "\t" << x << "\t" << Spline.x(ihi) << std::endl; for (Index ix=1; ix