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