/************************************************************************* * Copyright (C) 2010-2012 Tavian Barnes * * * * This file is part of The Dimension Test Suite. * * * * The Dimension Test Suite is free software; you can redistribute it * * and/or modify it under the terms of the GNU General Public License as * * published by the Free Software Foundation; either version 3 of the * * License, or (at your option) any later version. * * * * The Dimension Test Suite is distributed in the hope that it will be * * useful, but WITHOUT ANY WARRANTY; without even the implied warranty * * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * * General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see . * *************************************************************************/ /** * @file * Basic tests of the polynomial root-finder. */ #include "tests.h" #include "../polynomial.c" /* poly[] = 2*(x + 1)*(x - 1.2345)*(x - 2.3456)*(x - 5)*(x - 100) */ static const double poly[6] = { [5] = 2.0, [4] = -215.1602, [3] = 1540.4520864, [2] = -2430.5727856, [1] = -1292.541872, [0] = 2895.6432, }; static double roots[5]; static size_t nroots; #define DMNSN_CLOSE_ENOUGH 1.0e-6 DMNSN_TEST_SETUP(polynomial) { nroots = dmnsn_polynomial_solve(poly, 5, roots); } DMNSN_TEST(polynomial, finds_positive_roots) { ck_assert_int_eq(nroots, 4); } DMNSN_TEST(polynomial, local_min_roots) { for (size_t i = 0; i < nroots; ++i) { double evmin = dmnsn_polynomial_evaluate(poly, 5, roots[i] - dmnsn_epsilon); double ev = dmnsn_polynomial_evaluate(poly, 5, roots[i]); double evmax = dmnsn_polynomial_evaluate(poly, 5, roots[i] + dmnsn_epsilon); ck_assert(fabs(ev) < fabs(evmin) && fabs(ev) < fabs(evmax)); } } DMNSN_TEST(polynomial, accurate_roots) { for (size_t i = 0; i < nroots; ++i) { double ev = dmnsn_polynomial_evaluate(poly, 5, roots[i]); ck_assert(fabs(ev) < DMNSN_CLOSE_ENOUGH); } } /* repeated_root[] = (x - 1)^6 */ static const double repeated_root[7] = { [6] = 1.0, [5] = -6.0, [4] = 15.0, [3] = -20.0, [2] = 15.0, [1] = -6.0, [0] = 1.0, }; DMNSN_TEST(stability, equal_bounds) { double root = dmnsn_bisect_root(repeated_root, 6, 1.0, 1.0); ck_assert_msg(root == 1.0, "root == %.17g", root); } DMNSN_TEST(stability, equal_values_at_bounds) { double root = dmnsn_bisect_root(repeated_root, 6, 0.9, 1.1); ck_assert_msg(fabs(root - 1.0) < dmnsn_epsilon, "root == %.17g", root); }