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
1.2.7