Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

tab_fn.H

Go to the documentation of this file.
00001 #ifndef TAB_FN_H_IS_INCLUDED
00002 #define TAB_FN_H_IS_INCLUDED
00003 
00004 /*!
00005  *  \file tab_fn.H
00006  *  \brief Contains the definition of the TabulatedFunction class.
00007  *  \ingroup group_MLIB
00008  *
00009  */
00010 
00011 #include "std/error.H"
00012 
00013 namespace mlib {
00014 
00015 //! \brief Function pointer type for the type of functions that can be tabulated
00016 //! by the TabulatedFunction class.
00017 //! \relates TabulatedFunction
00018 typedef double (*real_fn_t)(double);
00019 
00020 /*!
00021  *  \brief Tabulates values of a given function over an interval [a,b]
00022  *  using a specified resolution.
00023  *  \ingroup group_MLIB
00024  *  
00025  *  Approximations of the function at values in [a,b) are returned as
00026  *  interpolations of the tabulated values. at values outside that range the
00027  *  function itself is used to compute the value.
00028  *
00029  */
00030 class TabulatedFunction
00031 {
00032    
00033    protected:
00034  
00035       //! a (the start of the interval over which the function is tabulated)
00036       double       _a;
00037       //! b (the end of the interval over which the function is tabulated)
00038       double       _b;
00039       //! b - a (the length of the interval over which the function is tabulated)
00040       double       _len;
00041       int          _res;           //!< resolution (# of subintervals)
00042       double       _rlen;          //!< _res / _len (used in computation)
00043       double*      _tab;           //!< table of values
00044       real_fn_t    _f;             //!< the given function
00045 
00046    public:
00047    
00048       //! \name Constructors
00049       //@{
00050  
00051       //! \brief Constructor that tabulates the function \p f over the range
00052       //! [a,b) by taking \p res samples.
00053       TabulatedFunction(double a, double b, real_fn_t f, int res) :
00054          _tab(0) {
00055          init(a,b,f,res);
00056       }
00057       
00058       //! \brief Constructor that creates a tabulated function over the range
00059       //! [a,b) from the values in \p vals.
00060       //!
00061       //! \p vals should have at least \p res elements.
00062       TabulatedFunction(double a, double b, double vals[], int res) :
00063          _tab(0) {
00064          init(a,b,vals,res);
00065       }
00066       
00067       //@}
00068       
00069       //! \name Initialization Functions
00070       //@{
00071          
00072       //! \brief Creates a tabulated function over the range
00073       //! [a,b) from the values in \p vals.
00074       //!
00075       //! \note \p vals should have at least \p res elements.
00076       //!
00077       //! \param[in] a The start of the range of the tabulated function.
00078       //! \param[in] b The end of the range of the tabulated function.
00079       //! \param[in] vals The values to use as samples of the tabulated function.
00080       //! \param[in] res The number of samples in \p vals.
00081       //!
00082       //! \bug This function checks the for allocation errors from the new
00083       //! operator incorrectly (new doesn't return a null pointer on failure,
00084       //! it throws a bad_alloc exception).
00085       void init(double a, double b, double vals[], int res) {
00086          _a = a;
00087          _b = b;
00088          _len = (b-a);
00089          _f = 0;
00090          _res = res;
00091          
00092          delete _tab;
00093          _tab = 0;
00094       
00095          if (_len <= 0 ) {
00096             err_msg("TabulatedFunction::init: interval (%f,%f) is bad", a, b);
00097          } else if (_res < 1) {
00098             err_msg("TabulatedFunction::init: resolution (%d) is too small", _res);
00099          } else if ((_tab = new double [ _res + 1 ]) == 0) {
00100             err_ret("TabulatedFunction::init: can't allocate table");
00101          } else {
00102             _rlen = _res / _len;
00103             for (int n=0; n<=_res; n++) {
00104                _tab[n] = vals[n];
00105             }
00106          }
00107       }
00108       
00109       //! \brief Tabulates the function \p f over the range
00110       //! [a,b) by taking \p res samples.
00111       //!
00112       //! \param[in] a The start of the range over which to tabulate \p f.
00113       //! \param[in] b The end of the range over which to tabulate \p f.
00114       //! \param[in] f The function to tabulate.
00115       //! \param[in] res The number of samples to take while tabulating \p f.
00116       //!
00117       //! \bug This function checks the for allocation errors from the new
00118       //! operator incorrectly (new doesn't return a null pointer on failure,
00119       //! it throws a bad_alloc exception).
00120       void init(double a, double b, real_fn_t f, int res) {
00121          _a = a;
00122          _b = b;
00123          _len = (b - a);
00124          _f = f;
00125          _res = res;
00126       
00127          delete _tab;
00128          _tab = 0;
00129       
00130          if (_len <= 0 ) {
00131             err_msg("TabulatedFunction::init: interval (%f,%f) is bad", a, b);
00132          } else if (_res < 1) {
00133             err_msg("TabulatedFunction::init: resolution (%d) is too small", _res);
00134          } else if ((_tab = new double [ _res + 1 ]) == 0) {
00135             err_ret("TabulatedFunction::init: can't allocate table");
00136          } else {
00137             _rlen = _res / _len;
00138             for (int n=0; n<=_res; n++) {
00139                _tab[n] = (*_f)(n/_rlen + _a);
00140             }
00141          }
00142       }
00143       
00144       //@}
00145       
00146       //! \name Tabulated Function Evaulation
00147       //@{
00148       
00149       //! \brief Evaluates the tabulated function at \p x.
00150       //!
00151       //! Computes the interpolated values of the tabulated function at \p x.
00152       //!
00153       //! If \p x is out of bounds, evaluate the function directly if we have it.
00154       //! If we don't have it, extend the tabulated function to be constant
00155       //! outside of its defined range.
00156       double map(double x) const {
00157          if (x<_a || x>=_b || !_tab)
00158             return _f ? (*_f)(x) : _tab ? _tab[x<_a? 0 : _res] : 0;
00159          else {
00160             double t = _rlen*(x - _a);
00161             int n = (int) floor(t);
00162             double d = t - n;
00163             return _tab[n] + (_tab[n+1] - _tab[n])*d;
00164          }
00165       }
00166       
00167       //@}
00168       
00169 };
00170 
00171 } // namespace mlib
00172 
00173 #endif // TAB_FN_H_IS_INCLUDED
00174 
00175 /* end of file tab_fn.H */

Generated on Mon Sep 18 11:39:33 2006 for jot by  doxygen 1.4.4