Object-oriented Scientific Computing Library: Version 0.910
twod_intp.h
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 
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).

Get Object-oriented Scientific Computing
Lib at SourceForge.net. Fast, secure and Free Open Source software
downloads.