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
,
O2scl Sourceforge Project Page