gsl_chebapp.h

00001 /*
00002   -------------------------------------------------------------------
00003   
00004   Copyright (C) 2006, 2007, 2008, 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_GSL_CHEBAPP_H
00024 #define O2SCL_GSL_CHEBAPP_H
00025 
00026 #include <o2scl/collection.h>
00027 #include <o2scl/funct.h>
00028 #include <gsl/gsl_chebyshev.h>
00029 #include <cmath>
00030 
00031 #ifndef DOXYGENP
00032 namespace o2scl {
00033 #endif
00034 
00035   /** 
00036       \brief Chebyshev approximation (GSL)
00037       
00038       Approximate a function using a Chebyshev series:
00039       \f[
00040       f(x) = \sum_n c_n T_n(x) \qquad \mathrm{where}
00041       \qquad T_n(x)=\cos(n \arccos x)
00042       \f]
00043 
00044       \future Implement eval_err(), eval_n() and eval_n_err() methods
00045       from GSL.
00046   */
00047   template<class param_t, class func_t> class gsl_chebapp {
00048   public:
00049   
00050     gsl_chebapp() {
00051       order=5;
00052       init_called=false;
00053       gcs=gsl_cheb_alloc(order);
00054     }
00055     
00056     /** \brief Initialize a Chebyshev approximation of the function
00057         \c func over the interval from \c a to \c b
00058 
00059         The interval must be specified so that \f$ a < b \f$ .
00060     */
00061     int init(func_t &func, double a, double b, param_t &vp) {
00062       size_t k, j;
00063   
00064       if(a>=b) {
00065         O2SCL_ERR_RET("Interval a>=b in gsl_chebapp::init().",gsl_einval);
00066       }
00067       gcs->a=a;
00068       gcs->b=b;
00069   
00070       double bma=0.5*(gcs->b-gcs->a);
00071       double bpa=0.5*(gcs->b+gcs->a);
00072       double fac=2.0/(gcs->order+1.0);
00073   
00074       for(k=0;k<=gcs->order;k++) {
00075         double y=cos(M_PI*(k+0.5)/(gcs->order+1));
00076         gcs->f[k]=func(y*bma+bpa,vp);
00077       }
00078   
00079       for(j=0;j<=gcs->order;j++) {
00080         double sum=0.0;
00081         for(k=0;k<=gcs->order; k++) {
00082           sum+=gcs->f[k]*cos(M_PI*j*(k+0.5)/(gcs->order+1));
00083         }
00084         gcs->c[j]=fac*sum;
00085       }
00086 
00087       init_called=true;
00088 
00089       return 0;
00090     }
00091 
00092     /** 
00093         \brief Set the order (default 5)
00094         
00095         The function init() must be called after calling set_order()
00096         to reinitialize the series for the new order.
00097      */
00098     int set_order(size_t od) {
00099       order=od;
00100       init_called=false;
00101       gsl_cheb_free(gcs);
00102       gcs=gsl_cheb_alloc(order);
00103       return 0;
00104     }
00105 
00106     /** \brief Evaluate the approximation
00107      */
00108     double eval(double x) {
00109       if (init_called==false) {
00110         O2SCL_ERR("Series not initialized in gsl_chebapp::eval().",
00111                 gsl_einval);
00112         return 0.0;
00113       }
00114       return gsl_cheb_eval(gcs,x);
00115     }
00116     
00117     /** 
00118         \brief Return a pointer to an approximation to the derivative
00119         
00120         The new gsl_chebapp object is allocated by new, and the memory
00121         should be deallocated using delete by the user.
00122      */
00123     gsl_chebapp *deriv() {
00124       if (init_called==false) {
00125         O2SCL_ERR("Series not initialized in gsl_chebapp::deriv().",
00126                 gsl_einval);
00127         return 0;
00128       }
00129       gsl_chebapp *gc=new gsl_chebapp;
00130       gc->set_order(order);
00131       gc->init_called=true;
00132       gsl_cheb_calc_deriv(gc->gcs,gcs);
00133       return gc;
00134     }
00135 
00136     /** 
00137         \brief Return a pointer to an approximation to the integral
00138 
00139         The new gsl_chebapp object is allocated by new, and the memory
00140         should be deallocated using delete by the user.
00141      */
00142     gsl_chebapp *inte() {
00143       if (init_called==false) {
00144         O2SCL_ERR("Series not initialized in gsl_chebapp::inte().",
00145                 gsl_einval);
00146         return 0;
00147       }
00148       gsl_chebapp *gc=new gsl_chebapp;
00149       gc->set_order(order);
00150       gc->init_called=true;
00151       gsl_cheb_calc_integ(gc->gcs,gcs);
00152       return gc;
00153     }
00154 
00155     /** 
00156         \brief Get the coefficient
00157 
00158         Legal values of the argument are 0 to \c order (inclusive)
00159     */
00160     double get_coefficient(size_t ix) {
00161       if (ix<order+1) {
00162         return gcs->c[ix];
00163       }
00164       O2SCL_ERR
00165         ("Requested invalid coefficient in gsl_chebapp::get_coefficient()",
00166          gsl_einval);
00167       return 0.0;
00168     }
00169 
00170 #ifndef DOXYGENP
00171 
00172   protected:
00173 
00174     /// The GSL representation of the series
00175     gsl_cheb_series *gcs;
00176 
00177     /// The order
00178     size_t order;
00179 
00180     /// True if init has been called
00181     bool init_called;
00182 
00183 #endif
00184   
00185   };
00186 
00187 #ifndef DOXYGENP
00188 }
00189 #endif
00190 
00191 #endif

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

Project hosting provided by SourceForge.net Logo, O2scl Sourceforge Project Page