Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

interpolate.h

Go to the documentation of this file.
00001 // SuperMix version 1.0  C++ source file
00002 //
00003 // Copyright (c) 1999 California Institute of Technology.
00004 // All rights reserved.
00005 //
00006 // Redistribution and use in source and binary forms for noncommercial
00007 // purposes are permitted provided that the above copyright notice and
00008 // this paragraph are duplicated in all such forms and that any
00009 // documentation and other materials related to such distribution and
00010 // use acknowledge that the software was developed by California
00011 // Institute of Technology. Redistribution and/or use in source or
00012 // binary forms is not permitted for any commercial purpose. Use of
00013 // this software does not include a permitted use of the Institute's
00014 // name or trademark for any purpose.
00015 //
00016 // DISCLAIMER:
00017 // THIS SOFTWARE AND/OR RELATED MATERIALS ARE PROVIDED "AS-IS" WITHOUT
00018 // WARRANTY OF ANY KIND INCLUDING ANY WARRANTIES OF PERFORMANCE OR
00019 // MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE OR PURPOSE (AS SET
00020 // FORTH IN UCC 23212-2313) OR FOR ANY PURPOSE WHATSOEVER, FOR THE
00021 // LICENSED PRODUCT, HOWEVER USED.  IN NO EVENT SHALL CALTECH/JPL BE
00022 // LIABLE FOR ANY DAMAGES AND/OR COSTS, INCLUDING BUT NOT LIMITED TO
00023 // INCIDENTAL OR CONSEQUENTIAL DAMAGES OF ANY KIND, INCLUDING ECONOMIC
00024 // DAMAGE OR INJURY TO PROPERTY AND LOST PROFITS, REGARDLESS OF
00025 // WHETHER CALTECH/JPL SHALL BE ADVISED, HAVE REASON TO KNOW, OR IN
00026 // FACT SHALL KNOW OF THE POSSIBILITY.  THE USER BEARS ALL RISK
00027 // RELATING TO QUALITY AND PERFORMANCE OF THE SOFTWARE AND/OR RELATED
00028 // MATERIALS.
00029 //
00030 // ********************************************************************
00031 // interpolate.h
00032 //
00033 // defines generalized 1-parameter "interpolator" template class
00034 // defines typedef "interpolation" as interpolator<double>
00035 // 
00036 // class interpolator<>:
00037 //
00038 // Template class for performing interpolation into a single-indexed
00039 // set of numerical values. Both linear and cubic spline interpolations
00040 // are provided. Extrapolations are performed as well; extrapolations 
00041 // are always linear. The index must be a single double (real scalar).
00042 // The indexed objects must be members of a "vector space" with the
00043 // following operations defined on them (Y_type is the type of the objects,
00044 // double is the type of the index):
00045 //
00046 // double x;
00047 // Y_type A;    // construct an instance of Y_type, no particular value.
00048 // Y_type B(A); // construct an independent copy of Y_type A;
00049 // A = B;       // make A an independent copy of B
00050 // A *= x;      // modify A by scaling by x.
00051 // A += B;      // modify A by adding B to it
00052 // A -= B;      // modify A by subtracting B from it
00053 //
00054 // Y_type objects must be a vector space, in that (A *= 2.0) is equivalent
00055 // to (A += A), and (A *= 0.0) is equivalent to (A -= A) and gives the
00056 // additive identity of Y_type, etc. 
00057 //
00058 // General scheme to use the interpolator:
00059 //
00060 // interpolator<Y_type> Y;         // an empty interpolator
00061 // double x; Y_type y;             // independent and dependent variables
00062 //
00063 // (Also: interpolation Y;         // same as: interpolator<double> Y)
00064 //
00065 // provide tabulated data points:
00066 //   Y.add(x1,y1).add(x2,y2)....add(xN,yN);
00067 //   Y.add(xM,yM);         // etc.
00068 // prepare for use (cubic spline in this case, which is the default):
00069 //   Y.spline().build();   // or just: Y.build();
00070 //
00071 // y = Y(x);               // interpolate data to determine y(x)
00072 // y = Y.prime(x);         // interpolate data to determine (d/dx)y(x)
00073 //
00074 // Also the following function is provided for certain special applications.
00075 // Note that the return values are written into the variables provided. Function
00076 // return value is a flag which tells if an extrapolation was performed.
00077 //
00078 // Y.val_prime(x, y1, y2); // write y(x) into y1, y'(x) into y2
00079 // 
00080 // Cubic spline interpolation is very loosely based on the algorithm in 
00081 // Numerical Recipes in C, 2nd Edition (Cambridge).
00082 //
00083 // F. Rice 3/26/99
00084 //
00085 // Change History:
00086 // 11/15/99: Added more_data(), add(interpolator<>)
00087 // 10/8/99:  Made some functions virtual; added virtual destructor.
00088 // 9/27/99:  Changed default warning behavior; added verbose() and quiet()
00089 // 7/6/99:   Changed private members to protected.
00090 // 6/30/99:  Changed default interpolation to SPLINE. Added linear(), spline(),
00091 //           class interpolation.
00092 //
00093 // ********************************************************************
00094 
00095 #ifndef INTERPOLATE_H
00096 #define INTERPOLATE_H
00097 
00098 #include <list>
00099 #include <vector>
00100 
00101 template < class Y_type >  // Y_type is the type of object we're interpolating
00102 class interpolator
00103 {
00104 public:
00105 
00106   // ----------------------------------------------
00107   // Constructing or clearing the interpolator; operator =:
00108 
00109   interpolator();                      // an empty, default interpolator.
00110   interpolator(const interpolator<Y_type> &);  // copy constructor; may trigger build()
00111   virtual interpolator<Y_type> & clear();      // erase all data; return to default behavior.
00112   interpolator<Y_type> & operator=(const interpolator<Y_type> &);  // may trigger build
00113 
00114   // ----------------------------------------------
00115   // Supplying data and describing the desired interpolation:
00116 
00117   // Add data points. Data points may be added in any order, but the x values 
00118   // (of type double) must all be unique. Sorted points get added faster.
00119  
00120   virtual interpolator<Y_type> & add(const double, const Y_type &);  // a new data entry
00121 
00122   // Add all the data points of the supplied interpolator. All points previously
00123   // add()'ed to the supplied interpolator will be included. Any points of the
00124   // supplied interpolator with X values duplicating those already included will
00125   // be ignored.
00126 
00127   virtual interpolator<Y_type> & add(const interpolator<Y_type> &);
00128 
00129   // Type of interpolation (the default is cubic spline). Calling this function will
00130   // reset ready() until build() is called (see below). The enumeration gives mnemonics
00131   // for the interpolation types. Extrapolation is always linear. 
00132 
00133   interpolator<Y_type> & type(int);
00134   enum { LINEAR = 0, SPLINE = 1 };  // SPLINE is a cubic spline
00135 
00136   interpolator<Y_type> & linear() { return type(LINEAR); }
00137   interpolator<Y_type> & spline() { return type(SPLINE); }
00138 
00139   // Optionally specify slopes at the endpoints of the data set. These slopes are used for
00140   // any extrapolations, which are always linear. They also affect spline interpolation.
00141   // If either is called, then ready() is reset until build() is called (see below).
00142   // The default slope for an endpoint is calculated by the interpolator from the data
00143   // points using the  so-called "natural" boundary condition of vanishing curvature at
00144   // that endpoint.
00145 
00146   interpolator<Y_type> & left_slope(const Y_type &);  // set slope at left (smallest x) end
00147   interpolator<Y_type> & right_slope(const Y_type &); // set slope at right (largest x) end
00148 
00149   // ----------------------------------------------
00150   // Building internal data structures so that the interpolator may be used
00151 
00152   // Status. If this function returns 0, an attempt to use the interpolator will result
00153   // in a fatal error.
00154 
00155   virtual int ready() const {return ready_;}  // == 1 if ready to interpolate, == 0 otherwise.
00156 
00157   // Build tables and prepare for interpolation. If successful, sets ready().
00158   // Any points added following a call to build() will not be used by the
00159   // interpolator until build() is called again.
00160  
00161   interpolator<Y_type> & build();  // set up interpolator for points added so far
00162 
00163   // The following function returns 1 if there is more data available that is not being
00164   // used in the interpolation (that is, add() has been called since the latest call to
00165   // build()).
00166 
00167   int more_data() const {return (data.size() > table.size()); }
00168 
00169   // ----------------------------------------------
00170   // Performing an interpolation
00171 
00172   // Use: interpolator A; double x; Y_type y;  ... (build A) ...; y = A(x); 
00173   // This is the operator to perform an interpolation. It will generate a fatal error
00174   // if called while ready() == 0 (not set). 
00175 
00176   // return an interpolated/extrapolated Y_type estimate of Y(x):
00177 
00178   Y_type operator()(double x) const;
00179 
00180   // return an interpolated/extrapolated Y_type estimate of Y'(x):
00181 
00182   Y_type prime(double x) const;
00183 
00184   // Note that prime(x) will be continuous even for linear interpolations. Consequently,
00185   // integrating these estimated Y'(x) will not reproduce the estimates to Y(x). If
00186   // this property is required, use a spline interpolation.
00187 
00188   // Write operator()(x) into y, prime(x) into y_prime. Executes faster than the two
00189   // independent function calls. Returns: (-1) if extrapolating below minimum x; (0) if
00190   // interpolating; (1) if extrapolating above the maximum x in the internal table.
00191 
00192   int val_prime(double x, Y_type & y, Y_type & y_prime) const;
00193 
00194   // ----------------------------------------------
00195   // Other miscellaneous functions
00196 
00197   // The following functions turn on or off warnings regarding extrapolation. The default
00198   // behavior is to warn whenever an extrapolation is performed. Does not affect
00199   // ready() status.
00200 
00201   interpolator<Y_type> & verbose() { no_warn_ = false; return *this; }
00202   interpolator<Y_type> & quiet() { no_warn_ = true; return *this; }
00203 
00204   // the following function is retained for backward compatibilty.  An argument != 0
00205   // will turn off the extrapolation warning:
00206 
00207   interpolator<Y_type> & no_extrapolation_warning(int f)  // f == 1: no warnings
00208     { no_warn_ = (f != 0); return *this; }
00209 
00210   // The following functions provide direct read access to the sorted data used for
00211   // actual interpolations (they do not include data add()ed following build()):
00212   // x(0) returns the smallest x value; x(size()-1) returns the largest x value
00213 
00214   unsigned size() const                 // the number of points used in the interpolation
00215     { return unsigned(table.size()); }
00216 
00217   double x(unsigned i) const                          // returns x[i] ( 0 <= i < size() )
00218     { return table[index(i)].first; }                 // NO BOUNDS CHECKING ON i
00219 
00220   const Y_type & operator[](unsigned i) const         // returns y[i] ( 0 <= i < size() )
00221     { return table[index(i)].second.first->second; }  // NO BOUNDS CHECKING ON i
00222 
00223 
00224   // virtual destructor for proper subclass destruction
00225   virtual ~interpolator() { }
00226 
00227   // debugging functions; may be removed in a later release
00228   void list_data_list() const;   // send entries to cout
00229   void list_lists() const;       // send entries to cout, use table as reference
00230 
00231 
00232 protected:
00233 
00234   typedef pair< double, Y_type >        data_type;
00235   typedef list< data_type >             data_list;
00236   typedef data_list::iterator           data_iter;
00237   typedef data_list::const_iterator     const_data_iter;
00238   typedef pair< double, pair< data_iter, data_iter > >  entry;
00239   typedef vector<entry>                 interp_table;
00240   typedef interp_table::iterator        table_iter;
00241   typedef interp_table::const_iterator  const_table_iter;
00242   typedef interp_table::size_type       index;
00243 
00244   data_list       data, aux;     // hold sorted data and auxilliary info
00245   interp_table    table;         // provides random access to data and aux
00246   mutable Y_type  result;        // holds the interpolation result
00247   bool            ready_;        // internal ready flag
00248   bool            no_warn_;      // don't warn if extrapolating
00249   int type_;                     // type of interpolation (0 => linear)
00250   Y_type lslope, rslope;         // slopes for extrapolations and boundary conditions
00251   bool user_ls, user_rs;         // were endpoint slopes supplied by user?
00252   void build_linear();           // called by build for linear interpolation
00253   void build_spline();           // called by build for spline interpolation
00254 
00255   // the following functions write into the Y_type argument:
00256   void linear(index,double,Y_type &) const;       // linear interpolator
00257   void spline(index,double,Y_type &) const;       // spline interpolator
00258   void lextrapolate(double,Y_type &) const;       // linear extrapolator to left
00259   void rextrapolate(double,Y_type &) const;       // linear extrapolator to right
00260   void prime_linear(index,double,Y_type &) const; // dy/dx using linear interpolator
00261   void prime_spline(index,double,Y_type &) const; // dy/dx using spline interpolator
00262 
00263   // the following functions write into result:
00264   void linear(index i,double x) const
00265     { linear(i,x,result); }
00266   void spline(index i,double x) const
00267     { spline(i,x,result); }
00268   void lextrapolate(double x) const
00269     { lextrapolate(x,result); }
00270   void rextrapolate(double x) const
00271     { rextrapolate(x,result); }
00272   void prime_linear(index i,double x) const
00273     { prime_linear(i,x,result); }
00274   void prime_spline(index i,double x) const
00275     { prime_spline(i,x,result); }
00276 
00277 };
00278 
00279 typedef interpolator<double> interpolation;
00280 
00281 #include "numerical/num_interpolate.h"
00282 
00283 #endif /* INTERPOLATE_H */

Please direct comments and corrections to supermix@submm.caltech.edu
Go to the supermix home page
Generated by doxygen1.2.7