00001 /* 00002 ------------------------------------------------------------------- 00003 00004 Copyright (C) 2006, 2007, 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 00039 two-dimensional interpolation. Derivatives and integrals 00040 along both x- and y-directions can be computed. 00041 00042 The storage for the data, including the arrays \c x_fun 00043 and \c y_fun are all managed by the user. If the data is 00044 changed without calling reset_interp(), then interp() will 00045 return incorrect results. 00046 00047 No caching is done (except for the caching already present 00048 in sm_interp), and successive calls to interp() with the 00049 same values of x and y will take nearly the same amount of time. 00050 00051 \todo Test non-square data 00052 \todo Allow specification of data as [ny][nx] or as [nx][ny]? 00053 00054 \todo Need to rewrite to use \ref o2scl_interp after that 00055 class is finished. 00056 \todo Could also include mixed second/first derivatives: 00057 deriv_xxy and deriv_xyy. 00058 00059 */ 00060 class twod_intp { 00061 public: 00062 00063 twod_intp(); 00064 00065 virtual ~twod_intp(); 00066 00067 /** \brief Initialize the data for the 2-dimensional interpolation 00068 00069 The interpolation type (passed directly to int_type) is 00070 specified in \c int_type and the data is specified in 00071 \c data. The data should be arranged so that the first 00072 array index is the y-value (the "row") and the second array 00073 index is the x-value (the "column"). The arrays \c xfun 00074 and \c yfun specify the two independent 00075 variables. \c xfun should be an array of length 00076 \c nx , and should be an array of length \c ny. The 00077 array \c data should be a two-dimensional array of size 00078 [ny][nx]. 00079 00080 If \c x_first is true, then set_data() creates interpolation 00081 objects for each of the rows. Calls to interp() then uses 00082 these to create a column at the specified value of \c x. An 00083 interpolation object is created at this column to find the 00084 value of the function at the specified value \c y. If \c 00085 x_first is false, the opposite strategy is employed. These two 00086 options will give different results (unless linear 00087 interpolation is explicity selected). Using \c x_first=false 00088 will be slightly slower, since the data has to be rearranged 00089 in the opposite order first. In general, if the data is "more 00090 accurate" in the x direction than in the y direction, it is 00091 probably better to choose \c x_first=true. 00092 00093 Valid values of \c int_type are: 00094 - 0 - default (cubic spline) 00095 - 1 - linear 00096 - 2 - cubic spline 00097 - 3 - periodic cubic spline 00098 - 4 - akima spline 00099 - 5 - periodic akima spline 00100 00101 */ 00102 int set_data(int n_x, int n_y, ovector &x_fun, 00103 ovector &y_fun, omatrix &u_data, 00104 bool x_first=true); 00105 00106 /** \brief Reset the stored interpolation since the data has changed 00107 00108 This will return an error if the set_data() has not been called 00109 */ 00110 int reset_interp(); 00111 00112 /** \brief Perform the 2-d interpolation 00113 */ 00114 double interp(double x, double y); 00115 00116 /** \brief Compute the partial derivative in the x-direction 00117 */ 00118 double deriv_x(double x, double y); 00119 00120 /** \brief Compute the partial second derivative in the x-direction 00121 */ 00122 double deriv2_x(double x, double y); 00123 00124 /** \brief Compute the integral in the x-direction between x=x0 00125 and x=x1 00126 */ 00127 double integ_x(double x0, double x1, double y); 00128 00129 /** \brief Compute the partial derivative in the y-direction 00130 */ 00131 double deriv_y(double x, double y); 00132 00133 /** \brief Compute the partial second derivative in the y-direction 00134 */ 00135 double deriv2_y(double x, double y); 00136 00137 /** \brief Compute the integral in the y-direction between y=y0 00138 and y=y1 00139 */ 00140 double integ_y(double x, double y0, double y1); 00141 00142 /** \brief Compute the mixed partial derivative 00143 \f$ \frac{\partial^2 f}{\partial x \partial y} \f$ 00144 */ 00145 double deriv_xy(double x, double y); 00146 00147 00148 #ifndef DOXYGENP 00149 00150 protected: 00151 00152 /// The array of sm_interp pointers 00153 sm_interp_vec **si; 00154 /// An array of omatrix_rows 00155 omatrix_row **ari; 00156 /// An array of omatrix_cols 00157 omatrix_col **aci; 00158 00159 /// The number of x grid points 00160 int nx; 00161 00162 /// The number of y grid points 00163 int ny; 00164 00165 /// True if the x interpolation should be done first 00166 bool xfirst; 00167 00168 /// True if the data has been specified by the user 00169 bool data_set; 00170 00171 /// The definition of the x grid 00172 ovector *xfun; 00173 00174 /// The definition of the y grid 00175 ovector *yfun; 00176 00177 /// The data 00178 omatrix *data; 00179 00180 /// The x-y flipped data if we're doing the y-interpolation first 00181 omatrix yfirst_data; 00182 00183 #endif 00184 00185 }; 00186 00187 #ifndef DOXYGENP 00188 } 00189 #endif 00190 00191 #endif 00192 00193 00194