mirror of
https://github.com/boostorg/math.git
synced 2026-01-19 04:22:09 +00:00
Fix some issues in bernoulli docs.
This commit is contained in:
Binary file not shown.
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.7 KiB |
File diff suppressed because one or more lines are too long
|
Before Width: | Height: | Size: 10 KiB After Width: | Height: | Size: 5.5 KiB |
230
doc/equations/bernoulli_numbers2.mml
Normal file
230
doc/equations/bernoulli_numbers2.mml
Normal file
@@ -0,0 +1,230 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<math xmlns="http://www.w3.org/1998/Math/MathML">
|
||||
<semantics>
|
||||
<mrow>
|
||||
<mtable>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mrow>
|
||||
<mi>ln</mi>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<msub>
|
||||
<mi>B</mi>
|
||||
<mi>n</mi>
|
||||
</msub>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mrow>
|
||||
<mtext>=</mtext>
|
||||
</mrow>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mfrac>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</mfrac>
|
||||
<mo stretchy="false">+</mo>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
<mi>ln</mi>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
<mo stretchy="false">+</mo>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mfrac>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</mfrac>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
</mrow>
|
||||
<mi>ln</mi>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mo stretchy="false">π</mo>
|
||||
<mtext/>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
<mo stretchy="false">+</mo>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mfrac>
|
||||
<mrow>
|
||||
<mn>3</mn>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</mfrac>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
</mrow>
|
||||
<mi>ln</mi>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mi>R</mi>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</mtd>
|
||||
</mtr>
|
||||
<mtr>
|
||||
<mtd>
|
||||
<mrow>
|
||||
<mi>R</mi>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mi>n</mi>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mrow>
|
||||
<mtext>=</mtext>
|
||||
</mrow>
|
||||
</mtd>
|
||||
<mtd>
|
||||
<mrow>
|
||||
<mi>n</mi>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mfrac>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
</mrow>
|
||||
<mn>12</mn>
|
||||
</mfrac>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mfrac>
|
||||
<mn>1</mn>
|
||||
<mn>30</mn>
|
||||
</mfrac>
|
||||
</mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">(</mo>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mn>1</mn>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mfrac>
|
||||
<mn>2</mn>
|
||||
<mn>7</mn>
|
||||
</mfrac>
|
||||
</mrow>
|
||||
<msup>
|
||||
<mi>n</mi>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</msup>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
<msup>
|
||||
<mi>n</mi>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</msup>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
<msup>
|
||||
<mi>n</mi>
|
||||
<mrow>
|
||||
<mrow>
|
||||
<mo stretchy="false">−</mo>
|
||||
<mn>2</mn>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</msup>
|
||||
</mrow>
|
||||
<mo stretchy="false">)</mo>
|
||||
</mrow>
|
||||
</mrow>
|
||||
</mtd>
|
||||
</mtr>
|
||||
</mtable>
|
||||
</mrow>
|
||||
<annotation encoding="StarMath 5.0">matrix {ln(B_n) # "=" # ({1} over {2} + n)ln(n) + ({1} over {2} - n)ln(%pi%) + ({3} over {2} - n)ln(2) - R(n)
|
||||
##
|
||||
R(n) # "=" # n(1 - {1} over 12 (1 - 1 over 30 (1 - 2 over 7 n^{-2})n^{-2})n^{-2}) }</annotation>
|
||||
</semantics>
|
||||
</math>
|
||||
BIN
doc/equations/bernoulli_numbers2.png
Normal file
BIN
doc/equations/bernoulli_numbers2.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.4 KiB |
2
doc/equations/bernoulli_numbers2.svg
Normal file
2
doc/equations/bernoulli_numbers2.svg
Normal file
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
@@ -7,9 +7,9 @@
|
||||
#
|
||||
# Paths to tools come first, change these to match your system:
|
||||
#
|
||||
math2svg='m:\download\open\SVGMath-0.3.1\math2svg.py'
|
||||
python=/cygdrive/c/Python26/python.exe
|
||||
inkscape=/cygdrive/c/progra~1/Inkscape/inkscape
|
||||
math2svg='d:\download\open\SVGMath-0.3.1\math2svg.py'
|
||||
python=/cygdrive/c/Python27/python.exe
|
||||
inkscape=/cygdrive/c/progra~1/Inkscape/inkscape.exe
|
||||
# Image DPI:
|
||||
dpi=120
|
||||
|
||||
@@ -18,7 +18,7 @@ for mmlfile in $*; do
|
||||
pngfile=$(basename $svgfile .svg).png
|
||||
tempfile=temp.mml
|
||||
# strip html wrappers put in by MathCast:
|
||||
cat $mmlfile | tr -d "\r\n" | sed -e 's/.*\(<math[^>]*>.*<\/math>\).*/\1/' > $tempfile
|
||||
cat $mmlfile | tr -d "\r\n" | sed -e 's/.*\(<math[^>]*>.*<\/math>\).*/\1/' -e 's/<semantics>//g' -e 's/<\/semantics>//g' > $tempfile
|
||||
|
||||
echo Generating $svgfile
|
||||
$python $math2svg $tempfile > $svgfile
|
||||
@@ -31,3 +31,4 @@ done
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -18,16 +18,23 @@ including the __tgamma, __lgamma and polygamma functions.
|
||||
namespace boost { namespace math {
|
||||
|
||||
template <class T>
|
||||
T bernoulli_b2n(const int i); // Single Bernoulli number (default policy).
|
||||
T bernoulli_b2n(const int n); // Single Bernoulli number (default policy).
|
||||
|
||||
template <class T, class Policy>
|
||||
T bernoulli_b2n(const int i, const Policy &pol); // User policy for errors etc.
|
||||
T bernoulli_b2n(const int n, const Policy &pol); // User policy for errors etc.
|
||||
|
||||
}} // namespaces
|
||||
|
||||
[h4 Description]
|
||||
|
||||
Both return the (2 * i)[super th] Bernoulli number.
|
||||
Both return the (2 * n)[super th] Bernoulli number B[sub 2n].
|
||||
|
||||
Note that since all odd numbered Bernoulli numbers are zero (apart from B[sub 1] which is [plusminus][frac12])
|
||||
the interface will only return the even numbered Bernoulli numbers.
|
||||
|
||||
This function uses fast table lookup for low-indexed Bernoulli numbers, while larger values are calculated
|
||||
as needed and then cached. The caching mechanism requires a certain amount of thread safety code, so
|
||||
`unchecked_bernoulli_b2n` may provide a better interface for performance critical code.
|
||||
|
||||
The final __Policy argument is optional and can be used to control the behaviour of the function:
|
||||
how it handles errors, what level of precision to use, etc.
|
||||
@@ -45,23 +52,32 @@ Refer to __policy_section for more details.
|
||||
|
||||
[h4 Synopsis]
|
||||
``
|
||||
#include <boost/math/special_functions/detail/unchecked_bernoulli.hpp>
|
||||
#include <boost/math/special_functions/bernoulli.hpp>
|
||||
|
||||
``
|
||||
|
||||
template <>
|
||||
struct max_bernoulli_b2n<T>;
|
||||
|
||||
template<class T>
|
||||
inline T unchecked_bernoulli_b2n(unsigned n);
|
||||
|
||||
`unchecked_bernoulli_b2n` provides access to Bernoulli numbers [*without any checks for overflow or invalid parameters].
|
||||
(Not recommended for normal use, but bypassing overflow checks is quicker.)
|
||||
It is implemented as a direct (and very fast) table lookup, and while not recomended for general use it can be useful
|
||||
inside inner loops where the ultimate performance is required, and error checking is moved outside the loop.
|
||||
|
||||
template <>
|
||||
struct max_bernoulli_index<T>::value
|
||||
The largest value you can pass to `unchecked_bernoulli_b2n<>` is `max_bernoulli_b2n<>::value`: passing values greater than
|
||||
that will result in a buffer overrun error, so it's clearly important to place the error handling in your own code
|
||||
when using this direct interface.
|
||||
|
||||
The largest value you can (without overflow) pass to `unchecked_bernoulli_b2n<>`
|
||||
is `max_bernoulli_b2n<>::value`.
|
||||
The value of `boost::math::max_bernoulli_b2n<T>::value` varies by the type T, for types `float`/`double`/`long double`
|
||||
it's the largest value which doesn't overflow the target type: for example, `boost::math::max_bernoulli_b2n<double>::value` is 129.
|
||||
However, for multiprecision types, it's the largest value for which the result can be represented as the ratio of two 64-bit
|
||||
integers, for example `boost::math::max_bernoulli_b2n<boost::multiprecision::cpp_dec_float_50>::value` is just 17. Of course
|
||||
larger indexes can be passed to `bernoulli_b2n<T>(n)`, but then then you loose fast table lookup (i.e. values may need to be calculated).
|
||||
|
||||
For example, `boost::math::max_bernoulli_b2n<double>::value` is 129.
|
||||
[bernoulli_example_4]
|
||||
[bernoulli_output_4]
|
||||
|
||||
[h4 Multiple Bernoulli Numbers]
|
||||
|
||||
@@ -96,20 +112,15 @@ with one call (one with default policy and the other allowing a user-defined pol
|
||||
|
||||
These return a series of Bernoulli numbers:
|
||||
|
||||
Bernoulli(2*start_index),
|
||||
Bernoulli(2*(start_index+1))
|
||||
...
|
||||
Bernoulli(2*(number_of_bernoullis_b2n-1))
|
||||
[:B[sub 2*start_index],B[sub 2*(start_index+1)],...,B[sub 2*(start_index+number_of_bernoullis_b2n-1)]]
|
||||
|
||||
[h4 Examples]
|
||||
[bernoulli_example_2]
|
||||
[bernoulli_output_2]
|
||||
[bernoulli_example_3]
|
||||
[bernoulli_output_3]
|
||||
[bernoulli_example_4]
|
||||
[bernoulli_output_4]
|
||||
|
||||
The source of this example is at [../../example/bernoulli_example.cpp bernoulli_example.cpp]
|
||||
The source of this example is at [@../../example/bernoulli_example.cpp bernoulli_example.cpp]
|
||||
|
||||
[h4 Accuracy]
|
||||
|
||||
@@ -117,9 +128,10 @@ All the functions usually return values within one ULP (unit in the last place)
|
||||
|
||||
[h4 Implementation]
|
||||
|
||||
The implementation details are in [@../../include/boost/math/special_functions/detail/bernoulli_details.hpp bernoulli_details.hpp].
|
||||
The implementation details are in [@../../include/boost/math/special_functions/detail/bernoulli_details.hpp bernoulli_details.hpp]
|
||||
and [@../../include/boost/math/special_functions/detail/unchecked_bernoulli.hpp unchecked_bernoulli.hpp].
|
||||
|
||||
For `i <= max_bernoulli_index<T>::value` this is implemented by table lookup;
|
||||
For `i <= max_bernoulli_index<T>::value` this is implemented by simple table lookup from a statically initialized table;
|
||||
for larger values of `i`, this is implemented by the Tangent Numbers algorithm as described in the paper:
|
||||
Fast Computation of Bernoulli, Tangent and Secant Numbers, Richard P. Brent and David Harvey,
|
||||
[@http://arxiv.org/pdf/1108.0286v3.pdf] (2011).
|
||||
@@ -128,8 +140,6 @@ Fast Computation of Bernoulli, Tangent and Secant Numbers, Richard P. Brent and
|
||||
(an even alternating permutation number) are defined
|
||||
and their generating function is also given therein.
|
||||
|
||||
[/@http://mathworld.wolfram.com/images/equations/TangentNumber/Inline15.gif]
|
||||
|
||||
The relation of Tangent numbers with Bernoulli numbers ['B[sub i]]
|
||||
is given by Brent and Harvey's equation 14:
|
||||
|
||||
@@ -143,7 +153,13 @@ elseif i == 0 then ['B[sub i]] = 1 [br]
|
||||
elseif i == 1 then ['B[sub i]] = -1/2 [br]
|
||||
elseif i < 0 or i is odd then ['B[sub i]] = 0
|
||||
|
||||
[/@http://s7.postimg.org/mygi2kror/bernoulli_1.png]
|
||||
Note that computed values are stored in a fixed-size table, access is thread safe via atomic operations (i.e. lock
|
||||
free programming), this imparts a much lower overhead on access to cached values than might overwise be expected -
|
||||
typically for multiprecision types the cost of thread synchronisation is negligable, while for built in types
|
||||
this code is not normally executed anyway. For very large arguments which cannot be reasonably computed or
|
||||
stored in our cache, an asymptotic expansion [@http://www.luschny.de/math/primes/bernincl.html due to Luschny] is used:
|
||||
|
||||
[equation bernoulli_numbers2]
|
||||
|
||||
[endsect] [/section:bernoulli_numbers Bernoulli Numbers]
|
||||
|
||||
|
||||
@@ -34,7 +34,8 @@ int main()
|
||||
{
|
||||
//[bernoulli_example_1
|
||||
|
||||
/*`A simple example computes the value of `Bernoulli(2)` where the return type is `double`.
|
||||
/*`A simple example computes the value of B[sub 4] where the return type is `double`,
|
||||
note that the argument to bernoulli_b2n is ['2] not ['4] since it computes B[sub 2N].
|
||||
|
||||
|
||||
*/
|
||||
@@ -48,7 +49,7 @@ int main()
|
||||
/*`So B[sub 4] == -1/30 == -0.0333333333333333
|
||||
|
||||
If we use Boost.Multiprecision and its 50 decimal digit floating-point type `cpp_dec_float_50`,
|
||||
we can calculate the value of much larger numbers like `Bernoulli(100)`
|
||||
we can calculate the value of much larger numbers like B[sub 200]
|
||||
and also obtain much higher precision.
|
||||
*/
|
||||
|
||||
@@ -107,11 +108,7 @@ and we will get a helpful error message (provided try'n'catch blocks are used).
|
||||
//] //[/bernoulli_example_3]
|
||||
|
||||
//[bernoulli_example_4
|
||||
/*`Users can determine from `max_bernoulli_b2n<>::value`
|
||||
the largest Bernoulli number you can evaluate for any type
|
||||
(or safely pass to `unchecked_bernoulli_b2n<>`).
|
||||
|
||||
For example:
|
||||
/*For example:
|
||||
*/
|
||||
std::cout << "boost::math::max_bernoulli_b2n<float>::value = " << boost::math::max_bernoulli_b2n<float>::value << std::endl;
|
||||
std::cout << "Maximum Bernoulli number using float is " << boost::math::bernoulli_b2n<float>( boost::math::max_bernoulli_b2n<float>::value) << std::endl;
|
||||
|
||||
Reference in New Issue
Block a user