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