![]() |
Object-oriented Scientific Computing Library: Version 0.910
|
00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006-2012, 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 <vector> 00029 #include <o2scl/smart_interp.h> 00030 #include <o2scl/omatrix_tlate.h> 00031 00032 #ifndef DOXYGENP 00033 namespace o2scl { 00034 #endif 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 00041 The storage of the matrix to be specified in the function 00042 set_data() and this function is designed to follow the format: 00043 \f[ 00044 \begin{array}{cccc} 00045 & x_0 & x_1 & x_2 \\ 00046 y_0 & M_{00} & M_{01} & M_{02} \\ 00047 y_1 & M_{10} & M_{11} & M_{12} \\ 00048 y_2 & M_{20} & M_{21} & M_{22} 00049 \end{array} 00050 \f] 00051 thus the matrix should be \c M[i][j] where \c i is the y index 00052 and \c j is the x index. (See also the discussion in the 00053 User's guide in the section called \ref rowcol_subsect.) 00054 00055 The function set_data(), does not copy the data, it 00056 stores pointers to the data. If the data is modified, then the 00057 function reset_interp() must be called to reset the 00058 interpolation information with the original pointer information. 00059 The storage for the data, including the arrays \c x_grid and \c 00060 y_grid are all managed by the user. 00061 00062 By default, cubic spline interpolation with natural boundary 00063 conditions is used. This can be changed with the set_interp() 00064 function. 00065 00066 There is an example for the usage of this class given 00067 in <tt>examples/ex_twod_intp.cpp</tt>. 00068 00069 \future Could also include mixed second/first derivatives: 00070 deriv_xxy and deriv_xyy. 00071 \future Implement an improved caching system in case, for example 00072 \c xfirst is true and the last interpolation used the same 00073 value of \c x. 00074 00075 \comment 00076 00077 There's a whole list of things to think about here: 00078 00079 1. One could 00080 generalize the matrix and vector types. This would demand 00081 adding subvector types for the interpolation, etc. 00082 00083 2. One could copy the user data instead of storing pointers to it. 00084 00085 3. One could include get() and set() methods, but one would 00086 have to be careful about when to reset the interpolation. 00087 00088 4. xy order vs. yx order for the matrix 00089 00090 5/16/08 - There has been some talk about GSL implementing 2d 00091 interpolation, and I think the table3d class will be much more 00092 useful in the end. Thus, I think it's probably best to delay 00093 working on this for awhile until GSL 2d interpolation or table3d 00094 are more settled. 00095 00096 \endcomment 00097 00098 */ 00099 class twod_intp { 00100 public: 00101 00102 twod_intp(); 00103 00104 virtual ~twod_intp(); 00105 00106 /** \brief Initialize the data for the 2-dimensional interpolation 00107 00108 The interpolation type (passed directly to int_type) is 00109 specified in \c int_type and the data is specified in 00110 \c data. The data should be arranged so that the first 00111 array index is the y-value (the "row") and the second array 00112 index is the x-value (the "column"). The arrays \c xfun 00113 and \c yfun specify the two independent 00114 variables. \c xfun should be an array of length 00115 \c nx , and should be an array of length \c ny. The 00116 array \c data should be a two-dimensional array of size 00117 [ny][nx]. 00118 00119 If \c x_first is true, then set_data() creates interpolation 00120 objects for each of the rows. Calls to interp() then uses 00121 these to create a column at the specified value of \c x. An 00122 interpolation object is created at this column to find the 00123 value of the function at the specified value \c y. If \c 00124 x_first is false, the opposite strategy is employed. These two 00125 options may give slightly different results. 00126 00127 */ 00128 int set_data(size_t n_x, size_t n_y, ovector &x_grid, 00129 ovector &y_grid, omatrix &data, 00130 bool x_first=true); 00131 00132 /** \brief Reset the stored interpolation since the data has changed 00133 00134 This will return an error if the set_data() has not been called 00135 */ 00136 int reset_interp(); 00137 00138 /** \brief Perform the 2-d interpolation 00139 */ 00140 double interp(double x, double y); 00141 00142 /** \brief Compute the partial derivative in the x-direction 00143 */ 00144 double deriv_x(double x, double y); 00145 00146 /** \brief Compute the partial second derivative in the x-direction 00147 */ 00148 double deriv2_x(double x, double y); 00149 00150 /** \brief Compute the integral in the x-direction between x=x0 00151 and x=x1 00152 */ 00153 double integ_x(double x0, double x1, double y); 00154 00155 /** \brief Compute the partial derivative in the y-direction 00156 */ 00157 double deriv_y(double x, double y); 00158 00159 /** \brief Compute the partial second derivative in the y-direction 00160 */ 00161 double deriv2_y(double x, double y); 00162 00163 /** \brief Compute the integral in the y-direction between y=y0 00164 and y=y1 00165 */ 00166 double integ_y(double x, double y0, double y1); 00167 00168 /** \brief Compute the mixed partial derivative 00169 \f$ \frac{\partial^2 f}{\partial x \partial y} \f$ 00170 */ 00171 double deriv_xy(double x, double y); 00172 00173 /** \brief Specify the base interpolation objects to use 00174 00175 This allows the user to provide new interpolation objects for 00176 use in the two-dimensional interpolation. For 00177 example, 00178 00179 \code 00180 twod_intp ti; 00181 ovector x(20), y(40); 00182 omatrix d(40,20); 00183 00184 // Fill x, y, and d with the data, choose linear interpolation 00185 // instead of the default cubic spline 00186 def_interp_mgr<ovector_const_view,linear_interp> dim1; 00187 def_interp_mgr<ovector_const_subvector,linear_interp> dim2; 00188 00189 ti.set_interp(dim1,dim2); 00190 ti.set_data(20,40,x,y,d,true); 00191 \endcode 00192 00193 This function automatically calls reset_interp() and 00194 reset_data() if the data has already been set to reset the 00195 internal interpolation objects. 00196 */ 00197 int set_interp(base_interp_mgr<ovector_const_view> &b1, 00198 base_interp_mgr<ovector_const_subvector> &b2) { 00199 bimp1=&b1; 00200 bimp2=&b2; 00201 return 0; 00202 } 00203 00204 /** \brief Inform the class the data has been modified or 00205 changed in a way that set_data() will need to be called 00206 again. 00207 */ 00208 int unset_data(); 00209 00210 #ifndef DOXYGENP 00211 00212 protected: 00213 00214 /// \name Default interpolation manager 00215 //@{ 00216 def_interp_mgr<ovector_const_view,cspline_interp> dim1; 00217 def_interp_mgr<ovector_const_subvector,cspline_interp> dim2; 00218 //@} 00219 00220 /// \name Interpolation manager pointers 00221 //@{ 00222 base_interp_mgr<ovector_const_view> *bimp1; 00223 base_interp_mgr<ovector_const_subvector> *bimp2; 00224 //@} 00225 00226 /// The array of sm_interp pointers 00227 sm_interp_vec **si; 00228 /// An array of omatrix_rows 00229 omatrix_row **ari; 00230 /// An array of omatrix_cols 00231 omatrix_col **aci; 00232 00233 /// The number of x grid points 00234 size_t nx; 00235 00236 /// The number of y grid points 00237 size_t ny; 00238 00239 /// If true, the user has specified the base interpolation objects 00240 bool it_set; 00241 00242 /// True if the x interpolation should be done first 00243 bool xfirst; 00244 00245 /// True if the data has been specified by the user 00246 bool data_set; 00247 00248 /// The x grid 00249 ovector *xfun; 00250 00251 /// The y grid 00252 ovector *yfun; 00253 00254 /// The data 00255 omatrix *datap; 00256 00257 /// Allocate the base interpolation objects 00258 int alloc_interp(size_t n); 00259 00260 /// Free the base interpolation objects 00261 int free_interp(); 00262 00263 /// Free the data and interpolation objects 00264 int free_data(); 00265 00266 #endif 00267 00268 }; 00269 00270 #ifndef DOXYGENP 00271 } 00272 #endif 00273 00274 #endif 00275 00276 00277
Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).