From ccb508194fabf02dac9a75c5648756409d82647b Mon Sep 17 00:00:00 2001 From: pabristow Date: Wed, 7 Aug 2019 09:07:11 +0100 Subject: [PATCH] [CI SKIP] Added missing example file and more index entries --- doc/index.idx | 2 +- doc/overview/structure.qbk | 38 ++++++------ doc/sf/factorials.qbk | 20 +++--- example/jacobi_zeta_example.cpp | 104 ++++++++++++++++++++++++++++++++ 4 files changed, 133 insertions(+), 31 deletions(-) create mode 100644 example/jacobi_zeta_example.cpp diff --git a/doc/index.idx b/doc/index.idx index c12fbdfdb..6f147bdc6 100644 --- a/doc/index.idx +++ b/doc/index.idx @@ -60,7 +60,7 @@ DCDFLIB feedback -bugs \ +bug \ GIT \ diff --git a/doc/overview/structure.qbk b/doc/overview/structure.qbk index a106f97a1..550639c15 100644 --- a/doc/overview/structure.qbk +++ b/doc/overview/structure.qbk @@ -51,28 +51,28 @@ This documentation aims to use of the following naming and formatting convention * Names that refer to ['concepts] in the generic programming sense (like template parameter names) are specified in CamelCase. - [endsect] [/section:conventions Document Conventions] [section:hints Other Hints and tips] -* If you have a feature request, -or if it appears that the implementation is in error, -please search first in the [@https://svn.boost.org/trac/boost/ Boost Trac]. - -* [@https://svn.boost.org/trac/boost/ Trac] entries may indicate that -updates or corrections that solve your problem are in -[@http://svn.boost.org/svn/boost/trunk Boost-trunk] -where changes are being assembled and tested ready for the next release. +* Historial records of issues are at [@https://svn.boost.org/trac/boost/ Boost Trac]. +* Always ensure that you are using the [@https://www.boost.org/users/download/#live current release version]. +* The current documentation for the release version is [@https://www.boost.org/doc/libs/release/libs/math/doc/html/index.html here]. +* The current documentation for the version being developed is [@https://www.boost.org/doc/libs/develop/libs/math/doc/html/index.html here]. +* See [@https://github.com/boostorg/math develop branch(es)] where changes are being assembled and tested ready for the next release.[br] You may, at your own risk, download new versions from there. - +* If you have a new feature request, raise a new [@https://github.com/boostorg/math/issues Boost.Math issue], +* If it appears that the implementation is in error, +please search first at [@https://github.com/boostorg/math/issues Boost.Math issues]. +Entries may indicate that updates or corrections that solve your problem are in +[@https://github.com/boostorg/math Boost.Math on Github]. * If you do not understand why things work the way they do, see the ['rationale] section. +* If you do not find satisfaction for your idea/feature/complaint, +please reach the author(s) preferably through the [@boost@lists.boost.org Boost development list], +or raise a new [@https://github.com/boostorg/math/issues Boost.Math issue], +or email the author(s) direct. -* If you do not find your idea/feature/complaint, -please reach the author preferably through the Boost -development list, or email the author(s) direct. - -[h5 Admonishments] +[h5:admonishments Admonishments] [note In addition, notes such as this one specify non-essential information that provides additional background or rationale.] @@ -83,8 +83,7 @@ provides additional background or rationale.] Failure to follow suggestions in these blocks will probably result in undesired behavior. Read all of these you find.] -[warning Failure to heed this will lead to incorrect, -and very likely undesired, results.] +[warning Failure to heed this will lead to incorrect, and very likely undesired, results.] [endsect] [/section:hints Other Hints and tips] @@ -100,12 +99,11 @@ and very likely undesired, results.] as the RealType (and short `typedef` names of distributions are reserved for this type where possible), a few will use `float` or `long double`, but it is also possible to use higher precision types - like __NTL_RR, __GMP, __MPFR + like __NTL_RR, __GMP, __MPFR, __multiprecision like cpp_bin_float_50 that conform to the requirements specified by real_concept.]] [[\/constants\/] - [Templated definition of some highly accurate math - constants (in constants.hpp).]] + [Templated definition of some highly accurate math constants ([@https://github.com/boostorg/math/blob/develop/include/boost/math/constants/constants.hpp constants.hpp]).]] [[\/distributions\/] [Distributions used in mathematics and, especially, statistics: diff --git a/doc/sf/factorials.qbk b/doc/sf/factorials.qbk index 21b4d61d9..946e602b6 100644 --- a/doc/sf/factorials.qbk +++ b/doc/sf/factorials.qbk @@ -183,13 +183,13 @@ generated by functions.wolfram.com. The double factorial is implemented in terms of the factorial and gamma functions using the relations: -[:(2n)!! = 2[super n ] * n!] +[:['(2n)!! = 2[super n ] * n!]] -[:(2n+1)!! = (2n+1)! / (2[super n ] n!)] +[:['(2n+1)!! = (2n+1)! / (2[super n ] n!)]] and -[:(2n-1)!! = [Gamma]((2n+1)/2) * 2[super n ] / sqrt(pi)] +[:['(2n-1)!! = [Gamma]((2n+1)/2) * 2[super n ] / sqrt(pi)]] [endsect] [/section:sf_double_factorial Double Factorial] @@ -211,11 +211,11 @@ and Returns the rising factorial of /x/ and /i/: -[:rising_factorial(x, i) = [Gamma](x + i) / [Gamma](x)] +[:['rising_factorial(x, i) = [Gamma](x + i) / [Gamma](x)]] or -[:rising_factorial(x, i) = x(x+1)(x+2)(x+3)...(x+i-1)] +[:['rising_factorial(x, i) = x(x+1)(x+2)(x+3)...(x+i-1)]] Note that both /x/ and /i/ can be negative as well as positive. @@ -240,7 +240,7 @@ by functions.wolfram.com. [h4 Implementation] -Rising and falling factorials are implemented as ratios of gamma functions +Rising and [' factorials are implemented as ratios of gamma functions using __tgamma_delta_ratio. Optimisations for small integer arguments are handled internally by that function. @@ -264,7 +264,7 @@ small integer arguments are handled internally by that function. Returns the falling factorial of /x/ and /i/: -[:falling_factorial(x, i) = x(x-1)(x-2)(x-3)...(x-i+1)] +[:['falling_factorial(x, i) = x(x-1)(x-2)(x-3)...(x-i+1)]] Note that this function is only defined for positive /i/, hence the `unsigned` second argument. Argument /x/ can be either positive or @@ -353,15 +353,15 @@ generated by functions.wolfram.com. Binomial coefficients are calculated using table lookup of factorials where possible using: -[:[sub n]C[sub k] = n! / (k!(n-k)!)] +[:['[sub n]C[sub k] = n! / (k!(n-k)!)]] Otherwise it is implemented in terms of the beta function using the relations: -[:[sub n]C[sub k] = 1 / (k * __beta(k, n-k+1))] +[:['[sub n]C[sub k] = 1 / (k * __beta(k, n-k+1))]] and -[:[sub n]C[sub k] = 1 / ((n-k) * __beta(k+1, n-k))] +[:['[sub n]C[sub k] = 1 / ((n-k) * __beta(k+1, n-k))]] [endsect] [/section:sf_binomial Binomial Coefficients] diff --git a/example/jacobi_zeta_example.cpp b/example/jacobi_zeta_example.cpp new file mode 100644 index 000000000..062f27baa --- /dev/null +++ b/example/jacobi_zeta_example.cpp @@ -0,0 +1,104 @@ +// Copyright Paul A. Bristow, 2019 + +// 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) + +/*! \title Simple example of computation of the Jacobi Zeta function using Boost.Math, +and also using corresponding WolframAlpha commands. +*/ + +#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS +# error "This example requires a C++ compiler that supports C++11 numeric_limits. Try C++11 or later." +#endif + +#include // For jacobi_zeta function. +#include // For cpp_bin_float_50. + +#include +#include +#include +#include + +int main() +{ + try + { + std::cout.precision(std::numeric_limits::max_digits10); // Show all potentially significant digits. + std::cout.setf(std::ios_base::showpoint); // Include any significant trailing zeros. + + using boost::math::jacobi_zeta; // jacobi_zeta(T1 k, T2 phi) |k| <=1, k = sqrt(m) + using boost::multiprecision::cpp_bin_float_50; + + // Wolfram Mathworld function JacobiZeta[phi, m] where m = k^2 + // JacobiZeta[phi,m] gives the Jacobi zeta function Z(phi | m) + + // If phi = 2, and elliptic modulus k = 0.9 so m = 0.9 * 0.9 = 0.81 + + // https://reference.wolfram.com/language/ref/JacobiZeta.html // Function information. + // A simple computation using phi = 2. and m = 0.9 * 0.9 + // JacobiZeta[2, 0.9 * 0.9] + // https://www.wolframalpha.com/input/?i=JacobiZeta%5B2,+0.9+*+0.9%5D + // -0.248584... + // To get the expected 17 decimal digits precision for a 64-bit double type, + // we need to ask thus: + // N[JacobiZeta[2, 0.9 * 0.9],17] + // https://www.wolframalpha.com/input/?i=N%5BJacobiZeta%5B2,+0.9+*+0.9%5D,17%5D + + double k = 0.9; + double m = k * k; + double phi = 2.; + + std::cout << "m = k^2 = " << m << std::endl; // m = k^2 = 0.81000000000000005 + std::cout << "jacobi_zeta(" << k << ", " << phi << " ) = " << jacobi_zeta(k, phi) << std::endl; + // jacobi_zeta(0.90000000000000002, 2.0000000000000000 ) = + // -0.24858442708494899 Boost.Math + // -0.24858442708494893 Wolfram + // that agree within the expected precision of 17 decimal digits for 64-bit type double. + + // We can also easily get a higher precision too: + // For example, to get 50 decimal digit precision using WolframAlpha: + // N[JacobiZeta[2, 0.9 * 0.9],50] + // https://www.wolframalpha.com/input/?i=N%5BJacobiZeta%5B2,+0.9+*+0.9%5D,50%5D + // -0.24858442708494893408462856109734087389683955309853 + + // Using Boost.Multiprecision we can do them same almost as easily. + + // To check that we are not losing precision, we show all the significant digits of the arguments ad result: + std::cout.precision(std::numeric_limits::digits10); // Show all significant digits. + + // We can force the computation to use 50 decimal digit precision thus: + cpp_bin_float_50 k50("0.9"); + cpp_bin_float_50 phi50("2."); + + std::cout << "jacobi_zeta(" << k50 << ", " << phi50 << " ) = " << jacobi_zeta(k50, phi50) << std::endl; + // jacobi_zeta(0.90000000000000000000000000000000000000000000000000, + // 2.0000000000000000000000000000000000000000000000000 ) + // = -0.24858442708494893408462856109734087389683955309853 + + // and a comparison with Wolfram shows agreement to the expected precision. + // -0.24858442708494893408462856109734087389683955309853 Boost.Math + // -0.24858442708494893408462856109734087389683955309853 Wolfram + + // Taking care not to fall into the awaiting pit, we ensure that ALL arguments passed are of the + // appropriate 50-digit precision and do NOT suffer from precision reduction to that of type double, + // We do NOT write: + std::cout << "jacobi_zeta(0.9, 2.) = " << jacobi_zeta(0.9, 2) << std::endl; + // jacobi_zeta(0.90000000000000000000000000000000000000000000000000, + // 2.0000000000000000000000000000000000000000000000000 ) + // = -0.24858442708494895921459900494815797085727097762164 << Wrong at about 17th digit! + // -0.24858442708494893408462856109734087389683955309853 Wolfram + } + catch (std::exception const& ex) + { + // Lacking try&catch blocks, the program will abort after any throw, whereas the + // message below from the thrown exception will give some helpful clues as to the cause of the problem. + std::cout << "\n""Message from thrown exception was:\n " << ex.what() << std::endl; + // An example of message: + // std::cout << " = " << jacobi_zeta(2, 0.5) << std::endl; + // Message from thrown exception was: + // Error in function boost::math::ellint_k(long double) : Got k = 2, function requires |k| <= 1 + // Shows that first parameter is k and is out of range, as the definition in docs jacobi_zeta(T1 k, T2 phi); + } +} // int main()