blob: 587ad1a3cd8e14f83d392a4f1d280b1f97e918a5 [file]
// SPDX-FileCopyrightText: The Eigen Authors
// SPDX-License-Identifier: MPL-2.0
// Interpolatory quadrature: the weights w of a rule sum_i w_i f(x_i) that is
// exact for polynomials of degree < n solve the transposed Vandermonde system
// V^T w = m with the moments m_k = \int_{-1}^{1} x^k dx. Bjorck-Pereyra solves
// it (the dual system) in O(n^2); on Chebyshev extreme points the weights are
// those of Clenshaw-Curtis quadrature. The primal system V a = f gives the
// monomial coefficients of the interpolating polynomial.
#include <contrib/Eigen/StructuredMatrices>
#include <cmath>
#include <iomanip>
#include <iostream>
using namespace Eigen;
int main() {
const double pi = std::acos(-1.0);
const double exact = 2 * std::sinh(1.0); // \int_{-1}^{1} e^x dx
std::cout << " n sum(w) error on e^x\n";
for (int n : {5, 9, 13, 17}) {
VectorXd x(n), moments(n);
for (int i = 0; i < n; ++i) x[i] = -std::cos(pi * i / (n - 1)); // increasing nodes
for (int k = 0; k < n; ++k) moments[k] = k % 2 == 0 ? 2.0 / (k + 1) : 0.0;
const BjorckPereyra<double> bp(makeVandermonde(x));
const VectorXd w = bp.transpose().solve(moments);
std::cout << std::setw(3) << n << " " << std::setw(6) << w.sum() << " "
<< std::abs(w.dot(x.array().exp().matrix()) - exact) << "\n";
}
// Interpolation: the cubic through four samples of x^3 - 2x + 1.
const Vector4d x(-1, 0, 0.5, 2);
const Vector4d f = x.array().cube() - 2 * x.array() + 1;
std::cout << "monomial coefficients of the interpolant: "
<< BjorckPereyra<double>(makeVandermonde(x)).solve(f).transpose() << "\n";
}