// Copyright (C) 2026 Kiyotsugu Arai // SPDX-License-Identifier: LGPL-3.0-or-later // // example_doc_roots_samples.cpp // Verification harness for samples written in api/Roots.html. #include #include #include #include #include // needed for Matrix::solve member #include #include #include using namespace sangi; int main() { std::cout << std::setprecision(15); // ---- sample 1: bisection sqrt(2) ----------------------------- { std::cout << "[bisection sqrt(2)]\n"; auto r = bisection( [](double x) { return x * x - 2.0; }, 1.0, 2.0); std::cout << " converged = " << std::boolalpha << r.converged << " iter = " << r.iterations << " root = " << (r.root ? *r.root : 0.0) << " err = " << r.error_estimate << "\n"; } // ---- sample 2: brent cos(x) = x ------------------------------- { std::cout << "[brent cos(x) - x = 0]\n"; auto r = brent_method( [](double x) { return std::cos(x) - x; }, 0.0, 1.0); std::cout << " converged = " << std::boolalpha << r.converged << " iter = " << r.iterations << " root = " << (r.root ? *r.root : 0.0) << " err = " << r.error_estimate << "\n"; } // ---- sample 4: newton_raphson sqrt(2) ------------------------- { std::cout << "[newton_raphson sqrt(2)]\n"; auto r = newton_raphson( [](double x) { return x * x - 2.0; }, [](double x) { return 2.0 * x; }, 1.0); std::cout << " converged = " << std::boolalpha << r.converged << " iter = " << r.iterations << " root = " << (r.root ? *r.root : 0.0) << "\n"; } // ---- sample 5: secant Dottie ---------------------------------- { std::cout << "[secant cos(x)-x]\n"; auto r = secant_method( [](double x) { return x - std::cos(x); }, 0.0, 1.0); std::cout << " converged = " << std::boolalpha << r.converged << " iter = " << r.iterations << " root = " << (r.root ? *r.root : 0.0) << "\n"; } // ---- sample 6: halley cube root of 2 -------------------------- { std::cout << "[halley cube root of 2]\n"; auto r = halley_method( [](double x) { return x * x * x - 2.0; }, [](double x) { return 3.0 * x * x; }, [](double x) { return 6.0 * x; }, 1.0); std::cout << " converged = " << std::boolalpha << r.converged << " iter = " << r.iterations << " root = " << (r.root ? *r.root : 0.0) << "\n"; } // ---- sample 7: solveQuadratic x^2 - 5x + 6 -------------------- { std::cout << "[solveQuadratic x^2 - 5x + 6 = 0]\n"; Polynomial p({6.0, -5.0, 1.0}); // ascending auto roots = solveQuadratic(p); std::cout << " roots ="; for (auto& r : roots) std::cout << ' ' << r.re; std::cout << "\n"; } // ---- sample 8: jenkinsTraub x^6 - 1 --------------------------- { std::cout << "[jenkinsTraub x^6 - 1 = 0]\n"; Polynomial p({-1.0, 0, 0, 0, 0, 0, 1.0}); auto roots = jenkinsTraub(p); double max_residual = 0.0; for (auto& r : roots) { auto r2 = r * r; auto r6 = r2 * r2 * r2; auto resid_re = r6.re - 1.0; auto resid_im = r6.im; double m = std::sqrt(resid_re * resid_re + resid_im * resid_im); if (m > max_residual) max_residual = m; } std::cout << " n_roots = " << roots.size() << " max |p(root)| = " << max_residual << "\n"; } // ---- sample 3: newton_raphson_nd, unit circle ∩ y = x ---- { std::cout << "[newton_raphson_nd unit circle ∩ y=x]\n"; auto F = [](const Vector& v) { Vector r(2); r[0] = v[0] * v[0] + v[1] * v[1] - 1.0; r[1] = v[0] - v[1]; return r; }; auto J = [](const Vector& v) { Matrix m(2, 2); m(0, 0) = 2 * v[0]; m(0, 1) = 2 * v[1]; m(1, 0) = 1.0; m(1, 1) = -1.0; return m; }; Vector x0(2); x0[0] = 0.5; x0[1] = 0.5; auto r = newton_raphson_nd, Matrix>(F, J, x0); std::cout << " converged = " << std::boolalpha << r.converged << " iter = " << r.iterations; if (r.root) { const auto& v = *r.root; std::cout << " root = (" << v[0] << ", " << v[1] << ")"; } std::cout << "\n"; } return 0; }