// Copyright Nick Thompson 2017. // Use, modification and distribution are subject to the // Boost Software License, Version 1.0. // (See accompanying file LICENSE_1_0.txt // or copy at http://www.boost.org/LICENSE_1_0.txt) #define BOOST_TEST_MAIN #include #include #include #include #include using boost::math::legendre_stieltjes; using boost::math::legendre_p; using boost::multiprecision::cpp_bin_float_quad; template void test_legendre_stieltjes() { std::cout << std::setprecision(std::numeric_limits::digits10); using std::sqrt; using std::abs; using boost::math::constants::third; using boost::math::constants::half; Real tol = std::numeric_limits::epsilon(); legendre_stieltjes ls1(1); legendre_stieltjes ls2(2); legendre_stieltjes ls3(3); legendre_stieltjes ls4(4); legendre_stieltjes ls5(5); legendre_stieltjes ls8(8); Real x = -1; while(x <= 1) { BOOST_CHECK_CLOSE_FRACTION(ls1(x), x, tol); BOOST_CHECK_CLOSE_FRACTION(ls1.prime(x), 1, tol); Real p2 = legendre_p(2, x); BOOST_CHECK_CLOSE_FRACTION(ls2(x), p2 - 2/static_cast(5), tol); BOOST_CHECK_CLOSE_FRACTION(ls2.prime(x), 3*x, tol); Real p3 = legendre_p(3, x); BOOST_CHECK_CLOSE_FRACTION(ls3(x), p3 - 9*x/static_cast(14), 600*tol); BOOST_CHECK_CLOSE_FRACTION(ls3.prime(x), 15*x*x*half() -3*half()-9/static_cast(14), 100*tol); Real p4 = legendre_p(4, x); //-20P_2(x)/27 + 14P_0(x)/891 Real E4 = p4 - 20*p2/static_cast(27) + 14/static_cast(891); BOOST_CHECK_CLOSE_FRACTION(ls4(x), E4, 250*tol); BOOST_CHECK_CLOSE_FRACTION(ls4.prime(x), 35*x*(9*x*x -5)/static_cast(18), 250*tol); Real p5 = legendre_p(5, x); Real E5 = p5 - 35*p3/static_cast(44) + 135*x/static_cast(12584); BOOST_CHECK_CLOSE_FRACTION(ls5(x), E5, 29000*tol); Real E5prime = (315*(123 + 143*x*x*(11*x*x-9)))/static_cast(12584); BOOST_CHECK_CLOSE_FRACTION(ls5.prime(x), E5prime, 29000*tol); x += 1/static_cast(1 << 9); } // Test norm: // E_1 = x Real expected_norm_sq = 2*third(); BOOST_CHECK_CLOSE_FRACTION(expected_norm_sq, ls1.norm_sq(), tol); // E_2 = P[sub 2](x) - 2P[sup 0](x)/5 expected_norm_sq = 2/static_cast(5) + 8/static_cast(25); BOOST_CHECK_CLOSE_FRACTION(expected_norm_sq, ls2.norm_sq(), tol); // E_3 = P[sub 3](x) - 9P[sub 1]/14 expected_norm_sq = 2/static_cast(7) + 9*9*2*third()/static_cast(14*14); BOOST_CHECK_CLOSE_FRACTION(expected_norm_sq, ls3.norm_sq(), tol); // E_4 = P[sub 4](x) -20P[sub 2](x)/27 + 14P[sub 0](x)/891 expected_norm_sq = static_cast(2)/static_cast(9) + static_cast(20*20*2)/static_cast(27*27*5) + 14*14*2/static_cast(891*891); BOOST_CHECK_CLOSE_FRACTION(expected_norm_sq, ls4.norm_sq(), tol); // E_5 = P[sub 5](x) - 35P[sub 3](x)/44 + 135P[sub 1](x)/12584 expected_norm_sq = 2/static_cast(11) + (35*35/static_cast(44*44))*(2/static_cast(7)) + (135*135/static_cast(12584*12584))*2*third(); BOOST_CHECK_CLOSE_FRACTION(expected_norm_sq, ls5.norm_sq(), tol); // Only zero of E1 is 0: std::vector zeros = ls1.zeros(); BOOST_CHECK(zeros.size() == 1); BOOST_CHECK_SMALL(zeros[0], tol); BOOST_CHECK_SMALL(ls1(zeros[0]), tol); zeros = ls2.zeros(); BOOST_CHECK(zeros.size() == 1); BOOST_CHECK_CLOSE_FRACTION(zeros[0], sqrt(3/static_cast(5)), tol); BOOST_CHECK_SMALL(ls2(zeros[0]), tol); zeros = ls3.zeros(); BOOST_CHECK(zeros.size() == 2); BOOST_CHECK_SMALL(zeros[0], tol); BOOST_CHECK_CLOSE_FRACTION(zeros[1], sqrt(6/static_cast(7)), tol); zeros = ls4.zeros(); BOOST_CHECK(zeros.size() == 2); Real expected = sqrt( (55 - 2*sqrt(static_cast(330)))/static_cast(11) )/static_cast(3); BOOST_CHECK_CLOSE_FRACTION(zeros[0], expected, tol); expected = sqrt( (55 + 2*sqrt(static_cast(330)))/static_cast(11) )/static_cast(3); BOOST_CHECK_CLOSE_FRACTION(zeros[1], expected, 10*tol); zeros = ls5.zeros(); BOOST_CHECK(zeros.size() == 3); BOOST_CHECK_SMALL(zeros[0], tol); expected = sqrt( ( 195 - sqrt(static_cast(6045)) )/static_cast(286)); BOOST_CHECK_CLOSE_FRACTION(zeros[1], expected, tol); expected = sqrt( ( 195 + sqrt(static_cast(6045)) )/static_cast(286)); BOOST_CHECK_CLOSE_FRACTION(zeros[2], expected, tol); for (size_t i = 6; i < 50; ++i) { legendre_stieltjes En(i); zeros = En.zeros(); for(auto const & zero : zeros) { BOOST_CHECK_SMALL(En(zero), 50*tol); } } } BOOST_AUTO_TEST_CASE(LegendreStieltjesZeros) { test_legendre_stieltjes(); test_legendre_stieltjes(); test_legendre_stieltjes(); //test_legendre_stieltjes(); }