Question: need help with C++ plz, I have errors in my code :( your program will use three different 5-point numerical quadrature methods (Closed Newton Cotes,
need help with C++ plz, I have errors in my code :(
your program will use three different 5-point numerical quadrature methods (Closed Newton Cotes, Gaussian Quadrature, and Lobatto Quadrature)
You will employ each of these methods to solve each of the following three problems to find the area under the respective curves over the interval (-1, 1).
1) f(x) = 1 - sin(1 - x) (The true area under the above curve is (to 20 digits) 0.58385316345285761300)
2) f(x) = sqrt(x + 1) + 1 (The true area under the above curve is (to 20 digits) 3.8856180831641267317)
3) f(x) = tanh(x + 1) (The true area under the above curve is (to 20 digits) 1.3250027473578644309)
First, print out the values of the weights and the nodes for each quadrature formula, Then for each function (or curve), print out your approximation to the area under the curve, the true value of the area, and the error in the approximation for each of the three quadrature formulae.
#include
#include
double GaussLobattoIntStep(const boost::function
double a, double b,
double fa, double fb,
size_t &neval,
size_t maxeval,
double acc)
{
// Constants used in the algorithm
const double alpha = std::sqrt(2.0/3.0);
const double beta = 1.0/std::sqrt(5.0);
if (neval >= maxeval)
{
throw std::runtime_error("Maximum number of evaluations reached in GaussLobatto");
}
const double h=(b-a)/2;
const double m=(a+b)/2;
const double mll=m-alpha*h;
const double ml =m-beta*h;
const double mr =m+beta*h;
const double mrr=m+alpha*h;
const double fmll= f(mll);
const double fml = f(ml);
const double fm = f(m);
const double fmr = f(mr);
const double fmrr= f(mrr);
neval+=5;
// Both the 4-point and 7-point rule integrals are evaluted
const double integral2=(h/6)*(fa+fb+5*(fml+fmr));
const double integral1=(h/1470)*(77*(fa+fb)
+432*(fmll+fmrr)+625*(fml+fmr)+672*fm);
// The difference betwen the 4-point and 7-point integrals is the
// estimate of the accuracy
const double estacc=(integral1-integral2);
// The volatile keyword should prevent the floating point
// destination value from being stored in extended precision
// registers which actually have a very different
// std::numeric_limits
volatile double dist = acc + estacc;
if(dist==acc || mll<=a || b<=mrr)
{
if (not (m>a && b>m))
{
throw std::runtime_error("Integration reached an interval with no more machine numbers");
}
return integral1;
}
else {
return GaussLobattoIntStep(f, a, mll, fa, fmll, neval, maxeval, acc)
+ GaussLobattoIntStep(f, mll, ml, fmll, fml, neval, maxeval, acc)
+ GaussLobattoIntStep(f, ml, m, fml, fm, neval, maxeval, acc)
+ GaussLobattoIntStep(f, m, mr, fm, fmr, neval, maxeval, acc)
+ GaussLobattoIntStep(f, mr, mrr, fmr, fmrr, neval, maxeval, acc)
+ GaussLobattoIntStep(f, mrr, b, fmrr, fb, neval, maxeval, acc);
}
}
/** \brief Compute the Gauss-Lobatto integral
\param f The function to be integrated
\param a The lower integration limit
\param b The upper integration limit
\param abstol Absolute tolerance -- integration stops when the
error estimate is smaller than this
\param maxeval Maxium of evaluations to make. If this number of
evalution is made without reaching the requied accuracy, an
exception of type std::runtime_error is thrown.
*/
double GaussLobattoInt(const boost::function
double a, double b,
double abstol,
size_t maxeval)
{
const double tol_epsunit=abstol/std::numeric_limits
size_t neval=0;
return GaussLobattoIntStep(f, a, b,
f(a), f(b),
neval,
maxeval,
tol_epsunit);
}
// Below is a very simple illustration of the code
double samplef(double x)
{
return std::sin(x);
}
int main(void)
{
double res=GaussLobattoInt(&samplef,
0, 10,
1e-10,
1000);
std::cout< < } #Gauss Legendre class LegendrePolynomial { public: LegendrePolynomial(double lowerBound, double upperBound, size_t numberOfIterations) : mLowerBound(lowerBound), mUpperBound(upperBound), mNumberOfIterations(numberOfIterations), mWeight(numberOfIterations+1), mRoot(numberOfIterations+1) { calculateWeightAndRoot(); } const std::vector return mWeight; } const std::vector return mRoot; } private: const static double EPSILON; struct Result { double value; double derivative; Result() : value(0), derivative(0) {} Result(double val, double deriv) : value(val), derivative(deriv) {} }; void calculateWeightAndRoot() { for(int step = 0; step <= mNumberOfIterations; step++) { double root = cos(M_PI * (step-0.25)/(mNumberOfIterations+0.5)); Result result = calculatePolynomialValueAndDerivative(root); double newtonRaphsonRatio; do { newtonRaphsonRatio = result.value/result.derivative; root -= newtonRaphsonRatio; result = calculatePolynomialValueAndDerivative(root); } while (fabs(newtonRaphsonRatio) > EPSILON); mRoot[step] = root; mWeight[step] = 2.0/((1-root*root)*result.derivative*result.derivative); } } Result calculatePolynomialValueAndDerivative(double x) { Result result(x, 0); double value_minus_1 = 1; const double f = 1/(x*x-1); for(int step = 2; step <= mNumberOfIterations; step++) { const double value = ((2*step-1)*x*result.value-(step-1)*value_minus_1)/step; result.derivative = step*f*(x*value result.value); value_minus_1 = result.value; result.value = value; } return result; } const double mLowerBound; const double mUpperBound; const int mNumberOfIterations; std::vector std::vector }; const double LegendrePolynomial::EPSILON = 1e-15; double gaussLegendreIntegral(double a, double b, int n, const std::function const LegendrePolynomial legendrePolynomial(a, b, n); const std::vector const std::vector const double width = 0.5*(b-a); const double mean = 0.5*(a+b); double gaussLegendre = 0; for(int step = 1; step <= n; step++) { gaussLegendre += weight[step]*f(width * root[step] + mean); } return gaussLegendre * width; }
Step by Step Solution
There are 3 Steps involved in it
Get step-by-step solutions from verified subject matter experts
