00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 2008, Andrew W. Steiner 00005 00006 This file is part of O2scl. 00007 00008 O2scl is free software; you can redistribute it and/or modify 00009 it under the terms of the GNU General Public License as published by 00010 the Free Software Foundation; either version 3 of the License, or 00011 (at your option) any later version. 00012 00013 O2scl is distributed in the hope that it will be useful, 00014 but WITHOUT ANY WARRANTY; without even the implied warranty of 00015 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00016 GNU General Public License for more details. 00017 00018 You should have received a copy of the GNU General Public License 00019 along with O2scl. If not, see <http://www.gnu.org/licenses/>. 00020 00021 ------------------------------------------------------------------- 00022 */ 00023 #ifndef O2SCL_TWOD_INTP_H 00024 #define O2SCL_TWOD_INTP_H 00025 00026 #include <iostream> 00027 #include <string> 00028 #include <o2scl/smart_interp.h> 00029 #include <o2scl/omatrix_tlate.h> 00030 00031 #ifndef DOXYGENP 00032 namespace o2scl { 00033 #endif 00034 00035 /** 00036 \brief Two-dimensional interpolation class 00037 00038 This class implements two-dimensional interpolation. Derivatives 00039 and integrals along both x- and y-directions can be computed. 00040 The function set_data(), does not copy the data but rather 00041 stores pointers to the data. If the data is modified, then the 00042 function reset_interp() can be called to reset the interpolation 00043 information with the original pointer information. 00044 00045 The storage for the data, including the arrays \c x_fun 00046 and \c y_fun are all managed by the user. If the data is 00047 changed without calling reset_interp(), then interp() will 00048 return incorrect results. 00049 00050 By default, cubic spline interpolation with natural boundary 00051 conditions is used. This can be changed with the set_interp() 00052 function. 00053 00054 \warning This class assumes that the data specified through 00055 set_data() is not deallocated or modified by the user until 00056 unset_data() has been called. 00057 00058 There is an example for the usage of this class given 00059 in <tt>examples/ex_twod_intp.cpp</tt>. 00060 00061 \future Could also include mixed second/first derivatives: 00062 deriv_xxy and deriv_xyy. 00063 \future Implement an improved caching system in case, for example 00064 \c xfirst is true and the last interpolation used the same 00065 value of \c x. 00066 00067 */ 00068 class twod_intp { 00069 public: 00070 00071 twod_intp(); 00072 00073 virtual ~twod_intp(); 00074 00075 /** \brief Initialize the data for the 2-dimensional interpolation 00076 00077 The interpolation type (passed directly to int_type) is 00078 specified in \c int_type and the data is specified in 00079 \c data. The data should be arranged so that the first 00080 array index is the y-value (the "row") and the second array 00081 index is the x-value (the "column"). The arrays \c xfun 00082 and \c yfun specify the two independent 00083 variables. \c xfun should be an array of length 00084 \c nx , and should be an array of length \c ny. The 00085 array \c data should be a two-dimensional array of size 00086 [ny][nx]. 00087 00088 If \c x_first is true, then set_data() creates interpolation 00089 objects for each of the rows. Calls to interp() then uses 00090 these to create a column at the specified value of \c x. An 00091 interpolation object is created at this column to find the 00092 value of the function at the specified value \c y. If \c 00093 x_first is false, the opposite strategy is employed. These two 00094 options may give slightly different results. In general, if 00095 the data is "more accurate" in the x direction than in the y 00096 direction, it is probably better to choose \c x_first=true. 00097 00098 */ 00099 int set_data(int n_x, int n_y, ovector &x_fun, 00100 ovector &y_fun, omatrix &u_data, 00101 bool x_first=true); 00102 00103 /** 00104 \brief Reset the stored interpolation since the data has changed 00105 00106 This will return an error if the set_data() has not been called 00107 */ 00108 int reset_interp(); 00109 00110 /** \brief Perform the 2-d interpolation 00111 */ 00112 double interp(double x, double y); 00113 00114 /** \brief Compute the partial derivative in the x-direction 00115 */ 00116 double deriv_x(double x, double y); 00117 00118 /** \brief Compute the partial second derivative in the x-direction 00119 */ 00120 double deriv2_x(double x, double y); 00121 00122 /** \brief Compute the integral in the x-direction between x=x0 00123 and x=x1 00124 */ 00125 double integ_x(double x0, double x1, double y); 00126 00127 /** \brief Compute the partial derivative in the y-direction 00128 */ 00129 double deriv_y(double x, double y); 00130 00131 /** \brief Compute the partial second derivative in the y-direction 00132 */ 00133 double deriv2_y(double x, double y); 00134 00135 /** \brief Compute the integral in the y-direction between y=y0 00136 and y=y1 00137 */ 00138 double integ_y(double x, double y0, double y1); 00139 00140 /** \brief Compute the mixed partial derivative 00141 \f$ \frac{\partial^2 f}{\partial x \partial y} \f$ 00142 */ 00143 double deriv_xy(double x, double y); 00144 00145 /** 00146 \brief Specify the base interpolation objects to use 00147 00148 This allows the user to provide new interpolation objects for 00149 use in the two-dimensional interpolation. This class requires 00150 an array of interpolation objects for the first two arguments 00151 because one interpolation object is required for each row (or 00152 each column). The argument \c ni specifies the size of these 00153 arrays. In the case where the user intends the x interpolation 00154 first (i.e. \c x_first \c = \c true in set_data() ), the 00155 parameter \c ni should be equal to \c ny. For 00156 <tt>x_first=false</tt>, \c ni should be equal to \c nx. If the 00157 class does not find enough interpolation objects, i.e. if \c 00158 ni is smaller than the values suggested above, the class will 00159 switch back to the default internal interpolation objects when 00160 it runs out of user-specified interpolation objects. For 00161 example, 00162 00163 \code 00164 twod_intp ti; 00165 ovector x(20), y(40); 00166 omatrix d(40,20); 00167 00168 // Fill x, y, and d with the data, choose linear interpolation 00169 // instead of the default cubic spline 00170 linear_interp<ovector_view> li[41]; 00171 linear_interp<ovector_const_subvector> li2[41]; 00172 00173 ti.set_interp(40,li,li2,li[40],li2[40]); 00174 ti.set_data(20,40,x,y,d,true); 00175 \endcode 00176 00177 This function automatically calls reset_interp() if the 00178 data has already been set to reset the internal interpolation 00179 objects. 00180 00181 \future Use std::vector for the first two base_interp arguments? 00182 */ 00183 int set_interp(size_t ni, base_interp<ovector_view> *it, 00184 base_interp<ovector_const_subvector> *it_sub, 00185 base_interp<ovector_view> &it2, 00186 base_interp<ovector_const_subvector> &it2_sub) { 00187 nuit=ni; 00188 uit1=it; 00189 uit2=it_sub; 00190 uit3=&it2; 00191 uit4=&it2_sub; 00192 it_set=true; 00193 if (data_set) reset_interp(); 00194 return 0; 00195 } 00196 00197 /** 00198 \brief Inform the class the data has been modified or 00199 changed in a way that set_data() will need to be called 00200 again. 00201 */ 00202 int unset_data() { 00203 data_set=false; 00204 return 0; 00205 } 00206 00207 #ifndef DOXYGENP 00208 00209 protected: 00210 00211 /// The array of sm_interp pointers 00212 sm_interp_vec **si; 00213 /// An array of omatrix_rows 00214 omatrix_row **ari; 00215 /// An array of omatrix_cols 00216 omatrix_col **aci; 00217 00218 /// The number of x grid points 00219 int nx; 00220 00221 /// The number of y grid points 00222 int ny; 00223 00224 /// If true, the user has specified the base interpolation objects 00225 bool it_set; 00226 00227 /// Number of user-specified interpolation objects 00228 int nuit; 00229 00230 /// \name User-specified interpolation objects 00231 //@{ 00232 base_interp<ovector_view> *uit1; 00233 base_interp<ovector_const_subvector> *uit2; 00234 base_interp<ovector_view> *uit3; 00235 base_interp<ovector_const_subvector> *uit4; 00236 //@} 00237 00238 /// True if the x interpolation should be done first 00239 bool xfirst; 00240 00241 /// True if the data has been specified by the user 00242 bool data_set; 00243 00244 /// The x grid 00245 ovector *xfun; 00246 00247 /// The y grid 00248 ovector *yfun; 00249 00250 /// The data 00251 omatrix *data; 00252 00253 #endif 00254 00255 }; 00256 00257 #ifndef DOXYGENP 00258 } 00259 #endif 00260 00261 #endif 00262 00263 00264
Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.
Project hosting provided by
,
O2scl Sourceforge Project Page