twod_intp.h

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 

Documentation generated with Doxygen and provided under the GNU Free Documentation License. See License Information for details.