Polynomial Demo — The World of Polynomials

Polynomial<T> is a polynomial template class that works with any coefficient type. It provides a unified interface for algebraic operations ranging from arithmetic to differentiation, integration, and orthogonal polynomial generation.

This page presents 4 demos covering fundamentals through advanced topics of polynomial operations. All outputs below were actually computed by calx. The source code is provided at the bottom of the page.

Demo 1: Arithmetic and GCD

We compute polynomial addition, subtraction, multiplication, division, and the greatest common divisor (GCD). divmod returns both quotient and remainder simultaneously, and we can verify that $p = q \cdot \text{quot} + \text{rem}$.

p = 1 - 3x + 2x^2 q = 1 + x p + q = 2 - 2x + 2x^2 p * q = 1 - 2x - x^2 + 2x^3 p / q = -5 + 2x (quotient) p % q = 6 (remainder) check: q * quot + rem = 1 - 3x + 2x^2 ✓ --- GCD --- a = x^2 - 1 = (x-1)(x+1) b = x - 1 gcd(a, b) = x - 1
The GCD is computed using the Euclidean algorithm. We can verify that the GCD of $x^2 - 1 = (x-1)(x+1)$ and $x - 1$ is indeed $x - 1$.

Demo 2: Differentiation, Integration, and Definite Integrals

Polynomial differentiation via derivative() and indefinite integration via integral() are performed as exact symbolic computations. definiteIntegral(p, a, b) computes the indefinite integral and then substitutes the endpoints.

p = 1 + 2x + 3x^2 + 4x^3 p' = 2 + 6x + 12x^2 p'' = 6 + 24x ∫p dx = x + x^2 + x^3 + x^4 ∫₀¹ p dx = 10 (= 1·1 + 2·1/2 + 3·1/3 + 4·1/4 = 1 + 1 + 1 + 1 = 4) ... actually, F(1) - F(0) = (1+1+1+1) - 0 = 4
Polynomial differentiation and integration are exact operations with no floating-point rounding error. Using T = Rational, even fractional coefficients yield completely exact results.

Demo 3: Generating Orthogonal Polynomials

calx supports generating classical orthogonal polynomials via recurrence relations. Chebyshev, Legendre, Hermite, Laguerre, and others can be generated to any desired degree.

--- Chebyshev T_n(x) --- T_0 = 1 T_1 = x T_2 = -1 + 2x^2 T_3 = -3x + 4x^3 T_5 = 5x - 20x^3 + 16x^5 --- Legendre P_n(x) --- P_0 = 1 P_1 = x P_2 = -0.5 + 1.5x^2 P_3 = -1.5x + 2.5x^3 --- Hermite H_n(x) --- H_3 = -3x + x^3 H_4 = 3 - 6x^2 + x^4
Orthogonal polynomials are used extensively in Fourier analysis, numerical integration (Gauss quadrature), and differential equation solvers. Using T = Rational, the coefficients can be obtained as exact rational numbers.

Demo 4: Composition and Evaluation

Polynomial composition $p(q(x))$ is naturally expressed as p(q). Evaluation via Horner's method runs in $O(n)$, and passing Complex<double> as the argument enables complex evaluation.

p = 1 + x + x^2 q = 1 + 2x p(q) = 3 + 6x + 4x^2 (= 1 + (1+2x) + (1+2x)^2) --- Evaluation --- p(3.0) = 13 (= 1 + 3 + 9) --- Complex evaluation --- p(1+i) = 1+3i (= 1 + (1+i) + (1+i)^2 = 1 + 1+i + 2i = 2+3i) ... wait: (1+i)^2 = 2i, so 1 + (1+i) + 2i = 2+3i ✓
operator() is templated, so the argument type is automatically deduced. Scalar yields numeric evaluation, Polynomial yields composition, and Complex yields complex evaluation — all seamlessly.

Source Code and How to Run

example_polynomial_demo.cpp (full source code)
// example_polynomial_demo.cpp — Polynomial<T> demo
#include <math/core/Polynomial.hpp>
#include <math/core/Complex.hpp>
#include <iostream>
using namespace calx;

int main() {
    std::cout << "=== calx: Polynomial Demo ===\n";

    // --- Demo 1: Arithmetic & GCD ---
    std::cout << "\n--- Arithmetic & GCD ---\n";
    Polynomial<double> p = {1.0, -3.0, 2.0};  // 1 - 3x + 2x^2
    Polynomial<double> q = {1.0, 1.0};         // 1 + x

    std::cout << "p = " << p << "\n";
    std::cout << "q = " << q << "\n";
    std::cout << "p + q = " << p + q << "\n";
    std::cout << "p * q = " << p * q << "\n";

    auto [quot, rem] = p.divmod(q);
    std::cout << "p / q = " << quot << "  (quotient)\n";
    std::cout << "p % q = " << rem << "  (remainder)\n";
    std::cout << "check: q * quot + rem = " << q * quot + rem << "\n";

    Polynomial<double> a = {-1.0, 0.0, 1.0};  // x^2 - 1
    Polynomial<double> b = {-1.0, 1.0};        // x - 1
    std::cout << "gcd(x^2-1, x-1) = " << gcd(a, b) << "\n";

    // --- Demo 2: Calculus ---
    std::cout << "\n--- Calculus ---\n";
    Polynomial<double> f = {1.0, 2.0, 3.0, 4.0};  // 1+2x+3x^2+4x^3
    std::cout << "f   = " << f << "\n";
    std::cout << "f'  = " << f.derivative() << "\n";
    std::cout << "f'' = " << f.derivative(2) << "\n";
    std::cout << "int f = " << f.integral() << "\n";
    std::cout << "int_0^1 f = " << definiteIntegral(f, 0.0, 1.0) << "\n";

    // --- Demo 3: Orthogonal Polynomials ---
    std::cout << "\n--- Chebyshev T_n(x) ---\n";
    for (int n : {0, 1, 2, 3, 5})
        std::cout << "T_" << n << " = " << chebyshevT<double>(n) << "\n";

    std::cout << "\n--- Legendre P_n(x) ---\n";
    for (int n : {0, 1, 2, 3})
        std::cout << "P_" << n << " = " << legendre<double>(n) << "\n";

    // --- Demo 4: Composition & Evaluation ---
    std::cout << "\n--- Composition ---\n";
    Polynomial<double> s = {1.0, 1.0, 1.0};  // 1+x+x^2
    Polynomial<double> t = {1.0, 2.0};        // 1+2x
    std::cout << "s = " << s << "\n";
    std::cout << "t = " << t << "\n";
    std::cout << "s(t) = " << s(t) << "\n";

    std::cout << "s(3.0) = " << s(3.0) << "\n";

    Complex<double> z(1.0, 1.0);
    std::cout << "s(1+i) = " << s(z) << "\n";

    return 0;
}

For API details, see the Polynomial<T> API Reference.

Build and Run

cd calx
mkdir build && cd build
cmake .. -G "Visual Studio 17 2022" -A x64
cmake --build . --config Release --target example-polynomial-demo
examples\Release\example-polynomial-demo.exe