1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54
|
#include <iostream>
#include <iomanip>
#include <vector>
#include <cmath>
using namespace std;
double fn( double x ) { return log10( x ); } // function to approximate
double D( const vector<double> &xpt, int i, int j, double f( double x ) ) // successive differences
{
if ( j == i ) return f( xpt[i] );
else return ( D( xpt, i + 1, j, f ) - D( xpt, i, j - 1, f ) ) / ( xpt[j] - xpt[i] );
}
vector<double> coeffs( const vector<double> &xpt, double f( double x ) ) // set coefficients
{
int imax = xpt.size();
vector<double> a( imax );
for ( int i = 0; i < imax; i++ ) a[i] = D( xpt, 0, i, f ) ;
return a;
}
double poly( const vector<double> &xpt, const vector<double> &a, double x ) // evaluate Newton polynomial
{
int imax = xpt.size();
double result = 0.0;
for ( int i = imax - 1; i >= 0; i-- ) result = a[i] + ( x - xpt[i] ) * result;
return result;
}
int main()
{
// Set the interpolation points
const int NPT = 6;
const double xstart = 1.2, dx = 0.1;
vector<double> xpt( NPT );
for ( int i = 0; i < NPT; i++ ) xpt[i] = xstart + i * dx;
// Find the coefficients
vector<double> a = coeffs( xpt, fn );
// Set some points to interpolate to (add the originals as a check)
const int NCHECK = NPT * 2 - 1;
vector<double> xcheck;
for ( int i = 0; i < NCHECK; i++ ) xcheck.push_back( xstart + 0.5 * i * dx );
#define SP << " " << setw( 15 ) <<
cout SP "x" SP "Polynomial" SP "Actual" << '\n';
for ( double x : xcheck ) cout SP x SP poly( xpt, a, x ) SP fn( x ) << '\n';
}
|