Chebyshev Approximation

A class implementing the Chebyshev approximations based on GSL is given in o2scl::cheb_approx. This class has its own copy constructor, so that Chebyshev approximations can be copied and passed as arguments to functions. Derivatives and integrals of o2scl::cheb_approx objects are created as new o2scl::cheb_approx objects which can be easily manipulated.

Chebyshev approximation example

This example performs an approximation of the function $ y=\sin\left[ 1/\left(x+0.08 \right) \right] $ over $ [0,2 \pi] $ . This function oscillates strongly over this interval and requires a high order approximation to be accurate.

The image below shows the approximation for $ n=50 $ and $ n=25 $ . The $ n=100 $ would be nearly indistinguishable from the exact result on this scale.

ex_chebapp_plot.png
Chebyshev approximation plot
/* Example: ex_chebapp.cpp
-------------------------------------------------------------------
*/
#include <iostream>
#include <o2scl/constants.h>
#include <o2scl/test_mgr.h>
#include <o2scl/cheb_approx.h>
#include <o2scl/deriv_cern.h>
#include <o2scl/inte_qag_gsl.h>
using namespace std;
using namespace o2scl;
double func(double x) {
return sin(1.0/(x+0.08));
}
double dfunc(double x) {
return -cos(1.0/(x+0.08))/pow(x+0.08,2.0);
}
// Simple function to output information to file for plotting
void write_file(cheb_approx &gc);
int main(void) {
cout.setf(ios::scientific);
funct11 tf=func;
double res, err;
double x0=0.55;
// Initialize the Chebyshev approximation
gc.init(func,100,0.0,2.0*o2scl_const::pi);
// Evaluate the approximation and compare with the exact result
cout << "f(0.55)" << endl;
cout << "Exact : " << func(x0) << endl;
gc.eval_err(x0,res,err);
cout << "Approx (n=100): " << res << endl;
cout << " Est. Error : " << err << endl;
cout << " Act. Error : " << fabs(res-func(x0)) << endl;
// Evaluate the approximation at lower order
gc.eval_n_err(50,x0,res,err);
cout << "Approx (n=50) : " << res << endl;
cout << " Est. Error : " << err << endl;
cout << " Act. Error : " << fabs(res-func(x0)) << endl;
gc.eval_n_err(25,x0,res,err);
cout << "Approx (n=25) : " << res << endl;
cout << " Est. Error : " << err << endl;
cout << " Act. Error : " << fabs(res-func(x0)) << endl;
cout << endl;
t.test_rel(gc.eval(x0),func(x0),1.0e-4,"eval");
// Show how to use operator=() to create a new approximation
cheb_approx gc2=gc;
cout << "Using operator=(): " << gc2.eval(x0) << " " << func(x0) << endl;
cout << endl;
t.test_rel(gc2.eval(x0),gc.eval(x0),1.0e-10,"op=");
// Show how to compute the derivative
cheb_approx gc_deriv;
gc.deriv(gc_deriv);
cout << "f'(0.55)" << endl;
cout << "Exact : " << dfunc(x0) << endl;
gc_deriv.eval_err(x0,res,err);
cout << "Approx (n=100): " << res << endl;
cout << " Est. Error : " << err << endl;
cout << " Act. Error : " << fabs(res-dfunc(x0)) << endl;
cd.deriv_err(x0,tf,res,err);
cout << "Direct deriv : " << res << endl;
cout << " Est. Error : " << err << endl;
cout << " Act. Error : " << fabs(res-dfunc(x0)) << endl;
cout << endl;
t.test_abs(res,dfunc(x0),1.0e-12,"deriv with deriv_cern");
t.test_abs(gc_deriv.eval(x0),dfunc(x0),5.0e-3,"deriv with cheb");
// Show how to compute the integral
cheb_approx gc_integ;
gc.integ(gc_integ);
cout << "int(f,0,0.55)" << endl;
gc_integ.eval_err(x0,res,err);
cout << "Approx (n=100): " << res << endl;
cout << " Est. Error : " << err << endl;
gi.integ_err(tf,0.0,x0,res,err);
cout << "Direct integ : " << res << endl;
cout << " Est. Error : " << err << endl;
cout << "Rel. Error : " << fabs(res-gc_integ.eval(x0)) << endl;
cout << endl;
t.test_abs(gc_integ.eval(x0),gi.integ(tf,0.0,x0),1.0e-6,"integral");
write_file(gc);
t.report();
return 0;
}
// End of example

Documentation generated with Doxygen. Provided under the GNU Free Documentation License (see License Information).