2
0
mirror of https://github.com/boostorg/math.git synced 2026-01-19 04:22:09 +00:00

New sections of examples or cube, fifth, multiprecision and nth root finding, and comparison of timing and iterations.

This commit is contained in:
pabristow
2015-04-26 17:41:10 +01:00
parent 9b293b689d
commit e7ae689ea5
42 changed files with 3154 additions and 165 deletions

View File

@@ -490,7 +490,7 @@ These changes should be made last, when `my_special` is stable and the code is i
[h4 Concept Checks]
Our concept checks verify that your function's implementation makes no assumptions that aren't
required by our [link math_toolkit.concepts Real number conceptual requirements]. They also
required by our [link math_toolkit.real_concepts Real number conceptual requirements]. They also
check for various common bugs and programming traps that we've fallen into over time. To
add your function to these tests, edit libs/math/test/compile_test/instantiate.hpp to add
calls to your function: there are 7 calls to each function, each with a different purpose.

View File

@@ -20,12 +20,12 @@ Of course, the main cost of higher precision is very much decreased
(usually at least hundred-fold) computation speed, and big increases in memory use.
Some libraries offer true
[@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary precision arithmetic]
where the precision is limited only by avilable memory and compute time, but most are used
at some arbitrarily-fixed precision, say 100 decimal digits.
[@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary-precision arithmetic]
where the precision is limited only by available memory and compute time, but most are used
at some arbitrarily-fixed precision, say 100 decimal digits, like __boost_multiprecision `cpp_dec_float_100`.
__multiprecision can operate in both ways, but the most popular choice is likely to be about a hundred
decimal digits, though examples of computing tens of thousands of digits have been demonstrated.
decimal digits, though examples of computing about a million digits have been demonstrated.
[section:why_high_precision Why use a high-precision library rather than built-in floating-point types?]
@@ -37,8 +37,8 @@ Some reasons why one would want to use a higher precision:
* A much more precise result (many more digits) is just a requirement.
* The range of the computed value exceeds the range of the type: factorials are the textbook example.
* Using double is (or may be) too inaccurate.
* Using long double (or may be) is too inaccurate.
* Using `double` is (or may be) too inaccurate.
* Using `long double` (or may be) is too inaccurate.
* Using an extended precision type implemented in software as
[@http://en.wikipedia.org/wiki/Double-double_(arithmetic)#Double-double_arithmetic double-double]
([@http://en.wikipedia.org/wiki/Darwin_(operating_system) Darwin]) is sometimes unpredictably inaccurate.
@@ -237,7 +237,6 @@ to the majority of functions defined this library when used with `NTL::RR`.
There is a concept checking test program for NTL support
[@../../../../libs/math/test/ntl_concept_check.cpp here].
[endsect] [/section:use_ntl Using With NTL - a High-Precision Floating-Point Library]
[section:using_test Using without expression templates for Boost.Test and others]
@@ -258,25 +257,25 @@ you will need to override the default `boost::multiprecision::et_on` with
A full example code is at [@../../example/test_cpp_float_close_fraction.cpp test_cpp_float_close_fraction.cpp]
[endsect] [/section:using_test Using without expression templates for Boost.Test and others]
[endsect] [/section:high_precision Using With High-Precision Floating-Point Libraries]
[section:real_concepts Conceptual Requirements for Real Number Types]
[section:concepts Conceptual Requirements for Real Number Types]
The functions, and statistical distributions in this library can be used with
any type /RealType/ that meets the conceptual requirements given below. All
the built-in floating-point types will meet these requirements.
User-defined types that meet the requirements can also be used.
The functions and statistical distributions in this library can be used with
any type ['RealType] that meets the conceptual requirements given below. All
the built-in floating-point types like `double` will meet these requirements.
(Built-in types are also called __fundamental_types).
User-defined types that meet the conceptual requirements can also be used.
For example, with [link math_toolkit.high_precision.use_ntl a thin wrapper class]
one of the types provided with [@http://shoup.net/ntl/ NTL (RR)] can be used.
But now that __multiprecision library is available,
this has become the reference real number type.
this has become the preferred real-number type,
typically __cpp_dec_float or __cpp_bin_float.
Submissions of binding to other extended precision types would also still be welcome.
The guiding principal behind these requirements is that a /RealType/
The guiding principal behind these requirements is that a ['RealType]
behaves just like a built-in floating-point type.
[h4 Basic Arithmetic Requirements]
@@ -381,8 +380,8 @@ to a string, causing potentially serious loss of accuracy on output.
Although it might seem obvious that RealType should require `std::numeric_limits`
to be specialized, this is not sensible for
`NTL::RR` and similar classes where the number of digits is a runtime
parameter (where as for `numeric_limits` it has to be fixed at compile time).
`NTL::RR` and similar classes where the [*number of digits is a runtime parameter]
(whereas for `numeric_limits` everything has to be fixed at compile time).
]
[h4 Standard Library Support Requirements]
@@ -391,7 +390,7 @@ Many (though not all) of the functions in this library make calls
to standard library functions, the following table summarises the
requirements. Note that most of the functions in this library
will only call a small subset of the functions listed here, so if in
doubt whether a user defined type has enough standard library
doubt whether a user-defined type has enough standard library
support to be useable the best advise is to try it and see!
In the following table /r/ is an object of type `RealType`,
@@ -441,8 +440,8 @@ boost/math/special_functions/lanczos.hpp] or
[@../../../../boost/math/bindings/detail/big_lanczos.hpp
boost/math/bindings/detail/big_lanczos.hpp]:
in the former case you will need change
static_cast's to lexical_cast's, and the constants to /strings/
(in order to ensure the coefficients aren't truncated to long double)
`static_cast`'s to `lexical_cast`'s, and the constants to /strings/
(in order to ensure the coefficients aren't truncated to `long doubl`e)
and then specialise `lanczos_traits` for type T. Otherwise you may have to hack
[@../../tools/lanczos_generator.cpp
libs/math/tools/lanczos_generator.cpp] to find a suitable
@@ -450,11 +449,11 @@ approximation for your RealType. The code will still compile if you don't do
this, but both accuracy and efficiency will be greatly compromised in any
function that makes use of the gamma\/beta\/erf family of functions.
[endsect] [/section: ]
[endsect] [/section:real_concepts Conceptual Requirements for Real Number Types]
[section:dist_concept Conceptual Requirements for Distribution Types]
A /DistributionType/ is a type that implements the following conceptual
A ['DistributionType] is a type that implements the following conceptual
requirements, and encapsulates a statistical distribution.
Please note that this documentation should not be used as a substitute
@@ -463,8 +462,8 @@ for the
[link math_toolkit.stat_tut tutorial] of the statistical
distributions.
In the following table, /d/ is an object of type `DistributionType`,
/cd/ is an object of type `const DistributionType` and /cr/ is an
In the following table, ['d] is an object of type `DistributionType`,
['cd] is an object of type `const DistributionType` and ['cr] is an
object of a type convertible to `RealType`.
[table
@@ -495,16 +494,16 @@ object of a type convertible to `RealType`.
[[variance(cd)][RealType][Returns the variance of the distribution.]]
]
[endsect]
[endsect] [/ section:dist_concept Conceptual Requirements for Distribution Types]
[section:archetypes Conceptual Archetypes for Reals and Distributions]
There are a few concept archetypes available:
* Real concept for floating-point types.
* distribution Concept for statistical distributions.
* Distribution concept for statistical distributions.
[h5 Real concept]
[h5:real_concept Real concept]
`std_real_concept` is an archetype for theReal types,
including the built-in float, double, long double.
@@ -558,7 +557,7 @@ that instantiates every template in this library with type
}}} // namespaces
`real_concept` is an archetype for
[link math_toolkit.concepts user defined real types],
[link math_toolkit.real_concepts user defined real types],
it declares its standard library functions in its own
namespace: these will only be found if they are called unqualified
allowing argument dependent lookup to locate them. In addition
@@ -566,7 +565,7 @@ this type is useable at runtime:
this allows code that would not otherwise be exercised by the built-in
floating point types to be tested. There is no std::numeric_limits<>
support for this type, since numeric_limits is not a conceptual requirement
for [link math_toolkit.concepts RealType]s.
for [link math_toolkit.real_concepts RealType]s.
NTL RR is an example of a type meeting the requirements that this type
models, but note that use of a thin wrapper class is required: refer to
@@ -576,7 +575,7 @@ There is no specific test case for type `real_concept`, instead, since this
type is usable at runtime, each individual test case as well as testing
`float`, `double` and `long double`, also tests `real_concept`.
[h6 Distribution Concept]
[h6:distribution_concept Distribution Concept]
Distribution Concept models statistical distributions.

View File

@@ -30,7 +30,7 @@ with a tolerance provided by the user.
Some background reading is:
* Knuth D.E. The art of computer programming, vol II, section 4.2, especially Floating-Point_Comparison 4.2.2, pages 198-220.
* Knuth D.E. The art of computer programming, vol II, section 4.2, especially Floating-Point Comparison 4.2.2, pages 198-220.
* [@http://adtmag.com/articles/2000/03/16/comparing-floatshow-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been-r.aspx
Alberto Squassabia, Comparing floats listing]
* [@http://adtmag.com/articles/2000/03/16/comparing-floats-how-to-determine-if-floating-quantities-are-close-enough-once-a-tolerance-has-been.aspx

130
doc/math.css Normal file
View File

@@ -0,0 +1,130 @@
@import url('../../../../doc/src/boostbook.css');
/*=============================================================================
Copyright (c) 2004 Joel de Guzman
Copyright (c) 2014 John Maddock
http://spirit.sourceforge.net/
Copyright 2013 Niall Douglas additions for colors and alignment.
Copyright 2013 Paul A. Bristow additions for more colors and alignments.
Distributed under the Boost Software License, Version 1.0. (See accompany-
ing file LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
=============================================================================*/
/*=============================================================================
Program listings
=============================================================================*/
/* Code on paragraphs */
p tt.computeroutput
{
font-size: 10pt;
}
pre.synopsis
{
font-size: 10pt;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
.programlisting,
.screen
{
font-size: 10pt;
display: block;
margin: 1pc 4% 0pc 4%;
padding: 0.5pc 0.5pc 0.5pc 0.5pc;
}
@media screen
{
/* Syntax Highlighting */
.comment { color: green; }
/* .comment { color: #008000; } */
}
/* Program listings in tables don't get borders */
td .programlisting,
td .screen
{
margin: 0pc 0pc 0pc 0pc;
padding: 0pc 0pc 0pc 0pc;
}
/*=============================================================================
Table of contents
=============================================================================*/
div.toc
{
margin: 1pc 4% 0pc 4%;
padding: 0.1pc 1pc 0.1pc 1pc;
font-size: 100%;
line-height: 1.15;
}
.boost-toc
{
float: right;
padding: 0.5pc;
}
/* Code on toc */
.toc .computeroutput { font-size: 120% }
/* No margin on nested menus */
.toc dl dl { margin: 0; }
/*==============================================================================
Alignment and coloring use 'role' feature, available from Quickbook 1.6 up.
Added from Niall Douglas for role color and alignment.
http://article.gmane.org/gmane.comp.lib.boost.devel/243318
*/
/* Add text alignment (see http://www.w3schools.com/cssref/pr_text_text-align.asp) */
span.aligncenter
{
display: inline-block; width: 100%; text-align: center;
}
span.alignright
{
display: inline-block; width: 100%; text-align: right;
}
/* alignleft is the default. */
span.alignleft
{
display: inline-block; width: 100%; text-align: left;
}
/* alignjustify stretches the word spacing so that each line has equal width
within a chosen fraction of page width (here arbitrarily 20%).
*Not* useful inside table items as the column width remains the total string width.
Nor very useful, except to temporarily restrict the width.
*/
span.alignjustify
{
display: inline-block; width: 20%; text-align: justify;
}
/* Text colors.
Names at http://www.w3.org/TR/2002/WD-css3-color-20020219/ 4.3. X11 color keywords.
Quickbook Usage: [role red Some red text]
*/
span.red { inline-block; color: red; }
span.green { color: green; }
span.lime { color: #00FF00; }
span.blue { color: blue; }
span.navy { color: navy; }
span.yellow { color: yellow; }
span.magenta { color: magenta; }
span.indigo { color: #4B0082; }
span.cyan { color: cyan; }
span.purple { color: purple; }
span.gold { color: gold; }
span.silver { color: silver; } /* lighter gray */
span.gray { color: #808080; } /* light gray */

View File

@@ -64,6 +64,11 @@
[def __nearequal '''&#x224A;''']
[def __spaces '''&#x2000;&#x2000;'''] [/ two spaces - useful for an indent.]
[def __tick [role aligncenter [role green \u2714]]] [/ u2714 is a HEAVY CHECK MARK tick (2713 check
mark)]
[def __cross [role aligncenter [role red \u2718]]] [/ u2718 is a heavy cross]
[def __star [role aligncenter [role red \u2736]]] [/ 6-point star]
[def __caution This is now an official Boost library, but remains a library under
development, the code is fully functional and robust, but
interfaces, library structure, and function and distribution names
@@ -122,7 +127,6 @@ and use the function's name as the link text.]
[def __fifth_root [link math_toolkit.roots.root_finding_examples.fifth_root fifth root]]
[def __nth_root [link math_toolkit.roots.root_finding_examples.nth_root nth root]]
[def __multiprecision_root [link math_toolkit.roots.root_finding_examples.multiprecision_root multiprecision root]]
[/gammas]
[def __lgamma [link math_toolkit.sf_gamma.lgamma lgamma]]
[def __digamma [link math_toolkit.sf_gamma.digamma digamma]]
@@ -275,6 +279,7 @@ and use the function's name as the link text.]
[/tools]
[def __tuple [link math_toolkit.internals.tuples boost::math::tuple]]
[def __tuple_type [link math_toolkit.internals.tuples std::pair, std::tuple, or boost::math::tuple]]
[/ distribution non-members]
[def __cdf [link math_toolkit.dist_ref.nmp.cdf Cumulative Distribution Function]]
@@ -352,6 +357,10 @@ and use the function's name as the link text.]
__chf, __mean, __median, __mode, __variance, __sd, __skewness,
__kurtosis, __kurtosis_excess, __range and __support]
[def __real_concept [link math_toolkit.real_concepts real concept]]
[def __next_float [link math_toolkit.next_float Adjacent Floating-Point Values]]
[/ External links]
[def __gsl [@http://www.gnu.org/software/gsl/ GSL-1.9]]
[def __glibc [@http://www.gnu.org/software/libc/ GNU C Lib]]
[def __hpc [@http://docs.hp.com/en/B9106-90010/index.html HP-UX C Library]]
@@ -365,8 +374,10 @@ and use the function's name as the link text.]
[def __cpp_dec_float [@boost:/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_dec_float.html cpp_dec_float]]
[def __cpp_bin_float [@boost:/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/cpp_bin_float.html cpp_bin_float]]
[def __boost_test [@boost:/libs/test/doc/html/index.html Boost.Test]]
[def __boost_timer [@boost:/libs/timer/doc/index.html Boost.Timer]]
[def __boost_test_fp [@boost:/libs/test/doc/html/boost_test/users_guide/testing_tools/testing_floating_points.html Boost.Test floating-point comparison]]
[def __boost_math_fp [link math_toolkit.float_comparison Boost.Math floating-point utilities]]
[def __float_distance [@boost:/libs/math/doc/html/math_toolkit/next_float/float_distance.html Boost.Math float_distance]]
[def __ulp [@http://en.wikipedia.org/wiki/Unit_in_the_last_place Unit in the last place (ULP)]]
[def __R [@http://www.r-project.org/ The R Project for Statistical Computing]]
[def __godfrey [link godfrey Godfrey]]
@@ -388,6 +399,11 @@ and use the function's name as the link text.]
[def __floating_point [@http://en.wikipedia.org/wiki/Floating_point Floating point]]
[def __epsilon [@http://en.wikipedia.org/wiki/Machine_epsilon machine epsilon]]
[def __ADL [@http://en.cppreference.com/w/cpp/language/adl Argument Dependent Lookup (ADL)]]
[def __function_template_instantiation [@http://en.cppreference.com/w/cpp/language/function_template Function template instantiation]]
[def __fundamental_types [@http://en.cppreference.com/w/cpp/language/types fundamental]]
[def __guard_digits [@http://en.wikipedia.org/wiki/Guard_digit guard digits]]
[def __SSE2 [@http://en.wikipedia.org/wiki/SSE2 SSE2 instructions]]
[def __representable [@http://en.wikipedia.org/wiki/Floating_point#Representable_numbers.2C_conversion_and_rounding representable]]
[/ Some composite templates]
[template super[x]'''<superscript>'''[x]'''</superscript>''']

View File

@@ -23,8 +23,8 @@ These two functions locate the minima of the continuous function ['f] using
[*Parameters]
[variablelist
[[F] [class of functor]]
[[T] [floating-point type for computation and result]]
[[F] [class of functor.]]
[[T] [floating-point type for computation and result.]]
[[f] [The function to minimise a function object (functor) that should be smooth over the
range ['\[min, max\]], with no maxima occurring in that interval.]]
[[min] [The lower endpoint of the range in which to search for the minima.]]
@@ -88,7 +88,7 @@ so choosing a tight min-max range is good.]
For simplicity, we set the precision parameter `bits` to `std::numeric_limits<double>::digits`,
which is effectively the maximum possible `std::numeric_limits<double>::digits`/2.
Nor do we provide a maximum iterations parameter `max_iter`,
so the function will iterate until it finds a minimum.
(perhaps unwidely), so the function will iterate until it finds a minimum.
[brent_minimise_double_1]
@@ -152,7 +152,7 @@ that we reduce the number of iterations from 10 to 7 and the result significantl
Showing 13 bits precision with 9 decimal digits from tolerance 0.015625
x at minimum = 0.9999776, f(0.9999776) = 2.0069572e-009 after 7 iterations.
[h5:template Templated on floating-point type]
[h5:template Templating on floating-point type]
If we want to switch the floating-point type, then the functor must be revised.
@@ -185,6 +185,8 @@ For this optional include, the build should define the macro BOOST_HAVE_QUADMATH
[brent_minimise_mp_include_1]
or
[brent_minimise_template_quad]
[h5:multiprecision Multiprecision]
@@ -209,9 +211,9 @@ and with our show function
[brent_minimise_mp_output_2]
[tip One can usually rely on __ADL
[tip One can usually rely on __function_template_instantiation
to avoid specifying the verbose multiprecision types,
but some care in needed with the ['type of the values] provided
but great care in needed with the ['type of the values] provided
to avoid confusing the compiler.
]
@@ -226,7 +228,9 @@ The complete example code is at [@../../example/brent_minimise_example.cpp brent
[h4 Implementation]
This is a reasonably faithful implementation of Brent's algorithm, refer to:
This is a reasonably faithful implementation of Brent's algorithm.
[h4 References]
# Brent, R.P. 1973, Algorithms for Minimization without Derivatives,
(Englewood Cliffs, NJ: Prentice-Hall), Chapter 5.

View File

@@ -0,0 +1,182 @@
[/
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[section:root_comparison Comparison of Root Finding Algorithms]
[section:cbrt_comparison Comparison of Cube Root Finding Algorithms]
In the table below, the cube root of 28 was computed 10000 for three __fundamental_types floating-point types,
and one __multiprecision type __cpp_bin_float using 50 decimal digit precision, using four algorithms.
The 'exact' answer was computed using a 100 decimal digit type:
cpp_bin_float_100 full_answer ("3.036588971875662519420809578505669635581453977248111123242141654169177268411884961770250390838097895");
Times were measured using __boost_timer using `class cpu_timer`.
* ['Its] is the number of iterations.
* ['Times] is the CPU time-taken in arbitrary units.
* ['Norm] is a normalized time, in comparison to the quickest algorithm (with value 1.00).
* ['Dis] is the distance from the nearest representation of the 'exact' root in bits.
Distance from the 'exact' answer is measured by using function __float_distance.
One or two bits distance means that all results are effectively 'correct'.
Zero means 'exact' - the nearest __representable value for the floating-point type.
The cube-root function is a simple function, and is a contrived example for root-finding.
It does allow us to investigate some of the factors controlling efficiency that may be extrapolated to
more complex functions.
The program used was [@ ../../example/root_finding_algorithms.cpp root_finding_algorithms.cpp].
100000 evaluations of each floating-point type and algorithm were used and the CPU times were
judged from repeat runs to have an uncertainty of 10 %. Comparing MSVC for `double` and `long double`
(which are identical on this patform) may give a guide to uncertainty of timing.
* The C++ Standard cube root function [@http://en.cppreference.com/w/cpp/numeric/math/cbrt std::cbrt]
is only defined for built-in or fundamental types,
so cannot be used with any User-Defined floating-point types like __multiprecision.
This, and that the cube function is so impeccably-behaved,
allows the implementer to use many tricks to achieve a fast computation.
On some platforms,`std::cbrt` appeared several times as quick as the more general `boost::math::cbrt`,
but results were highly dependent on hardware, compiler and options, 32 or 64-bit and platform.
* Two compilers in optimise mode were compared: GCC 4.9.1 using Netbeans IDS
and Microsoft Visual Studio 2013 (Update 1) on the same hardware.
The number of iterations seemed consistent, but the relative run-times surprisingly different.
* `boost::math::cbrt` allows use with ['any user-defined floating-point type], conveniently
__multiprecision. It too can take some advantage of the good-behaviour of the cube function,
compared to the more general implementation in the nth root-finding examples. For example,
it uses a polynomial to generate a better guess than dividing the exponent by three,
and can avoid the complex checks in __newton required to prevent the
search going wildly off-track. For a known precision, it may also be possible to
fix the number of iterations, allowing inlining. Typically, it was found that computation using type `double`
took a few times longer when using the various root-finding algorithms directly.
* The importance of getting a good guess can be shown by using the `std::pow(x, 1.L/3)` function call
to obtain a `double` or `long double` 15 decimal-digit precision guess at cube-root
(much closer than the simple divide-exponent-by-3 method to get a 'guess').
Using Halley's algorithm, it only took [*a single iteration] to achieve 50 decimal-digit precision.
The limitation of this tatic is that the range of possible (exponent) values may be less than the multiprecision type.
* Using type `float` and __TOMS748, a few less iterations were required, but the time the same as Newton-Raphson.
* For __fundamental_types, there was little to choose between the three derivative methods,
but for __cpp_bin_float, __newton was twice as fast.
* Compiling with optimisation halved computation times, and any differences between algorithms
became nearly negligible. The optimisation speed-up of the __TOMS748 was especially noticable.
* Using a multiprecision type like `cpp_bin_float_50` for a precision of 50 decimal digits
took a lot longer, as expected because most computation
uses software rather than 64-bit floating-point hardware.
Speeds are often more than 50 times slower.
* Using `cpp_bin_float_50`, __TOMS748 was much slower showing the benefit of using derivatives.
__newton was found to be twice as quick as either of the second-derivative methods:
this must reflect the computational cost of calculating and using the extra derivatives
versus saving one or two iterations.
* Only one or two extra ['iterations] are needed to get the remaining 35 digits, whatever the algorithm used.
(The time taken was of course much greater for __multiprecision types).
* Using a 100 decimal-digit type only doubled the time and required only a very few more iterations,
so the cost of extra precision is mainly the underlying cost of computing more digits,
not in the way the algorithm works. This confirms previous observations using __NTL high-precision types.
* Experiment suggests that decreasing the number of bits of accuracy required from the maximum possible,
for example, to 3/4, does not decrease the accuracy as measured by the floating-point distances:
they remain essentially 'right'.
This suggests that requiring the maximum-possible accuracy means that an extra unproductive iteration may take place.
[include root_comparison_tables_gcc_075.qbk]
[include root_comparison_tables_msvc_075.qbk]
[include root_comparison_tables_gcc.qbk]
[include root_comparison_tables_msvc.qbk]
[endsect] [/section:cbrt_comparison Comparison of Cube Root Finding Algorithms]
[section:root_n_comparison Comparison of Nth-root Finding Algorithms]
A second example compares four generalized nth-root finding algorithms for various n-th roots (5, 7 and 13)
of a single value 28.0, for four floating-point types, `float`, `double`,
`long double` and a __multiprecision type __cpp_bin_float_50
and required all and only three-quarters available digits of accuracy.
Tests used Microsoft Visual Studio 2013 (Update 1) and GCC 4.9.1 using source code
[@../../example/root_n_finding_algorithms.cpp root_n_finding_algorithms.cpp].
The timing uncertainty (especially using MSVC) is at least 5% of normalized time 'Norm'.
To pick out the 'best' and 'worst' algorithms are highlighted in blue and red.
More than one result can be 'best' when normalized times are indistinguishable
within the uncertainty.
[/include roots_table_100_msvc.qbk]
[/include roots_table_75_msvc.qbk]
[include roots_table_75_msvc_X86.qbk]
[include roots_table_100_msvc_X86.qbk]
[/include roots_table_100_msvc_AVX.qbk]
[/include roots_table_75_msvc_AVX.qbk]
[include roots_table_75_msvc_X86_SSE2.qbk]
[include roots_table_100_msvc_X86_SSE2.qbk]
[include roots_table_100_gcc_X64_SSE2.qbk]
[include roots_table_75_gcc_X64_SSE2.qbk]
[include type_info_table_100_msvc.qbk]
[include type_info_table_75_msvc.qbk]
Some tentative conclusions can be drawn from this limited exercise.
* Perhaps surprisingly, there is little difference between the various algorithms for __fundamental_types floating-point types.
Using the first derivatives (__newton) is usually the best, but the improvement over the no-derivative
__TOMS748 is considerable in number of iterations, but little in execution time.
* The extra cost of evaluating the second derivatives (__halley or __schroeder) is usually too much for any net benefit.
* __halley usually seems better than __schroeder, but for no obvious reason.
* For a __multiprecision floating-point type, the __newton is a clear winner with a several-fold gain over __TOMS748,
and again no improvement from the second-derivative algorithms.
* The run-time of 50 decimal-digit __multiprecision is about 30-fold greater than `double`.
* The column 'dis' showing the number of bits distance from the correct result.
The Newton-Raphson algorithm shows a bit or two better accuracy than __TOMS748.
Multiprecision types have a number of __guard_digits and usually get exactly correct results.
* The goodness of the 'guess' is especially crucial for __multiprecision.
Separate experiments show that evaluating the 'guess' using `double` allows
convergence to the final exact result in one or two iterations.
So in this contrived example, crudely dividing the exponent by N for a 'guess',
it would be far better to use a `pow<double>` or ,
if more precise `pow<long double>`, function to estimate a 'guess'.
The limitation of this tatic is that the range of possible (exponent) values may be less than the multiprecision type.
* Reducing the number of bits of accuracy to three-quarters required,
only reduced the time several percent, and the accuracy barely at all.
* Using floating-point extension __SSE2 made a modest ten-percent speedup.
*Using MSVC, there was some improvement using 64-bit, markedly for __multiprecision.
* The GCC compiler 4.9.1 using 64-bit was at least five-folder faster,
apparently reflecting better optimization.
Clearly, your mileage [*will vary], but in summary, __newton seems the first choice of algorithm,
and effort to find a good 'guess' the first speed-up target, especially for __multiprecision.
And of course, compiler optimisation is crucial for speed.
[endsect] [/section:root_n_comparison Comparison of Nth-root Finding Algorithms]
[endsect] [/section:root_comparison Comparison of Root Finding Algorithms]

View File

@@ -0,0 +1,27 @@
[/
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h5 Program i:/modular-boost/libs/math/example/root_finding_algorithms.cpp, GNU C++ version 4.9.1, GNU libstdc++ version 20140716, Win32, Compiled in optimise mode.[br]1000000 evaluations of each of 5 root_finding algorithms.[br]Fraction of maximum possible bits of accuracy required is 1]
[table:cbrt_5 Info for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][24]]
[[double][17][53][53]]
[[long double][21][64][64]]
[[cpp_bin_float_50][52][168][168]]
] [/table cbrt_5]
[table:cbrt_4 Cube root(28) for float, double, long double and cpp_bin_float_50
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algorithm][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[cbrt ][ 0][46875][1.0][ 0][ ][ 0][140625][1.0][ 0][ ][ 0][109375][1.0][ 0][ ][ 0][3906250][1.0][ 0][ ]]
[[TOMS748 ][ 8][296875][6.3][ -1][ ][ 11][500000][3.6][ 2][ ][ 10][1828125][17.][ -1][ ][ 7][53562500][14.][ -2][ ]]
[[Newton ][ 6][140625][3.0][ 0][ ][ 7][156250][1.1][ 0][ ][ 8][531250][4.9][ -1][ ][ 9][12625000][3.2][ -1][ ]]
[[Halley ][ 4][156250][3.3][ 0][ ][ 5][187500][1.3][ 0][ ][ 5][671875][6.1][ -1][ ][ 6][20625000][5.3][ 0][ ]]
[[Schroeder][ 5][156250][3.3][ 0][ ][ 6][203125][1.4][ 0][ ][ 6][734375][6.7][ 0][ ][ 7][22656250][5.8][ 0][ ]]
] [/end of table cbrt_4]

View File

@@ -0,0 +1,27 @@
[/
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h5 Program i:/modular-boost/libs/math/example/root_finding_algorithms.cpp, GNU C++ version 4.9.1, GNU libstdc++ version 20140716, Win32, [br]1000000 evaluations of each of 5 root_finding algorithms.[br]Fraction of maximum possible bits of accuracy required is 0.75]
[table:cbrt_5 Info for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][18]]
[[double][17][53][39]]
[[long double][21][64][48]]
[[cpp_bin_float_50][52][168][126]]
] [/table cbrt_5]
[table:cbrt_4 Cube root(28) for float, double, long double and cpp_bin_float_50
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algorithm][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[cbrt ][ 0][187500][1.0][ 0][ ][ 0][390625][1.0][ 0][ ][ 0][406250][1.0][ 0][ ][ 0][25468750][1.0][ 0][ ]]
[[TOMS748 ][ 8][1343750][7.2][ -1][ ][ 11][2140625][5.5][ 2][ ][ 10][4796875][12.][ -1][ ][ 7][300296875][12.][ -2][ ]]
[[Newton ][ 6][562500][3.0][ 0][ ][ 7][578125][1.5][ 0][ ][ 7][1703125][4.2][ 0][ ][ 9][71203125][2.8][ -1][ ]]
[[Halley ][ 4][765625][4.1][ 0][ ][ 4][703125][1.8][ 0][ ][ 5][1750000][4.3][ -1][ ][ 5][95140625][3.7][ 0][ ]]
[[Schroeder][ 5][875000][4.7][ 0][ ][ 5][828125][2.1][ 0][ ][ 6][2046875][5.0][ 0][ ][ 7][122906250][4.8][ 0][ ]]
] [/end of table cbrt_4]

View File

@@ -0,0 +1,27 @@
[/
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h5 Program I:\modular-boost\libs\math\example\root_finding_algorithms.cpp, Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32, Compiled in optimise mode.[br]1000000 evaluations of each of 5 root_finding algorithms.[br]Fraction of maximum possible bits of accuracy required is 1]
[table:cbrt_5 Info for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][24]]
[[double][17][53][53]]
[[long double][17][53][53]]
[[cpp_bin_float_50][52][168][168]]
] [/table cbrt_5]
[table:cbrt_4 Cube root(28) for float, double, long double and cpp_bin_float_50
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algorithm][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[cbrt ][ 0][203125][1.0][ 0][ ][ 0][203125][1.0][ 1][ ][ 0][203125][1.0][ 1][ ][ 0][9312500][1.0][ 0][ ]]
[[TOMS748 ][ 8][859375][4.2][ -1][ ][ 11][1109375][5.5][ 2][ ][ 11][1140625][5.6][ 2][ ][ 7][130703125][14.][ -2][ ]]
[[Newton ][ 6][1062500][5.2][ 0][ ][ 7][1015625][5.0][ 0][ ][ 7][1031250][5.1][ 0][ ][ 9][33640625][3.6][ -1][ ]]
[[Halley ][ 4][1046875][5.2][ 0][ ][ 5][1093750][5.4][ 0][ ][ 5][1078125][5.3][ 0][ ][ 6][60750000][6.5][ 0][ ]]
[[Schroeder][ 5][1078125][5.3][ 0][ ][ 6][1078125][5.3][ 0][ ][ 6][1062500][5.2][ 0][ ][ 7][64343750][6.9][ 0][ ]]
] [/end of table cbrt_4]

View File

@@ -0,0 +1,27 @@
[/
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h5 Program I:\modular-boost\libs\math\example\root_finding_algorithms.cpp, Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32, Compiled in optimise mode.[br]1000000 evaluations of each of 5 root_finding algorithms.[br]Fraction of maximum possible bits of accuracy required is 0.75]
[table:cbrt_5 Info for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][18]]
[[double][17][53][39]]
[[long double][17][53][39]]
[[cpp_bin_float_50][52][168][126]]
] [/table cbrt_5]
[table:cbrt_4 Cube root(28) for float, double, long double and cpp_bin_float_50
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algorithm][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[cbrt ][ 0][203125][1.0][ 0][ ][ 0][187500][1.0][ 1][ ][ 0][187500][1.0][ 1][ ][ 0][8796875][1.0][ 0][ ]]
[[TOMS748 ][ 8][812500][4.0][ -1][ ][ 11][1031250][5.5][ 2][ ][ 11][1093750][5.8][ 2][ ][ 7][126125000][14.][ -2][ ]]
[[Newton ][ 6][968750][4.8][ 0][ ][ 7][968750][5.2][ 0][ ][ 7][1015625][5.4][ 0][ ][ 9][30421875][3.5][ -1][ ]]
[[Halley ][ 4][984375][4.8][ 0][ ][ 4][1046875][5.6][ 0][ ][ 4][1078125][5.8][ 0][ ][ 5][47453125][5.4][ 0][ ]]
[[Schroeder][ 5][968750][4.8][ 0][ ][ 5][1031250][5.5][ 0][ ][ 5][1000000][5.3][ 0][ ][ 7][59140625][6.7][ 0][ ]]
] [/end of table cbrt_4]

View File

@@ -45,7 +45,7 @@ __spaces ['f(x) = x[cubed] -a]
We will first solve this without using any information
about the slope or curvature of the cube root function.
Fortunately, the cube root function is 'Really Well Behaved' in that it is monotonic
Fortunately, the cube-root function is 'Really Well Behaved' in that it is monotonic
and has only one root (we leave negative values 'as an exercise for the student').
We then show how adding what we can know about this function, first just the slope
@@ -59,10 +59,10 @@ First we define a function object (functor):
[root_finding_noderiv_1]
Implementing the cube root function itself is fairly trivial now:
Implementing the cube-root function itself is fairly trivial now:
the hardest part is finding a good approximation to begin with.
In this case we'll just divide the exponent by three.
(There are better but more complex guess algorithms used in 'real-life'.)
(There are better but more complex guess algorithms used in 'real life'.)
[root_finding_noderiv_2]
@@ -80,7 +80,7 @@ The result of `bracket_and_solve_root` is a [@http://www.cplusplus.com/reference
of values that could be displayed.
Tthe number of bits separating them can be found using `float_distance(r.first, r.second)`.
The distance is zero (ideal) for 3[super 3] = 27
The distance is zero (closest representable) for 3[super 3] = 27
but `float_distance(r.first, r.second) = 3` for cube root of 28 with this function.
The result (avoiding overflow) is midway between these two values.
@@ -94,7 +94,7 @@ For the root function, the 1st differential (the slope of the tangent to a curve
This algorithm is similar to this [@http://en.wikipedia.org/wiki/Nth_root_algorithm nth root algorithm].
If you need some reminders, then
[@http://en.wikipedia.org/wiki/Derivative#Derivatives_of_elementary_functions Derivatives of elementary functions]
[@http://en.wikipedia.org/wiki/Derivative#Derivatives_of_elementary_functions derivatives of elementary functions]
may help.
Using the rule that the derivative of ['x[super n]] for positive n (actually all nonzero n) is ['n x[super n-1]],
@@ -242,7 +242,7 @@ The apocryphally astute reader might, by now, be asking "How do we know if this
For most values, there is, sadly, no 'right' answer.
This is because values can only rarely be ['exactly represented] by C++ floating-point types.
What we do want is the 'rightest' representation - one that is the nearest representable value.
What we do want is the 'best' representation - one that is the nearest __representable value.
(For more about how numbers are represented see __floating_point).
Of course, we might start with finding an external reference source like
@@ -276,7 +276,7 @@ at least `max_digits10` decimal digits (17 for 64-bit `double`).
If we wish to compute [*higher-precision values] then, on some platforms, we may be able to use `long double`
with a higher precision than `double` to compare with the very common `double`
and/or a more efficient built-in quad floating-point type like __float128.
and/or a more efficient built-in quad floating-point type like `__float128`.
Almost all platforms can easily use __multiprecision,
for example, __cpp_dec_float or a binary type __cpp_bin_float types,
@@ -297,7 +297,7 @@ that we can use with these includes:
[root_finding_multiprecision_include_1]
Some using statements simply their use:
Some using statements simplify their use:
[root_finding_multiprecision_example_1]
@@ -338,7 +338,7 @@ used to compute the guess and bracket values as `double`.
Even more treacherous is passing a `double` as in `cpp_dec_float_50 r = cbrt_2deriv(2.);`
which silently gives the 'wrong' result, computing a `double` result and [*then] converting to `cpp_dec_float_50`!
All digits beyond `max_digits10` will be incorrect.
Making the `cbrt` type explicit with `cbrt_2deriv<cpp_dec_float_50>(2.);` will give you the desired 5o decimal digit precision result.
Making the `cbrt` type explicit with `cbrt_2deriv<cpp_dec_float_50>(2.);` will give you the desired 50 decimal digit precision result.
] [/tip]
[h3:nth_root Generalizing to Compute the nth root]
@@ -349,7 +349,7 @@ where template parameter `N` is an integer. Our functor and function now have a
for the root required.
[note Since this is a compile-time static process, the resulting code is as efficient as as if hand-coded as the cube and fifth-root examples above.
The compiler should also optimise any repeated multiplications.]
A good compiler should also optimise any repeated multiplications.]
Our ['n]th root functor is

View File

@@ -0,0 +1,30 @@
[/
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode.
Fraction of maximum possible bits of accuracy required is 0.75
[table:cbrt_5 Info for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][18]]
[[double][17][53][39]]
[[long double][17][53][39]]
] [/table cbrt_5]
[table:cbrt_4 Cube root(28) for float, double, long double and cpp_bin_float_50
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[cbrt ][ 0][ 156][1.00][ 0][ ][ 0][ 156][1.00][ 1][ ][ 0][ 156][1.00][ 1][ ]]
[[TOMS748 ][ 8][ 781][5.01][ -1][ ][ 11][ 1093][7.01][ 2][ ][ 11][ 1093][7.01][ 2][ ]]
[[Newton ][ 6][ 1093][7.01][ 0][ ][ 7][ 1093][7.01][ 0][ ][ 7][ 937][6.01][ 0][ ]]
[[Halley ][ 4][ 1093][7.01][ 0][ ][ 4][ 937][6.01][ 0][ ][ 4][ 937][6.01][ 0][ ]]
[[Schroeder][ 5][ 1093][7.01][ 0][ ][ 5][ 1093][7.01][ 0][ ][ 5][ 1093][7.01][ 0][ ]]
] [/end of table cbrt_4]

View File

@@ -44,7 +44,7 @@ The functions all take the same parameters:
[variablelist Parameters of the root finding functions
[[F f] [Type F must be a callable function object that accepts one parameter and
returns a __tuple:
returns a __tuple_type:
For second-order iterative method ([@http://en.wikipedia.org/wiki/Newton_Raphson Newton Raphson])
the __tuple should have [*two] elements containing the evaluation
@@ -53,15 +53,15 @@ For second-order iterative method ([@http://en.wikipedia.org/wiki/Newton_Raphson
For the third-order methods
([@http://en.wikipedia.org/wiki/Halley%27s_method Halley] and
Schroeder)
the __tuple should have *three* elements containing the evaluation of
the `tuple` should have [*three*] elements containing the evaluation of
the function and its first and second derivatives.]]
[[T guess] [The initial starting value. A good guess is crucial to quick convergence!]]
[[T min] [The minimum possible value for the result, this is used as an initial lower bracket.]]
[[T max] [The maximum possible value for the result, this is used as an initial upper bracket.]]
[[int digits] [The desired number of binary digits precision.]]
[[uintmax_t& max_iter] [An optional maximum number of iterations to perform. On exit, this is updated to the actual number of iterations performed.]]
[[T] [Floating-point type, typically `double`, often deduced by __ADL.]]
[[F] [Floating-point types of the functor, usually deduced from T by __ADL, so it is rarely necessary to define F.]]
[[T] [Floating-point type, typically `double`, ]]
[[F] [Unary Functor that returns any suitable floating-point type T. ]]
]
When using these functions you should note that:

View File

@@ -14,12 +14,12 @@ There are several fully-worked __root_finding_examples, including:
* __root_finding_example_cbrt_without_derivatives
* __root_finding_example_cbrt_with_1_derivative
* __root_finding_example_cbrt_with_2_derivatives
* __brent_minima for a simple function.
[include roots_without_derivatives.qbk]
[include roots.qbk]
[include root_finding_examples.qbk]
[include minima.qbk]
[include root_comparison.qbk]
[/ roots_overview.qbk
Copyright 2015 John Maddock and Paul A. Bristow.

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_100_gcc_SEE SEE2 X64 .qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program i:/modular-boost/libs/math/example/root_n_finding_algorithms.cpp,
GNU C++ version 4.9.1, GNU libstdc++ version 20140716, Win32
Compiled in optimise mode.]
Fraction of full accuracy 1
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types.
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 296][2.72][ 0][ ][ 11][ 500][3.57][ 1][ ][ 9][ 1593][4.25][ 0][ ][ 12][74953][7.01][ 0][ ]]
[[Newton ][ 3][ 109][1.00][ 0][ ][ 5][ 140][1.00][ -1][ ][ 4][ 375][1.00][ 0][ ][ 6][10687][1.00][ 0][ ]]
[[Halley ][ 2][ 109][1.00][ 0][ ][ 4][ 171][1.22][ 0][ ][ 3][ 453][1.21][ 0][ ][ 4][17578][1.64][ 0][ ]]
[[Schroeder][ 6][ 203][1.86][ 0][ ][ 8][ 250][1.79][ -1][ ][ 7][ 609][1.62][ 0][ ][ 8][33546][3.14][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types.
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 500][3.21][ 1][ ][ 15][ 687][4.40][ 2][ ][ 13][ 2390][5.11][ 0][ ][ 14][99765][5.95][ 0][ ]]
[[Newton ][ 6][ 156][1.00][ 0][ ][ 7][ 156][1.00][ 0][ ][ 6][ 468][1.00][ 0][ ][ 8][16765][1.00][ 0][ ]]
[[Halley ][ 5][ 187][1.20][ 0][ ][ 6][ 218][1.40][ 0][ ][ 5][ 796][1.70][ 0][ ][ 6][29250][1.74][ 0][ ]]
[[Schroeder][ 6][ 203][1.30][ 0][ ][ 6][ 234][1.50][ 0][ ][ 6][ 531][1.13][ 0][ ][ 7][30687][1.83][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types.
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 593][3.47][ -2][ ][ 14][ 734][3.93][ 2][ ][ 14][ 2750][5.18][ 1][ ][ 17][155921][7.06][ 2][ ]]
[[Newton ][ 7][ 171][1.00][ 0][ ][ 8][ 187][1.00][ 0][ ][ 8][ 531][1.00][ 0][ ][ 10][22093][1.00][ 0][ ]]
[[Halley ][ 5][ 187][1.09][ 0][ ][ 6][ 234][1.25][ 0][ ][ 6][ 703][1.32][ 0][ ][ 7][36375][1.65][ 0][ ]]
[[Schroeder][ 7][ 234][1.37][ 0][ ][ 7][ 250][1.34][ 0][ ][ 8][ 625][1.18][ 0][ ][ 8][37843][1.71][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_100_gcc_X64_SSE2 _X64.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program i:/modular-boost/libs/math/example/root_n_finding_algorithms.cpp,
GNU C++ version 4.9.1, GNU libstdc++ version 20140716, Win32
Compiled in optimise mode., _X64_SSE2]
Fraction of full accuracy 1
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _X64_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 265][2.43][ 0][ ][ 11][ 468][3.34][ 1][ ][ 9][ 1531][4.08][ 0][ ][ 12][66937][[role red 6.66]][ 0][ ]]
[[Newton ][ 3][ 109][[role blue 1.00]][ 0][ ][ 5][ 140][[role blue 1.00]][ -1][ ][ 4][ 375][[role blue 1.00]][ 0][ ][ 6][10046][[role blue 1.00]][ 0][ ]]
[[Halley ][ 2][ 109][[role blue 1.00]][ 0][ ][ 4][ 171][[role blue 1.22]][ 0][ ][ 3][ 468][[role blue 1.25]][ 0][ ][ 4][16390][[role blue 1.63]][ 0][ ]]
[[Schroeder][ 6][ 203][[role blue 1.86]][ 0][ ][ 8][ 250][[role blue 1.79]][ -1][ ][ 7][ 593][[role blue 1.58]][ 0][ ][ 8][30890][3.07][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _X64_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 468][3.34][ 1][ ][ 15][ 671][3.92][ 2][ ][ 13][ 2359][[role red 5.21]][ 0][ ][ 14][89843][[role red 5.83]][ 0][ ]]
[[Newton ][ 6][ 140][[role blue 1.00]][ 0][ ][ 7][ 171][[role blue 1.00]][ 0][ ][ 6][ 453][[role blue 1.00]][ 0][ ][ 8][15421][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 187][[role blue 1.34]][ 0][ ][ 6][ 218][[role blue 1.27]][ 0][ ][ 5][ 718][[role blue 1.58]][ 0][ ][ 6][27937][[role blue 1.81]][ 0][ ]]
[[Schroeder][ 6][ 203][[role blue 1.45]][ 0][ ][ 6][ 203][[role blue 1.19]][ 0][ ][ 6][ 531][[role blue 1.17]][ 0][ ][ 7][28703][[role blue 1.86]][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _X64_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 562][3.29][ -2][ ][ 14][ 718][3.84][ 2][ ][ 14][ 2734][[role red 5.15]][ 1][ ][ 17][132031][[role red 6.77]][ 2][ ]]
[[Newton ][ 7][ 171][[role blue 1.00]][ 0][ ][ 8][ 187][[role blue 1.00]][ 0][ ][ 8][ 531][[role blue 1.00]][ 0][ ][ 10][19515][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 187][[role blue 1.09]][ 0][ ][ 6][ 218][[role blue 1.17]][ 0][ ][ 6][ 656][[role blue 1.24]][ 0][ ][ 7][32203][[role blue 1.65]][ 0][ ]]
[[Schroeder][ 7][ 234][[role blue 1.37]][ 0][ ][ 7][ 234][[role blue 1.25]][ 0][ ][ 8][ 625][[role blue 1.18]][ 0][ ][ 8][34187][[role blue 1.75]][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_100_msvc.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode.]
Fraction of full accuracy 1
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 750][[role blue 1.00]][ 0][ ][ 11][ 1015][1.08][ 1][ ][ 11][ 1000][1.03][ 1][ ][ 12][145687][[role red 6.07]][ 0][ ]]
[[Newton ][ 3][ 890][1.19][ 0][ ][ 5][ 937][[role blue 1.00]][ -1][ ][ 5][ 968][[role blue 1.00]][ -1][ ][ 6][24000][[role blue 1.00]][ 0][ ]]
[[Halley ][ 2][ 921][1.23][ 0][ ][ 4][ 953][[role blue 1.02]][ 0][ ][ 4][ 968][[role blue 1.00]][ 0][ ][ 4][41468][1.73][ 0][ ]]
[[Schroeder][ 6][ 984][1.31][ 0][ ][ 8][ 1062][1.13][ -1][ ][ 8][ 1046][1.08][ -1][ ][ 8][72062][3.00][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1015][1.07][ 1][ ][ 15][ 1218][1.22][ 2][ ][ 15][ 1218][1.24][ 2][ ][ 14][191937][[role red 5.43]][ 0][ ]]
[[Newton ][ 6][ 953][[role blue 1.00]][ 0][ ][ 7][ 1000][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 8][35359][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 984][1.03][ 0][ ][ 6][ 1031][1.03][ 0][ ][ 6][ 1015][1.03][ 0][ ][ 6][66968][1.89][ 0][ ]]
[[Schroeder][ 6][ 984][1.03][ 0][ ][ 6][ 1000][[role blue 1.00]][ 0][ ][ 6][ 1000][[role blue 1.02]][ 0][ ][ 7][67437][1.91][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1078][1.11][ -2][ ][ 14][ 1312][1.33][ 2][ ][ 14][ 1296][1.28][ 2][ ][ 17][294640][[role red 6.24]][ 2][ ]]
[[Newton ][ 7][ 968][[role blue 1.00]][ 0][ ][ 8][ 984][[role blue 1.00]][ 0][ ][ 8][ 1015][[role blue 1.00]][ 0][ ][ 10][47187][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1000][1.03][ 0][ ][ 6][ 1046][1.06][ 0][ ][ 6][ 1109][1.09][ 0][ ][ 7][79187][1.68][ 0][ ]]
[[Schroeder][ 7][ 1062][1.10][ 0][ ][ 7][ 1062][1.08][ 0][ ][ 7][ 1062][1.05][ 0][ ][ 8][78406][1.66][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_100_msvc_AVX.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode., _AVX]
Fraction of full accuracy 1
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _AVX
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 734][[role green 1.0000]1.00][ 0][ ][ 11][ 1015][1.06511.07][ 1][ ][ 11][ 1031][1.08181.08][ 1][ ][ 12][145968][[role red 5.8941]5.89][ 0][ ]]
[[Newton ][ 3][ 906][1.23431.23][ 0][ ][ 5][ 953][[role green 1.0000]1.00][ -1][ ][ 5][ 953][[role green 1.0000]1.00][ -1][ ][ 6][24765][[role green 1.0000]1.00][ 0][ ]]
[[Halley ][ 2][ 921][1.25481.25][ 0][ ][ 4][ 1015][1.06511.07][ 0][ ][ 4][ 1000][1.04931.05][ 0][ ][ 4][42156][1.70221.70][ 0][ ]]
[[Schroeder][ 6][ 1000][1.36241.36][ 0][ ][ 8][ 1062][1.11441.11][ -1][ ][ 8][ 1062][1.11441.11][ -1][ ][ 8][72500][2.92752.93][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _AVX
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 984][1.03251.03][ 1][ ][ 15][ 1234][1.25411.25][ 2][ ][ 15][ 1218][1.23781.24][ 2][ ][ 14][191484][[role red 5.3353]5.34][ 0][ ]]
[[Newton ][ 6][ 953][[role green 1.0000]1.00][ 0][ ][ 7][ 984][[role green 1.0000]1.00][ 0][ ][ 7][ 984][[role green 1.0000]1.00][ 0][ ][ 8][35890][[role green 1.0000]1.00][ 0][ ]]
[[Halley ][ 5][ 1000][1.04931.05][ 0][ ][ 6][ 1046][1.06301.06][ 0][ ][ 6][ 1046][1.06301.06][ 0][ ][ 6][66859][1.86291.86][ 0][ ]]
[[Schroeder][ 6][ 1015][1.06511.07][ 0][ ][ 6][ 1015][1.03151.03][ 0][ ][ 6][ 1000][[role green 1.0163]1.02][ 0][ ][ 7][68375][1.90511.91][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _AVX
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1078][1.09551.10][ -2][ ][ 14][ 1265][1.22701.23][ 2][ ][ 14][ 1265][1.22701.23][ 2][ ][ 17][288593][[role red 6.3844]6.38][ 2][ ]]
[[Newton ][ 7][ 984][[role green 1.0000]1.00][ 0][ ][ 8][ 1031][[role green 1.0000]1.00][ 0][ ][ 8][ 1031][[role green 1.0000]1.00][ 0][ ][ 10][45203][[role green 1.0000]1.00][ 0][ ]]
[[Halley ][ 5][ 1015][1.03151.03][ 0][ ][ 6][ 1078][1.04561.05][ 0][ ][ 6][ 1062][1.03011.03][ 0][ ][ 7][77625][1.71731.72][ 0][ ]]
[[Schroeder][ 7][ 1031][1.04781.05][ 0][ ][ 7][ 1046][[role green 1.0145]1.01][ 0][ ][ 7][ 1031][[role green 1.0000]1.00][ 0][ ][ 8][77718][1.71931.72][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_100_msvc_X86.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode., _X86]
Fraction of full accuracy 1
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 8][ 1109][1.08][ -2][ ][ 11][ 1265][1.29][ 1][ ][ 11][ 1203][1.22][ 1][ ][ 12][145453][[role red 5.95]][ 0][ ]]
[[Newton ][ 4][ 1031][[role blue 1.00]][ 0][ ][ 5][ 984][[role blue 1.00]][ -1][ ][ 5][ 984][[role blue 1.00]][ -1][ ][ 6][24453][[role blue 1.00]][ 0][ ]]
[[Halley ][ 3][ 1046][[role blue 1.01]][ 0][ ][ 4][ 1046][1.06][ 0][ ][ 4][ 1046][1.06][ 0][ ][ 4][40921][1.67][ 0][ ]]
[[Schroeder][ 7][ 1250][1.21][ 0][ ][ 8][ 1078][1.10][ -1][ ][ 8][ 1078][1.10][ -1][ ][ 8][70750][2.89][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1562][1.39][ 1][ ][ 15][ 1484][1.51][ 2][ ][ 15][ 1437][1.46][ 2][ ][ 14][188640][[role red 5.29]][ 0][ ]]
[[Newton ][ 6][ 1125][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 8][35640][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1156][[role blue 1.03]][ 0][ ][ 6][ 1125][1.14][ 0][ ][ 6][ 1109][1.13][ 0][ ][ 6][65218][1.83][ 0][ ]]
[[Schroeder][ 6][ 1187][1.06][ 0][ ][ 6][ 1031][[role blue 1.05]][ 0][ ][ 6][ 1015][[role blue 1.03]][ 0][ ][ 7][66828][1.88][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1812][1.49][ -2][ ][ 14][ 1531][1.48][ 2][ ][ 14][ 1500][1.43][ 2][ ][ 17][284937][[role red 6.38]][ 2][ ]]
[[Newton ][ 7][ 1218][[role blue 1.00]][ -1][ ][ 8][ 1031][[role blue 1.00]][ 0][ ][ 8][ 1046][[role blue 1.00]][ 0][ ][ 10][44640][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1265][[role blue 1.04]][ -1][ ][ 6][ 1156][1.12][ 0][ ][ 6][ 1140][1.09][ 0][ ][ 7][77843][1.74][ 0][ ]]
[[Schroeder][ 7][ 1343][1.10][ -1][ ][ 7][ 1046][[role blue 1.01]][ 0][ ][ 7][ 1109][1.06][ 0][ ][ 8][77343][1.73][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_100_msvc_X86_SSE2 .qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode., _X86_SSE2 ]
Fraction of full accuracy 1
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 765][[role blue 1.00]][ 0][ ][ 11][ 1046][1.10][ 1][ ][ 11][ 1015][[role blue 1.05]][ 1][ ][ 12][146437][[role red 5.98]][ 0][ ]]
[[Newton ][ 3][ 890][1.16][ 0][ ][ 5][ 953][[role blue 1.00]][ -1][ ][ 5][ 968][[role blue 1.00]][ -1][ ][ 6][24468][[role blue 1.00]][ 0][ ]]
[[Halley ][ 2][ 921][1.20][ 0][ ][ 4][ 968][[role blue 1.02]][ 0][ ][ 4][ 968][[role blue 1.00]][ 0][ ][ 4][42437][1.73][ 0][ ]]
[[Schroeder][ 6][ 1015][1.33][ 0][ ][ 8][ 1062][1.11][ -1][ ][ 8][ 1062][1.10][ -1][ ][ 8][74203][3.03][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 984][[role blue 1.02]][ 1][ ][ 15][ 1234][1.25][ 2][ ][ 15][ 1250][1.27][ 2][ ][ 14][193953][[role red 5.37]][ 0][ ]]
[[Newton ][ 6][ 968][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 8][36109][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 984][[role blue 1.02]][ 0][ ][ 6][ 1078][1.10][ 0][ ][ 6][ 1046][1.06][ 0][ ][ 6][67312][1.86][ 0][ ]]
[[Schroeder][ 6][ 1000][[role blue 1.03]][ 0][ ][ 6][ 1046][1.06][ 0][ ][ 6][ 1000][[role blue 1.02]][ 0][ ][ 7][68156][1.89][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1109][1.13][ -2][ ][ 14][ 1296][1.28][ 2][ ][ 14][ 1281][1.26][ 2][ ][ 17][289984][[role red 6.34]][ 2][ ]]
[[Newton ][ 7][ 984][[role blue 1.00]][ 0][ ][ 8][ 1015][[role blue 1.00]][ 0][ ][ 8][ 1015][[role blue 1.00]][ 0][ ][ 10][45734][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1000][[role blue 1.02]][ 0][ ][ 6][ 1046][[role blue 1.03]][ 0][ ][ 6][ 1062][[role blue 1.05]][ 0][ ][ 7][79453][1.74][ 0][ ]]
[[Schroeder][ 7][ 1031][[role blue 1.05]][ 0][ ][ 7][ 1078][1.06][ 0][ ][ 7][ 1046][[role blue 1.03]][ 0][ ][ 8][78437][1.72][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_75_gcc_SEE SEE2 X64 .qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program i:/modular-boost/libs/math/example/root_n_finding_algorithms.cpp,
GNU C++ version 4.9.1, GNU libstdc++ version 20140716, Win32
Compiled in optimise mode.]
Fraction of full accuracy 0.75
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types.
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 312][2.50][ 0][ ][ 11][ 484][3.46][ 1][ ][ 9][ 1625][4.17][ 0][ ][ 11][67718][6.46][ 0][ ]]
[[Newton ][ 3][ 125][1.00][ 0][ ][ 5][ 140][1.00][ -1][ ][ 4][ 390][1.00][ 0][ ][ 6][10484][1.00][ 0][ ]]
[[Halley ][ 2][ 125][1.00][ 0][ ][ 3][ 156][1.11][ 0][ ][ 3][ 453][1.16][ 0][ ][ 4][17359][1.66][ 0][ ]]
[[Schroeder][ 6][ 203][1.62][ 0][ ][ 7][ 234][1.67][ -1][ ][ 7][ 625][1.60][ 0][ ][ 8][35203][3.36][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types.
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 531][3.40][ 1][ ][ 15][ 734][4.29][ 2][ ][ 13][ 2437][5.04][ 0][ ][ 14][105421][6.48][ 0][ ]]
[[Newton ][ 5][ 156][1.00][ 0][ ][ 7][ 171][1.00][ 0][ ][ 6][ 484][1.00][ 0][ ][ 8][16281][1.00][ 0][ ]]
[[Halley ][ 5][ 187][1.20][ 0][ ][ 6][ 234][1.37][ 0][ ][ 5][ 796][1.64][ 0][ ][ 6][30781][1.89][ 0][ ]]
[[Schroeder][ 5][ 187][1.20][ 0][ ][ 6][ 218][1.27][ 0][ ][ 6][ 546][1.13][ 0][ ][ 7][30640][1.88][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types.
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 11][ 546][3.19][ 0][ ][ 14][ 750][4.01][ 2][ ][ 14][ 2828][5.33][ 1][ ][ 17][153093][7.82][ 2][ ]]
[[Newton ][ 6][ 171][1.00][ 0][ ][ 7][ 187][1.00][ 0][ ][ 8][ 531][1.00][ 0][ ][ 9][19578][1.00][ 0][ ]]
[[Halley ][ 5][ 203][1.19][ 0][ ][ 6][ 234][1.25][ 0][ ][ 6][ 703][1.32][ 0][ ][ 7][36296][1.85][ 0][ ]]
[[Schroeder][ 6][ 203][1.19][ 0][ ][ 7][ 250][1.34][ 0][ ][ 7][ 578][1.09][ 0][ ][ 8][38046][1.94][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_75_gcc_X64_SSE2 _X64.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program i:/modular-boost/libs/math/example/root_n_finding_algorithms.cpp,
GNU C++ version 4.9.1, GNU libstdc++ version 20140716, Win32
Compiled in optimise mode., _X64_SSE2]
Fraction of full accuracy 0.75
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _X64_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 250][2.29][ 0][ ][ 11][ 484][3.87][ 1][ ][ 9][ 1546][4.31][ 0][ ][ 11][57453][[role red 6.11]][ 0][ ]]
[[Newton ][ 3][ 109][[role blue 1.00]][ 0][ ][ 5][ 125][[role blue 1.00]][ -1][ ][ 4][ 359][[role blue 1.00]][ 0][ ][ 6][ 9406][[role blue 1.00]][ 0][ ]]
[[Halley ][ 2][ 109][[role blue 1.00]][ 0][ ][ 3][ 140][[role blue 1.12]][ 0][ ][ 3][ 453][[role blue 1.26]][ 0][ ][ 4][15359][[role blue 1.63]][ 0][ ]]
[[Schroeder][ 6][ 203][[role blue 1.86]][ 0][ ][ 7][ 218][[role blue 1.74]][ -1][ ][ 7][ 562][[role blue 1.57]][ 0][ ][ 8][30921][3.29][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _X64_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 468][3.74][ 1][ ][ 15][ 671][4.30][ 2][ ][ 13][ 2359][[role red 5.21]][ 0][ ][ 14][88515][[role red 6.05]][ 0][ ]]
[[Newton ][ 5][ 125][[role blue 1.00]][ 0][ ][ 7][ 156][[role blue 1.00]][ 0][ ][ 6][ 453][[role blue 1.00]][ 0][ ][ 8][14625][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 187][[role blue 1.50]][ 0][ ][ 6][ 218][[role blue 1.40]][ 0][ ][ 5][ 718][[role blue 1.58]][ 0][ ][ 6][27843][[role blue 1.90]][ 0][ ]]
[[Schroeder][ 5][ 171][[role blue 1.37]][ 0][ ][ 6][ 203][[role blue 1.30]][ 0][ ][ 6][ 515][[role blue 1.14]][ 0][ ][ 7][27640][[role blue 1.89]][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _X64_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 11][ 515][3.30][ 0][ ][ 14][ 718][4.20][ 2][ ][ 14][ 2765][[role red 5.37]][ 1][ ][ 17][132062][[role red 7.46]][ 2][ ]]
[[Newton ][ 6][ 156][[role blue 1.00]][ 0][ ][ 7][ 171][[role blue 1.00]][ 0][ ][ 8][ 515][[role blue 1.00]][ 0][ ][ 9][17703][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 187][[role blue 1.20]][ 0][ ][ 6][ 218][[role blue 1.27]][ 0][ ][ 6][ 671][[role blue 1.30]][ 0][ ][ 7][32000][[role blue 1.81]][ 0][ ]]
[[Schroeder][ 6][ 203][[role blue 1.30]][ 0][ ][ 7][ 234][[role blue 1.37]][ 0][ ][ 7][ 578][[role blue 1.12]][ 0][ ][ 8][34265][[role blue 1.94]][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_75_msvc.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode.]
Fraction of full accuracy 0.75
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 750][[role blue 1.00]][ 0][ ][ 11][ 1031][1.10][ 1][ ][ 11][ 1015][1.08][ 1][ ][ 11][125921][[role red 5.53]][ 0][ ]]
[[Newton ][ 3][ 906][1.21][ 0][ ][ 5][ 953][[role blue 1.02]][ -1][ ][ 5][ 937][[role blue 1.00]][ -1][ ][ 6][22750][[role blue 1.00]][ 0][ ]]
[[Halley ][ 2][ 921][1.23][ 0][ ][ 3][ 937][[role blue 1.00]][ 0][ ][ 3][ 953][[role blue 1.02]][ 0][ ][ 4][40125][1.76][ 0][ ]]
[[Schroeder][ 6][ 984][1.31][ 0][ ][ 7][ 1000][1.07][ -1][ ][ 7][ 1015][1.08][ -1][ ][ 8][73296][3.22][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1015][1.08][ 1][ ][ 15][ 1265][1.29][ 2][ ][ 15][ 1265][1.31][ 2][ ][ 14][198890][[role red 5.61]][ 0][ ]]
[[Newton ][ 5][ 937][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 7][ 1000][1.03][ 0][ ][ 8][35437][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 984][1.05][ 0][ ][ 6][ 1078][1.10][ 0][ ][ 6][ 1046][1.08][ 0][ ][ 6][69484][1.96][ 0][ ]]
[[Schroeder][ 5][ 953][[role blue 1.02]][ 0][ ][ 6][ 1000][[role blue 1.02]][ 0][ ][ 6][ 968][[role blue 1.00]][ 0][ ][ 7][67937][1.92][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 11][ 1093][1.11][ 0][ ][ 14][ 1343][1.34][ 2][ ][ 14][ 1375][1.35][ 2][ ][ 17][303625][[role red 7.07]][ 2][ ]]
[[Newton ][ 6][ 984][[role blue 1.00]][ 0][ ][ 7][ 1000][[role blue 1.00]][ 0][ ][ 7][ 1015][[role blue 1.00]][ 0][ ][ 9][42921][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1031][1.05][ 0][ ][ 6][ 1093][1.09][ 0][ ][ 6][ 1093][1.08][ 0][ ][ 7][83062][1.94][ 0][ ]]
[[Schroeder][ 6][ 1046][1.06][ 0][ ][ 7][ 1093][1.09][ 0][ ][ 7][ 1046][1.03][ 0][ ][ 8][86234][2.01][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_75_msvc_AVX.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode., _AVX]
Fraction of full accuracy 0.75
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _AVX
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 750][[role green 1.0000]1.00][ 0][ ][ 11][ 1031][1.10031.10][ 1][ ][ 11][ 1046][1.09761.10][ 1][ ][ 11][126781][[role red 5.5348]5.53][ 0][ ]]
[[Newton ][ 3][ 890][1.18671.19][ 0][ ][ 5][ 937][[role green 1.0000]1.00][ -1][ ][ 5][ 953][[role green 1.0000]1.00][ -1][ ][ 6][22906][[role green 1.0000]1.00][ 0][ ]]
[[Halley ][ 2][ 937][1.24931.25][ 0][ ][ 3][ 968][1.03311.03][ 0][ ][ 3][ 953][[role green 1.0000]1.00][ 0][ ][ 4][40265][1.75781.76][ 0][ ]]
[[Schroeder][ 6][ 1000][1.33331.33][ 0][ ][ 7][ 1031][1.10031.10][ -1][ ][ 7][ 1031][1.08181.08][ -1][ ][ 8][72296][3.15623.16][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _AVX
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 984][1.03251.03][ 1][ ][ 15][ 1218][1.21801.22][ 2][ ][ 15][ 1250][1.29131.29][ 2][ ][ 14][191500][[role red 5.5965]5.60][ 0][ ]]
[[Newton ][ 5][ 953][[role green 1.0000]1.00][ 0][ ][ 7][ 1062][1.06201.06][ 0][ ][ 7][ 968][[role green 1.0000]1.00][ 0][ ][ 8][34218][[role green 1.0000]1.00][ 0][ ]]
[[Halley ][ 5][ 1000][1.04931.05][ 0][ ][ 6][ 1109][1.10901.11][ 0][ ][ 6][ 1078][1.11361.11][ 0][ ][ 6][66765][1.95121.95][ 0][ ]]
[[Schroeder][ 5][ 984][1.03251.03][ 0][ ][ 6][ 1000][[role green 1.0000]1.00][ 0][ ][ 6][ 1000][1.03311.03][ 0][ ][ 7][65703][1.92011.92][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _AVX
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 11][ 1062][1.09711.10][ 0][ ][ 14][ 1281][1.26211.26][ 2][ ][ 14][ 1328][1.32801.33][ 2][ ][ 17][297875][[role red 7.2323]7.23][ 2][ ]]
[[Newton ][ 6][ 968][[role green 1.0000]1.00][ 0][ ][ 7][ 1031][[role green 1.0158]1.02][ 0][ ][ 7][ 1000][[role green 1.0000]1.00][ 0][ ][ 9][41187][[role green 1.0000]1.00][ 0][ ]]
[[Halley ][ 5][ 1015][1.04861.05][ 0][ ][ 6][ 1171][1.15371.15][ 0][ ][ 6][ 1093][1.09301.09][ 0][ ][ 7][77984][1.89341.89][ 0][ ]]
[[Schroeder][ 6][ 1000][1.03311.03][ 0][ ][ 7][ 1015][[role green 1.0000]1.00][ 0][ ][ 7][ 1046][1.04601.05][ 0][ ][ 8][77781][1.88851.89][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_75_msvc_X86.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode., _X86]
Fraction of full accuracy 0.75
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 8][ 1062][1.06][ -2][ ][ 11][ 1171][1.21][ 1][ ][ 11][ 1171][1.21][ 1][ ][ 11][122375][[role red 5.45]][ 0][ ]]
[[Newton ][ 3][ 1000][[role blue 1.00]][ 0][ ][ 5][ 968][[role blue 1.00]][ -1][ ][ 5][ 968][[role blue 1.00]][ -1][ ][ 6][22468][[role blue 1.00]][ 0][ ]]
[[Halley ][ 3][ 1062][1.06][ 0][ ][ 3][ 984][[role blue 1.02]][ 0][ ][ 3][ 984][[role blue 1.02]][ 0][ ][ 4][39234][1.75][ 0][ ]]
[[Schroeder][ 7][ 1234][1.23][ 0][ ][ 7][ 1046][1.08][ -1][ ][ 7][ 1031][1.07][ -1][ ][ 8][70406][3.13][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1562][1.47][ 1][ ][ 15][ 1484][1.48][ 2][ ][ 15][ 1453][1.45][ 2][ ][ 14][202265][[role red 5.41]][ 0][ ]]
[[Newton ][ 5][ 1062][[role blue 1.00]][ 0][ ][ 7][ 1000][[role blue 1.00]][ 0][ ][ 7][ 1000][[role blue 1.00]][ 0][ ][ 8][37359][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1156][1.09][ 0][ ][ 6][ 1125][1.13][ 0][ ][ 6][ 1109][1.11][ 0][ ][ 6][71843][1.92][ 0][ ]]
[[Schroeder][ 5][ 1125][1.06][ 0][ ][ 6][ 1031][[role blue 1.03]][ 0][ ][ 6][ 1031][[role blue 1.03]][ 0][ ][ 7][67875][1.82][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 11][ 1703][1.40][ 0][ ][ 14][ 1609][1.52][ 2][ ][ 14][ 1562][1.47][ 2][ ][ 17][290031][[role red 6.93]][ 2][ ]]
[[Newton ][ 6][ 1218][[role blue 1.00]][ 0][ ][ 7][ 1062][[role blue 1.00]][ 0][ ][ 7][ 1062][[role blue 1.00]][ 0][ ][ 9][41843][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1265][[role blue 1.04]][ -1][ ][ 6][ 1125][1.06][ 0][ ][ 6][ 1125][1.06][ 0][ ][ 7][75937][1.81][ 0][ ]]
[[Schroeder][ 6][ 1296][1.06][ 0][ ][ 7][ 1093][[role blue 1.03]][ 0][ ][ 7][ 1078][[role blue 1.02]][ 0][ ][ 8][77500][1.85][ 0][ ]]
] [/end of table root]

View File

@@ -0,0 +1,37 @@
[/i:/modular-boost/libs/math/doc/roots/roots_table_75_msvc_X86_SSE2 .qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Program I:\modular-boost\libs\math\example\root_n_finding_algorithms.cpp,
Microsoft Visual C++ version 12.0, Dinkumware standard library version 610, Win32
Compiled in optimise mode., _X86_SSE2 ]
Fraction of full accuracy 0.75
[table:root_5 5th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 7][ 750][[role blue 1.00]][ 0][ ][ 11][ 1031][1.10][ 1][ ][ 11][ 1031][1.12][ 1][ ][ 11][125250][[role red 5.53]][ 0][ ]]
[[Newton ][ 3][ 906][1.21][ 0][ ][ 5][ 937][[role blue 1.00]][ -1][ ][ 5][ 953][[role blue 1.03]][ -1][ ][ 6][22640][[role blue 1.00]][ 0][ ]]
[[Halley ][ 2][ 921][1.23][ 0][ ][ 3][ 953][[role blue 1.02]][ 0][ ][ 3][ 921][[role blue 1.00]][ 0][ ][ 4][39390][1.74][ 0][ ]]
[[Schroeder][ 6][ 984][1.31][ 0][ ][ 7][ 1031][1.10][ -1][ ][ 7][ 1031][1.12][ -1][ ][ 8][72515][3.20][ 0][ ]]
] [/end of table root]
[table:root_7 7th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 12][ 1000][1.09][ 1][ ][ 15][ 1218][1.28][ 2][ ][ 15][ 1218][1.26][ 2][ ][ 14][192640][[role red 5.64]][ 0][ ]]
[[Newton ][ 5][ 921][[role blue 1.00]][ 0][ ][ 7][ 953][[role blue 1.00]][ 0][ ][ 7][ 968][[role blue 1.00]][ 0][ ][ 8][34156][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1000][1.09][ 0][ ][ 6][ 1031][1.08][ 0][ ][ 6][ 1031][1.07][ 0][ ][ 6][66625][1.95][ 0][ ]]
[[Schroeder][ 5][ 968][1.05][ 0][ ][ 6][ 968][[role blue 1.02]][ 0][ ][ 6][ 1015][[role blue 1.05]][ 0][ ][ 7][64953][1.90][ 0][ ]]
] [/end of table root]
[table:root_11 11th root(28) for float, double, long double and cpp_bin_float_50 types, using _X86_SSE2
[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]
[[Algo ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ][Its][Times][Norm][Dis][ ]]
[[TOMS748 ][ 11][ 1046][1.08][ 0][ ][ 14][ 1296][1.32][ 2][ ][ 14][ 1312][1.33][ 2][ ][ 17][288437][[role red 6.98]][ 2][ ]]
[[Newton ][ 6][ 968][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 7][ 984][[role blue 1.00]][ 0][ ][ 9][41328][[role blue 1.00]][ 0][ ]]
[[Halley ][ 5][ 1000][[role blue 1.03]][ 0][ ][ 6][ 1046][1.06][ 0][ ][ 6][ 1046][1.06][ 0][ ][ 7][78593][1.90][ 0][ ]]
[[Schroeder][ 6][ 1015][[role blue 1.05]][ 0][ ][ 7][ 1046][1.06][ 0][ ][ 7][ 1046][1.06][ 0][ ][ 8][78218][1.89][ 0][ ]]
] [/end of table root]

View File

@@ -113,12 +113,12 @@
[h4 Description]
These functions solve the root of some function ['f(x)]
These functions solve the root of some function ['f(x)] -
['without the need for any derivatives of ['f(x)]].
The `bracket_and_solve_root` functions use __root_finding_TOMS748
that is asymptotically the most efficient known,
and have been shown to be optimal for a certain classes of smooth functions.
by Alefeld, Potra and Shi that is asymptotically the most efficient known,
and has been shown to be optimal for a certain classes of smooth functions.
Variants with and without __policy_section are provided.
Alternatively, __bisect is a simple __bisection_wikipedia routine which can be useful
@@ -183,15 +183,15 @@ These functions locate the root using __bisection_wikipedia.
[[f] [A unary functor which is the function ['f(x)] whose root is to be found.]]
[[min] [The left bracket of the interval known to contain the root.]]
[[max] [The right bracket of the interval known to contain the root.[br]
It is a precondition that /min < max/ and /f(min)*f(max) <= 0/,
the function signals evaluation error if these preconditions are violated.
It is a precondition that ['min < max] and ['f(min)*f(max) <= 0],
the function signals ['evaluation error] if these preconditions are violated.
The action taken is controlled by the evaluation error policy.[br]
A best guess may be returned, perhaps significantly wrong.]]
[[tol] [A binary functor that specifies the termination condition: the function
will return the current brackets enclosing the root when ['tol(min, max)] becomes true.]]
[[max_iter][The maximum number of invocations of ['f(x)] to make while searching for the root. On exit, this is updated to the actual number of invocations performed.]]
[[T] [Floating-point type, typically `double` (often deduced by __ADL)]]
[[F] [Floating-point types of the functor, usually deduced from T by __ADL, so it is rarely necessary to define F.]]
[[T] [Floating-point type, typically `double`, ]]
[[F] [Unary Functor that returns any suitable __tuple_type, of type T. ]]
]
[optional_policy]
@@ -242,27 +242,29 @@ because the termination condition ['tol] was satisfied.
to find the root of ['f(x)]. It's usable only when ['f(x)] is a monotonic
function, and the location of the root is known approximately, and in
particular it is known whether the root is occurs for positive or negative
/x/. The `bracket_and_solve_root` parameters are:
['x].
The `bracket_and_solve_root` parameters are:
[variablelist
[[f][A unary functor that is the function whose root is to be solved.
['f(x)] must be uniformly increasing or decreasing on /x/.]]
[[guess][An initial approximation to the root]]
['f(x)] must be uniformly increasing or decreasing on ['x].]]
[[guess][An initial approximation to the root.]]
[[factor][A scaling factor that is used to bracket the root: the value
/guess/ is multiplied (or divided as appropriate) by /factor/
until two values are found that bracket the root. A value
such as 2 is a typical choice for /factor/.]]
[[rising][Set to /true/ if ['f(x)] is rising on /x/ and /false/ if ['f(x)]
such as 2 is a typical choice for ['factor].]]
[[rising][Set to ['true] if ['f(x)] is rising on /x/ and /false/ if ['f(x)]
is falling on /x/. This value is used along with the result
of /f(guess)/ to determine if /guess/ is
above or below the root.]]
[[tol] [A binary functor that determines the termination condition for the search
for the root. /tol/ is passed the current brackets at each step,
when it returns true then the current brackets are returned as the result.]]
when it returns true then the current brackets are returned as the pair result.]]
[[max_iter] [The maximum number of function invocations to perform in the search
for the root. On exit is set to the actual number of invocations performed.]]
[[T] [Floating-point type, typically `double`, often deduced by __ADL]]
[[F] [Floating-point types of the functor, usually deduced from T by __ADL, so it is rarely necessary to define F.]]
[[T] [Floating-point type, typically `double`, ]]
[[F] [Unary Functor that returns any suitable __tuple_type, of type T. ]]
]
[optional_policy]
@@ -351,8 +353,8 @@ cubic, quadratic and linear (secant) interpolation to locate the root of
[[max_iter] [The maximum number of function invocations to perform in the search
for the root. On exit, ['max_iter] is set to actual number of function
invocations used.]]
[[T] [Floating-point type, typically `double`, often deduced by __ADL]]
[[F] [Floating-point types of the functor, usually deduced from T by __ADL, so it is rarely necessary to define F.]]
[[T] [Floating-point type, typically `double`, ]]
[[F] [Unary Functor that returns any suitable __tuple_type, of type T. ]]
]
[optional_policy]

View File

@@ -0,0 +1,18 @@
[/i:/modular-boost/libs/math/doc/roots/type_info_table_100_msvc.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Fraction of maximum possible bits of accuracy required is 1.0.]
[table:type_info_100_msvc Digits for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][24]]
[[float][17][53][53]]
[[long double][17][53][53]]
[[cpp_bin_float_50][52][168][168]]
] [/table table_id_msvc]

View File

@@ -0,0 +1,18 @@
[/i:/modular-boost/libs/math/doc/roots/type_info_table_75_msvc.qbk
Copyright 2015 Paul A. Bristow.
Copyright 2015 John Maddock.
Distributed under 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).
]
[h6 Fraction of maximum possible bits of accuracy required is 0.75.]
[table:type_info_75_msvc Digits for float, double, long double and cpp_bin_float_50
[[type name] [max_digits10] [binary digits] [required digits]]
[[float][9][24][18]]
[[float][17][53][39]]
[[long double][17][53][39]]
[[cpp_bin_float_50][52][168][126]]
] [/table table_id_msvc]

View File

@@ -30,14 +30,13 @@
//[brent_minimise_mp_include_0
#include <boost/multiprecision/cpp_dec_float.hpp> // For decimal boost::multiprecision::cpp_dec_float_50.
#include <boost/multiprecision/cpp_bin_float.hpp> // For binary boost::multiprecision::cpp_bin_float_50;
//] [/brent_minimise_mp_include_0]
//#ifndef _MSC_VER // float128 is not yet supported by Microsoft compiler at 2013.
#ifdef BOOST_HAVE_QUADMATH // Define only if GCC or Intel, and have quadmath.lib or .dll library available.
# include <boost/multiprecision/float128.hpp>
#endif
//] [/brent_minimise_mp_include_0]
#include <iostream>
// using std::cout; using std::endl;
#include <iomanip>
@@ -46,21 +45,19 @@
using std::numeric_limits;
#include <tuple>
#include <utility> // pair, make_pair
#include <type_traits>
#include <type_traits>
#include <typeinfo>
//typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>,
// boost::multiprecision::et_off>
// cpp_dec_float_50_et_off;
//
//
// typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<50>,
// boost::multiprecision::et_off>
// cpp_bin_float_50_et_off;
// http://en.wikipedia.org/wiki/Brent%27s_method Brent's method
double f(double x)
{
return (x + 3) * (x - 1) * (x - 1);
@@ -79,10 +76,10 @@ struct funcdouble
//[brent_minimise_T_functor
template <class T = double>
struct func
{
{
T operator()(T const& x)
{ //
return (x + 3) * (x - 1) * (x - 1); //
return (x + 3) * (x - 1) * (x - 1); //
}
};
//] [/brent_minimise_T_functor]
@@ -96,11 +93,11 @@ bool close(T expect, T got, T tolerance)
using boost::math::fpc::is_small;
if (is_small<T>(expect, tolerance))
{
{
return is_small<T>(got, tolerance);
}
else
{
{
return is_close_to<T>(expect, got, tolerance);
}
}
@@ -120,11 +117,11 @@ void show_minima()
std::streamsize prec = static_cast<int>(2 + sqrt(bits)); // Number of significant decimal digits.
std::streamsize precision = std::cout.precision(prec); // Save.
std::cout << "\n\nFor type " << typeid(T).name()
<< ",\n epsilon = " << std::numeric_limits<T>::epsilon()
std::cout << "\n\nFor type " << typeid(T).name()
<< ",\n epsilon = " << std::numeric_limits<T>::epsilon()
// << ", precision of " << bits << " bits"
<< ",\n the maximum theoretical precision from Brent minimization is " << sqrt(std::numeric_limits<T>::epsilon())
<< "\n Displaying to std::numeric_limits<T>::digits10 " << prec << " significant decimal digits."
<< "\n Displaying to std::numeric_limits<T>::digits10 " << prec << " significant decimal digits."
<< std::endl;
const boost::uintmax_t maxit = 20;
@@ -157,8 +154,8 @@ void show_minima()
std::cout.precision(precision); // Restore.
}
catch (const std::exception& e)
{ // Always useful to include try & catch blocks because default policies
// are to throw exceptions on arguments that cause errors like underflow, overflow.
{ // Always useful to include try & catch blocks because default policies
// are to throw exceptions on arguments that cause errors like underflow, overflow.
// Lacking try & catch blocks, the program will abort without a message below,
// which may give some helpful clues as to the cause of the exception.
std::cout <<
@@ -172,8 +169,8 @@ int main()
{
std::cout << "Brent's minimisation example." << std::endl;
std::cout << std::boolalpha << std::endl;
// Tip - using
// Tip - using
// std::cout.precision(std::numeric_limits<T>::digits10);
// during debugging is wise because it shows if construction of multiprecision involves conversion from double
// by finding random or zero digits after 17.
@@ -190,7 +187,7 @@ int main()
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
// x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018
//] [/brent_minimise_double_1]
std::cout << "x at minimum = " << (r.first - 1.) /r.first << std::endl;
double uncertainty = sqrt(std::numeric_limits<double>::epsilon());
@@ -203,7 +200,7 @@ int main()
std::cout << is_close_to(1., r.first, uncertainty) << std::endl;
std::cout << is_small(r.second, uncertainty) << std::endl;
std::cout << std::boolalpha << "x == 1 (compared to uncertainty " << uncertainty << ") is " << close(1., r.first, uncertainty) << std::endl;
std::cout << std::boolalpha << "f(x) == (0 compared to uncertainty " << uncertainty << ") is " << close(0., r.second, uncertainty) << std::endl;
@@ -233,9 +230,8 @@ int main()
// Showing 53 bits precision with 9 decimal digits from tolerance 1.49011611938477e-008
// x at minimum = 1, f(1) = 5.04852568e-018
//[brent_minimise_double_4
{
//[brent_minimise_double_4
bits /= 2; // Half digits precision (effective maximum).
double epsilon_2 = boost::math::pow<-(std::numeric_limits<double>::digits/2 - 1), double>(2);
@@ -248,12 +244,12 @@ int main()
r = brent_find_minima(funcdouble(), -4., 4. / 3, bits, it);
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
std::cout << it << " iterations. " << std::endl;
}
//] [/brent_minimise_double_4]
}
// x at minimum = 1, f(1) = 5.04852568e-018
//[brent_minimise_double_5
{
//[brent_minimise_double_5
bits /= 2; // Quarter precision.
double epsilon_4 = boost::math::pow<-(std::numeric_limits<double>::digits / 4 - 1), double>(2);
@@ -266,15 +262,15 @@ int main()
r = brent_find_minima(funcdouble(), -4., 4. / 3, bits, it);
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second
<< ", after " << it << " iterations. " << std::endl;
}
//] [/brent_minimise_double_5]
}
// Showing 13 bits precision with 9 decimal digits from tolerance 0.015625
// x at minimum = 0.9999776, f(0.9999776) = 2.0069572e-009
// 7 iterations.
//[brent_minimise_template_1
{
//[brent_minimise_template_1
std::cout.precision(std::numeric_limits<long double>::digits10);
long double bracket_min = -4.;
long double bracket_max = 4. / 3;
@@ -285,7 +281,7 @@ int main()
std::pair<long double, long double> r = brent_find_minima(func<long double>(), bracket_min, bracket_max, bits, it);
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second
<< ", after " << it << " iterations. " << std::endl;
//] [/brent_minimise_template_1]
//] [/brent_minimise_template_1]
}
// Show use of built-in type Template versions.
@@ -297,16 +293,15 @@ int main()
show_minima<long double>();
//] [/brent_minimise_template_fd]
//[brent_minimise_mp_include_1
using boost::multiprecision::cpp_bin_float_50; // binary.
//[brent_minimise_mp_include_1
#ifdef BOOST_HAVE_QUADMATH // Define only if GCC or Intel and have quadmath.lib or .dll library available.
using boost::multiprecision::float128;
#endif
//] [/brent_minimise_mp_include_1]
//[brent_minimise_template_quad
// #ifndef _MSC_VER
#ifdef BOOST_HAVE_QUADMATH // Define only if GCC or Intel and have quadmath.lib or .dll library available.
show_minima<float128>(); // Needs quadmath_snprintf, sqrtQ, fabsq that are in in quadmath library.
@@ -335,7 +330,6 @@ int main()
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>,
boost::multiprecision::et_off>
cpp_dec_float_50_et_off;
//] [/brent_minimise_mp_typedefs]
{ // binary ET on by default.
@@ -359,7 +353,7 @@ int main()
boost::uintmax_t it = maxit;
std::pair<cpp_bin_float_50, cpp_bin_float_50> r = brent_find_minima(func<cpp_bin_float_50>(), bracket_min, bracket_max, bits, it);
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second
std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second
// x at minimum = 1, f(1) = 5.04853e-018
<< ", after " << it << " iterations. " << std::endl;
@@ -378,13 +372,13 @@ int main()
//] [/brent_minimise_mp_output_1]
*/
//[brent_minimise_mp_2
show_minima<cpp_bin_float_50_et_on>(); //
show_minima<cpp_bin_float_50_et_on>(); //
//] [/brent_minimise_mp_2]
/*
/*
//[brent_minimise_mp_output_2
For type class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50, 10, void, int, 0, 0>, 1>,
//] [/brent_minimise_mp_output_1]
*/
}
@@ -406,7 +400,7 @@ int main()
// x at minimum = 1, f(1) = 5.04853e-018
std::cout << it << " iterations. " << std::endl;
show_minima<cpp_bin_float_50_et_on>(); //
show_minima<cpp_bin_float_50_et_on>(); //
}
return 0;
@@ -427,7 +421,7 @@ int main()
// x at minimum = 1, f(1) = 5.04853e-018
std::cout << it << " iterations. " << std::endl;
show_minima<cpp_bin_float_50_et_off>(); //
show_minima<cpp_bin_float_50_et_off>(); //
}
{ // decimal ET on by default
@@ -450,7 +444,7 @@ int main()
show_minima<cpp_dec_float_50>();
}
{ // decimal ET on
{ // decimal ET on
std::cout.precision(std::numeric_limits<cpp_dec_float_50_et_on>::digits10);
int bits = std::numeric_limits<cpp_dec_float_50_et_on>::digits / 2 - 2;
@@ -497,9 +491,9 @@ int main()
/*
// GCC 4.9.1 with quadmath
// GCC 4.9.1 with quadmath
Brent's minimisation example.
x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018
x at minimum = 1.12344622367552e-009
@@ -507,15 +501,15 @@ Uncertainty sqrt(epsilon) = 1.49011611938477e-008
x == 1 (compared to uncertainty 1.49011611938477e-008) is true
f(x) == (0 compared to uncertainty 1.49011611938477e-008) is true
Precision bits = 53
x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018 after 10 iterations.
x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018 after 10 iterations.
Showing 53 bits precision with 9 decimal digits from tolerance 1.49011611938477e-008
x at minimum = 1, f(1) = 5.04852568e-018 after 10 iterations.
x at minimum = 1, f(1) = 5.04852568e-018 after 10 iterations.
Showing 26 bits precision with 9 decimal digits from tolerance 0.000172633492
x at minimum = 1, f(1) = 5.04852568e-018
10 iterations.
10 iterations.
Showing 13 bits precision with 9 decimal digits from tolerance 0.015625
x at minimum = 0.9999776, f(0.9999776) = 2.0069572e-009, after 7 iterations.
x at minimum = 1.00000000000137302, f(1.00000000000137302) = 7.5407901369731193e-024, after 10 iterations.
x at minimum = 0.9999776, f(0.9999776) = 2.0069572e-009, after 7 iterations.
x at minimum = 1.00000000000137302, f(1.00000000000137302) = 7.5407901369731193e-024, after 10 iterations.
For type f,
@@ -557,7 +551,7 @@ For type N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26
x == 1 (compared to uncertainty 1.38777878e-17) is true
f(x) == (0 compared to uncertainty 1.38777878e-17) is true
-4 1.3333333333333333333333333333333333333333333333333
x at minimum = 0.99999999999999999999999999998813903221565569205253, f(0.99999999999999999999999999998813903221565569205253) = 5.6273022712501408640665300316078046703496236636624e-58, after 14 iterations.
x at minimum = 0.99999999999999999999999999998813903221565569205253, f(0.99999999999999999999999999998813903221565569205253) = 5.6273022712501408640665300316078046703496236636624e-58, after 14 iterations.
For type N5boost14multiprecision6numberINS0_8backends13cpp_bin_floatILj50ELNS2_15digit_base_typeE10EviLi0ELi0EEELNS0_26expression_template_optionE1EEE,
@@ -570,7 +564,7 @@ x == 1 (compared to uncertainty 7.311312755e-26) is true
f(x) == (0 compared to uncertainty 7.311312755e-26) is true
-4 1.3333333333333333333333333333333333333333333333333
x at minimum = 0.99999999999999999999999999998813903221565569205253, f(0.99999999999999999999999999998813903221565569205253) = 5.6273022712501408640665300316078046703496236636624e-58
14 iterations.
14 iterations.
For type N5boost14multiprecision6numberINS0_8backends13cpp_bin_floatILj50ELNS2_15digit_base_typeE10EviLi0ELi0EEELNS0_26expression_template_optionE1EEE,

View File

@@ -57,7 +57,7 @@ The constructor sets the [*fractional] tolerance and the equality strength.
Two member functions allow access to the chosen tolerance and strength.
FPT fraction_tolerance() const;
FPT fraction_tolerance() const;
strength strength() const; // weak or strong.
the `operator()` functor carries out the comparison,
@@ -92,7 +92,7 @@ that failed the test.
using namespace boost::math::fpc;
//`or
//`or
using boost::math::fpc::close_at_tolerance;
using boost::math::fpc::small_with_tolerance;
@@ -182,8 +182,8 @@ A class that stores a tolerance of three epsilon (and the default ['strong] test
std::cout << "failed_fraction = " << three_rounds.failed_fraction() << std::endl;
/*`To get some nearby values, it is convenient to use the Boost.Math next functions,
for which we need an include
/*`To get some nearby values, it is convenient to use the Boost.Math __next_float functions,
for which we need an include
#include <boost/math/special_functions/next.hpp>

View File

@@ -0,0 +1,220 @@
// (C) Copyright John Maddock 2006-7.
// 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)
#ifndef BOOST_MATH_HANDLE_TEST_RESULT
#define BOOST_MATH_HANDLE_TEST_RESULT
#include <boost/math/tools/stats.hpp>
#include <boost/math/tools/test.hpp>
#include <boost/math/tools/precision.hpp>
#include <boost/regex.hpp>
#include <boost/test/test_tools.hpp>
#include <iostream>
#include <iomanip>
#if defined(BOOST_INTEL)
# pragma warning(disable:239)
# pragma warning(disable:264)
#endif
//
// Every client of this header has to define this function,
// and initialise the table of expected results:
//
void expected_results();
typedef std::pair<boost::regex, std::pair<boost::uintmax_t, boost::uintmax_t> > expected_data_type;
typedef std::list<expected_data_type> list_type;
inline list_type&
get_expected_data()
{
static list_type data;
return data;
}
inline void add_expected_result(
const char* compiler,
const char* library,
const char* platform,
const char* type_name,
const char* test_name,
const char* group_name,
boost::uintmax_t max_peek_error,
boost::uintmax_t max_mean_error)
{
std::string re("(?:");
re += compiler;
re += ")";
re += "\\|";
re += "(?:";
re += library;
re += ")";
re += "\\|";
re += "(?:";
re += platform;
re += ")";
re += "\\|";
re += "(?:";
re += type_name;
re += ")";
re += "\\|";
re += "(?:";
re += test_name;
re += ")";
re += "\\|";
re += "(?:";
re += group_name;
re += ")";
get_expected_data().push_back(
std::make_pair(boost::regex(re, boost::regex::perl | boost::regex::icase),
std::make_pair(max_peek_error, max_mean_error)));
}
inline std::string build_test_name(const char* type_name, const char* test_name, const char* group_name)
{
std::string result(BOOST_COMPILER);
result += "|";
result += BOOST_STDLIB;
result += "|";
result += BOOST_PLATFORM;
result += "|";
result += type_name;
result += "|";
result += group_name;
result += "|";
result += test_name;
return result;
}
inline const std::pair<boost::uintmax_t, boost::uintmax_t>&
get_max_errors(const char* type_name, const char* test_name, const char* group_name)
{
static const std::pair<boost::uintmax_t, boost::uintmax_t> defaults(1, 1);
std::string name = build_test_name(type_name, test_name, group_name);
list_type& l = get_expected_data();
list_type::const_iterator a(l.begin()), b(l.end());
while(a != b)
{
if(regex_match(name, a->first))
{
#if 0
std::cout << name << std::endl;
std::cout << a->first.str() << std::endl;
#endif
return a->second;
}
++a;
}
return defaults;
}
template <class T, class Seq>
void handle_test_result(const boost::math::tools::test_result<T>& result,
const Seq& worst, int row,
const char* type_name,
const char* test_name,
const char* group_name)
{
#ifdef BOOST_MSVC
#pragma warning(push)
#pragma warning(disable:4127)
#endif
using namespace std; // To aid selection of the right pow.
T eps = boost::math::tools::epsilon<T>();
std::cout << std::setprecision(4);
T max_error_found = (result.max)()/eps;
T mean_error_found = result.rms()/eps;
//
// Begin by printing the main tag line with the results:
//
std::cout << test_name << "<" << type_name << "> Max = " << max_error_found
<< " RMS Mean=" << mean_error_found;
//
// If the max error is non-zero, give the row of the table that
// produced the worst error:
//
if((result.max)() != 0)
{
std::cout << "\n worst case at row: "
<< row << "\n { ";
if(std::numeric_limits<T>::digits10)
{
std::cout << std::setprecision(std::numeric_limits<T>::digits10 + 2);
}
else
{
std::cout << std::setprecision(std::numeric_limits<long double>::digits10 + 2);
}
for(unsigned i = 0; i < worst.size(); ++i)
{
if(i)
std::cout << ", ";
#if defined(__SGI_STL_PORT)
std::cout << boost::math::tools::real_cast<double>(worst[i]);
#else
std::cout << worst[i];
#endif
}
std::cout << " }";
}
std::cout << std::endl;
//
// Now verify that the results are within our expected bounds:
//
std::pair<boost::uintmax_t, boost::uintmax_t> const& bounds = get_max_errors(type_name, test_name, group_name);
if(bounds.first < max_error_found)
{
std::cerr << "Peak error greater than expected value of " << bounds.first << std::endl;
BOOST_CHECK(bounds.first >= max_error_found);
}
if(bounds.second < mean_error_found)
{
std::cerr << "Mean error greater than expected value of " << bounds.second << std::endl;
BOOST_CHECK(bounds.second >= mean_error_found);
}
std::cout << std::endl;
#ifdef BOOST_MSVC
#pragma warning(pop)
#endif
}
template <class T, class Seq>
void print_test_result(const boost::math::tools::test_result<T>& result,
const Seq& worst, int row, const char* name, const char* test)
{
using namespace std; // To aid selection of the right pow.
T eps = boost::math::tools::epsilon<T>();
std::cout << std::setprecision(4);
T max_error_found = (result.max)()/eps;
T mean_error_found = result.rms()/eps;
//
// Begin by printing the main tag line with the results:
//
std::cout << test << "(" << name << ") Max = " << max_error_found
<< " RMS Mean=" << mean_error_found;
//
// If the max error is non-zero, give the row of the table that
// produced the worst error:
//
if((result.max)() != 0)
{
std::cout << "\n worst case at row: "
<< row << "\n { ";
for(unsigned i = 0; i < worst.size(); ++i)
{
if(i)
std::cout << ", ";
std::cout << worst[i];
}
std::cout << " }";
}
std::cout << std::endl;
}
#endif // BOOST_MATH_HANDLE_TEST_RESULT

View File

@@ -0,0 +1,855 @@
// Copyright Paul A. Bristow 2015
// 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)
// Comparison of finding roots using TOMS748, Newton-Raphson, Schroeder & Halley algorithms.
// Note that this file contains Quickbook mark-up as well as code
// and comments, don't change any of the special comment mark-ups!
// root_finding_algorithms.cpp
#include <boost/cstdlib.hpp>
#include <boost/config.hpp>
#include <boost/array.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/concepts/real_concept.hpp>
#include <boost/utility/enable_if.hpp>
#include "table_type.hpp"
// Copy of i:\modular-boost\libs\math\test\table_type.hpp
// #include "handle_test_result.hpp"
// Copy of i:\modular - boost\libs\math\test\handle_test_result.hpp
#include <boost/math/tools/roots.hpp>
//using boost::math::policies::policy;
//using boost::math::tools::newton_raphson_iterate;
//using boost::math::tools::halley_iterate; //
//using boost::math::tools::eps_tolerance; // Binary functor for specified number of bits.
//using boost::math::tools::bracket_and_solve_root;
//using boost::math::tools::toms748_solve;
//using boost::math::tools::schroeder_iterate;
#include <boost/math/special_functions/next.hpp> // For float_distance.
#include <boost/math/tools/tuple.hpp> // for tuple and make_tuple.
#include <boost/math/special_functions/cbrt.hpp> // For boost::math::cbrt.
#include <boost/multiprecision/cpp_bin_float.hpp> // is binary.
//#include <boost/multiprecision/cpp_dec_float.hpp> // is decimal.
using boost::multiprecision::cpp_bin_float_100;
using boost::multiprecision::cpp_bin_float_50;
#include <boost/timer/timer.hpp>
#include <boost/system/error_code.hpp>
#include <boost/multiprecision/cpp_bin_float/io.hpp>
#include <boost/preprocessor/stringize.hpp>
// STL
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <limits>
#include <fstream> // std::ofstream
#include <cmath>
#include <typeinfo> // for type name using typid(thingy).name();
#ifndef BOOST_ROOT
# define BOOST_ROOT i:/modular-boost/
#endif
// Need to find this
#ifdef __FILE__
std::string sourcefilename = __FILE__;
#endif
#ifdef BOOST_ROOT
std::string boost_root = BOOST_STRINGIZE(BOOST_ROOT);
#endif
#ifdef _MSC_VER
std::string filename = boost_root.append("libs/math/doc/roots/root_comparison_tables_msvc.qbk");
#else // assume GCC
std::string filename = boost_root.append("libs/math/doc/roots/root_comparison_tables_gcc.qbk");
#endif
std::ofstream fout (filename.c_str(), std::ios_base::out);
//std::array<std::string, 6> float_type_names =
//{
// "float", "double", "long double", "cpp_bin_128", "cpp_dec_50", "cpp_dec_100"
//};
std::vector<std::string> algo_names =
{
"cbrt", "TOMS748", "Newton", "Halley", "Schroeder"
};
std::vector<int> max_digits10s;
std::vector<std::string> typenames; // Full computer generated type name.
std::vector<std::string> names; // short name.
uintmax_t iters; // Global as iterations is not returned by rooting function.
const int convert = 1000; // convert nanoseconds to microseconds (assuming this is resolution).
const int count = 1000000; // Number of iterations to average.
struct root_info
{ // for a floating-point type, float, double ...
std::size_t max_digits10; // for type.
std::string full_typename; // for type from type_id.name().
std::string short_typename; // for type "float", "double", "cpp_bin_float_50" ....
std::size_t bin_digits; // binary in floating-point type numeric_limits<T>::digits;
int get_digits; // fraction of maximum possible accuracy required.
// = digits * digits_accuracy
// Vector of values for each algorithm, std::cbrt, boost::math::cbrt, TOMS748, Newton, Halley.
//std::vector< boost::int_least64_t> times; converted to int.
std::vector<int> times;
//boost::int_least64_t min_time = std::numeric_limits<boost::int_least64_t>::max(); // Used to normalize times (as int).
std::vector<double> normed_times;
boost::int_least64_t min_time = std::numeric_limits<boost::int_least64_t>::max(); // Used to normalize times.
std::vector<uintmax_t> iterations;
std::vector<long int> distances;
std::vector<cpp_bin_float_100> full_results;
}; // struct root_info
std::vector<root_info> root_infos; // One element for each type used.
int type_no = -1; // float = 0, double = 1, ... indexing root_infos.
inline std::string build_test_name(const char* type_name, const char* test_name)
{
std::string result(BOOST_COMPILER);
result += "|";
result += BOOST_STDLIB;
result += "|";
result += BOOST_PLATFORM;
result += "|";
result += type_name;
result += "|";
result += test_name;
#ifdef _DEBUG
#if (_DEBUG == 0)
result += "|";
result += " debug";
#else
result += "|";
result += " release";
#endif
#endif
result += "|";
return result;
}
double digits_accuracy = 1. ; // 1 == maximum possible accuracy.
// No derivatives - using TOMS748 internally.
template <class T>
struct cbrt_functor_noderiv
{ // cube root of x using only function - no derivatives.
cbrt_functor_noderiv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor just stores value a to find root of.
}
T operator()(T const& x)
{
T fx = x*x*x - a; // Difference (estimate x^3 - a).
return fx;
}
private:
T a; // to be 'cube_rooted'.
}; // template <class T> struct cbrt_functor_noderiv
template <class T>
T cbrt_noderiv(T x)
{ // return cube root of x using bracket_and_solve (using NO derivatives).
using namespace std; // Help ADL of std functions.
using namespace boost::math::tools; // For bracket_and_solve_root.
// Maybe guess should be double, or use enable_if to avoid warning about conversion double to float here?
T guess;
if (boost::is_fundamental<T>::value)
{
int exponent;
frexp(x, &exponent); // Get exponent of z (ignore mantissa).
guess = ldexp((T)1., exponent / 3); // Rough guess is to divide the exponent by three.
}
else
{ // (boost::is_class<T>)
double dx = static_cast<double>(x);
guess = boost::math::cbrt<T>(dx); // Get guess using double.
}
T factor = 2; // How big steps to take when searching.
const boost::uintmax_t maxit = 50; // Limit to maximum iterations.
boost::uintmax_t it = maxit; // Initally our chosen max iterations, but updated with actual.
bool is_rising = true; // So if result if guess^3 is too low, then try increasing guess.
int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
// Some fraction of digits is used to control how accurate to try to make the result.
int get_digits = static_cast<int>(digits * digits_accuracy);
eps_tolerance<T> tol(get_digits); // Set the tolerance.
std::pair<T, T> r =
bracket_and_solve_root(cbrt_functor_noderiv<T>(x), guess, factor, is_rising, tol, it);
iters = it;
T result = r.first + (r.second - r.first) / 2; // Midway between brackets.
return result;
} // template <class T> T cbrt_noderiv(T x)
// Using 1st derivative only Newton-Raphson
template <class T>
struct cbrt_functor_deriv
{ // Functor also returning 1st derviative.
cbrt_functor_deriv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor stores value a to find root of,
// for example: calling cbrt_functor_deriv<T>(x) to use to get cube root of x.
}
std::pair<T, T> operator()(T const& x)
{ // Return both f(x) and f'(x).
T fx = x*x*x - a; // Difference (estimate x^3 - value).
T dx = 3 * x*x; // 1st derivative = 3x^2.
return std::make_pair(fx, dx); // 'return' both fx and dx.
}
private:
T a; // to be 'cube_rooted'.
};
template <class T>
T cbrt_deriv(T x)
{ // return cube root of x using 1st derivative and Newton_Raphson.
using namespace boost::math::tools;
int exponent;
frexp(x, &exponent); // Get exponent of z (ignore mantissa).
T guess = ldexp(static_cast<T>(1), exponent / 3); // Rough guess is to divide the exponent by three.
T min = ldexp(static_cast<T>(0.5), exponent / 3); // Minimum possible value is half our guess.
T max = ldexp(static_cast<T>(2), exponent / 3); // Maximum possible value is twice our guess.
const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
int get_digits = static_cast<int>(digits * digits_accuracy);
const boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = newton_raphson_iterate(cbrt_functor_deriv<T>(x), guess, min, max, get_digits, it);
iters = it;
return result;
}
// Using 1st and 2nd derivatives with Halley algorithm.
template <class T>
struct cbrt_functor_2deriv
{ // Functor returning both 1st and 2nd derivatives.
cbrt_functor_2deriv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor stores value a to find root of, for example:
// calling cbrt_functor_2deriv<T>(x) to get cube root of x,
}
boost::math::tuple<T, T, T> operator()(T const& x)
{ // Return both f(x) and f'(x) and f''(x).
using boost::math::make_tuple;
T fx = x*x*x - a; // Difference (estimate x^3 - value).
T dx = 3 * x*x; // 1st derivative = 3x^2.
T d2x = 6 * x; // 2nd derivative = 6x.
return make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
}
private:
T a; // to be 'cube_rooted'.
};
template <class T>
T cbrt_2deriv(T x)
{ // return cube root of x using 1st and 2nd derivatives and Halley.
//using namespace std; // Help ADL of std functions.
using namespace boost::math::tools;
int exponent;
frexp(x, &exponent); // Get exponent of z (ignore mantissa).
T guess = ldexp(static_cast<T>(1), exponent / 3); // Rough guess is to divide the exponent by three.
T min = ldexp(static_cast<T>(0.5), exponent / 3); // Minimum possible value is half our guess.
T max = ldexp(static_cast<T>(2), exponent / 3);// Maximum possible value is twice our guess.
const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
// digits used to control how accurate to try to make the result.
int get_digits = static_cast<int>(digits * digits_accuracy);
boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = halley_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, it);
iters = it;
return result;
}
// Using 1st and 2nd derivatives using Schroeder algorithm.
template <class T>
T cbrt_2deriv_s(T x)
{ // return cube root of x using 1st and 2nd derivatives and Schroeder algorithm.
//using namespace std; // Help ADL of std functions.
using namespace boost::math::tools;
int exponent;
frexp(x, &exponent); // Get exponent of z (ignore mantissa).
T guess = ldexp(static_cast<T>(1), exponent / 3); // Rough guess is to divide the exponent by three.
T min = ldexp(static_cast<T>(0.5), exponent / 3); // Minimum possible value is half our guess.
T max = ldexp(static_cast<T>(2), exponent / 3);// Maximum possible value is twice our guess.
const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
// digits used to control how accurate to try to make the result.
int get_digits = static_cast<int>(digits * digits_accuracy);
const boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = schroeder_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, it);
iters = it;
return result;
} // template <class T> T cbrt_2deriv_s(T x)
template <typename T>
int test_root(cpp_bin_float_100 big_value, cpp_bin_float_100 answer, const char* type_name)
{
//T value = 28.; // integer (exactly representable as floating-point)
// whose cube root is *not* exactly representable.
// Wolfram Alpha command N[28 ^ (1 / 3), 100] computes cube root to 100 decimal digits.
// 3.036588971875662519420809578505669635581453977248111123242141654169177268411884961770250390838097895
std::size_t max_digits = 2 + std::numeric_limits<T>::digits * 3010 / 10000;
// For new versions use max_digits10
// std::cout.precision(std::numeric_limits<T>::max_digits10);
std::cout.precision(max_digits);
std::cout << std::showpoint << std::endl; // Trailing zeros too.
root_infos.push_back(root_info());
type_no++; // Another type.
root_infos[type_no].max_digits10 = max_digits;
root_infos[type_no].full_typename = typeid(T).name(); // Full typename.
root_infos[type_no].short_typename = type_name; // Short typename.
root_infos[type_no].bin_digits = std::numeric_limits<T>::digits;
root_infos[type_no].get_digits = static_cast<int>(std::numeric_limits<T>::digits * digits_accuracy);
T to_root = static_cast<T>(big_value);
T result; // root
T ans = static_cast<T>(answer);
int algo = 0; // Count of algorithms used.
using boost::timer::nanosecond_type;
using boost::timer::cpu_times;
using boost::timer::cpu_timer;
cpu_times now; // Holds wall, user and system times.
// std::cbrt is much the fastest, but not useful for this comparison because it only handles fundamental types.
// Using enable_if allows us to avoid a compile fail with multiprecision types, but still distorts the results too much.
//{
// algorithm_names.push_back("std::cbrt");
// cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
// ti.start();
// for (long i = 0; i < count; ++i)
// {
// stdcbrt(big_value);
// }
// now = ti.elapsed();
// int time = static_cast<int>(now.user / count);
// root_infos[type_no].times.push_back(time); // CPU time taken per root.
// if (time < root_infos[type_no].min_time)
// {
// root_infos[type_no].min_time = time;
// }
// ti.stop();
// long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
// root_infos[type_no].distances.push_back(distance);
// root_infos[type_no].iterations.push_back(0); // Not known.
// root_infos[type_no].full_results.push_back(result);
// algo++;
//}
//{
// //algorithm_names.push_back("boost::math::cbrt"); // .
// cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
// ti.start();
// for (long i = 0; i < count; ++i)
// {
// result = boost::math::cbrt(to_root); //
// }
// now = ti.elapsed();
// int time = static_cast<int>(now.user / count);
// root_infos[type_no].times.push_back(time); // CPU time taken.
// ti.stop();
// if (time < root_infos[type_no].min_time)
// {
// root_infos[type_no].min_time = time;
// }
// long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
// root_infos[type_no].distances.push_back(distance);
// root_infos[type_no].iterations.push_back(0); // Iterations not knowable.
// root_infos[type_no].full_results.push_back(result);
//}
{
//algorithm_names.push_back("boost::math::cbrt"); // .
result = 0;
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < count; ++i)
{
result += boost::math::cbrt(to_root); //
}
now = ti.elapsed();
boost:int_least64_t n = now.user;
long time = static_cast<long>(now.user/1000); // convert nanoseconds to microseconds (assuming this is resolution).
root_infos[type_no].times.push_back(time); // CPU time taken.
ti.stop();
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
result = boost::math::cbrt(to_root);
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(0); // Iterations not knowable.
root_infos[type_no].full_results.push_back(result);
}
{
//algorithm_names.push_back("TOMS748"); //
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < count; ++i)
{
result = cbrt_noderiv<T>(to_root); //
}
now = ti.elapsed();
// int time = static_cast<int>(now.user / count);
long time = static_cast<long>(now.user/1000);
root_infos[type_no].times.push_back(time); // CPU time taken.
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
ti.stop();
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
{
// algorithm_names.push_back("Newton"); // algorithm
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < count; ++i)
{
result = cbrt_deriv(to_root); //
}
now = ti.elapsed();
// int time = static_cast<int>(now.user / count);
long time = static_cast<long>(now.user/1000);
root_infos[type_no].times.push_back(time); // CPU time taken.
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
ti.stop();
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
{
//algorithm_names.push_back("Halley"); // algorithm
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < count; ++i)
{
result = cbrt_2deriv(to_root); //
}
now = ti.elapsed();
// int time = static_cast<int>(now.user / count);
long time = static_cast<long>(now.user/1000);
root_infos[type_no].times.push_back(time); // CPU time taken.
ti.stop();
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
{
// algorithm_names.push_back("Shroeder"); // algorithm
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < count; ++i)
{
result = cbrt_2deriv_s(to_root); //
}
now = ti.elapsed();
// int time = static_cast<int>(now.user / count);
long time = static_cast<long>(now.user/1000);
root_infos[type_no].times.push_back(time); // CPU time taken.
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
ti.stop();
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
for (size_t i = 0; i != root_infos[type_no].times.size(); i++)
{ // Normalize times.
double normed_time = static_cast<double>(root_infos[type_no].times[i]);
normed_time /= root_infos[type_no].min_time;
root_infos[type_no].normed_times.push_back(normed_time);
}
algo++;
return algo; // Count of how many algorithms used.
} // test_root
void table_root_info(cpp_bin_float_100 full_value, cpp_bin_float_100 full_answer)
{
// Fill the elements.
int type_count = 0;
type_count = test_root<float>(full_value, full_answer, "float");
type_count = test_root<double>(full_value, full_answer, "double");
type_count = test_root<long double>(full_value, full_answer, "long double");
type_count = test_root<cpp_bin_float_50>(full_value, full_answer, "cpp_bin_float_50");
//type_count = test_root<cpp_bin_float_100>(full_value, full_answer, "cpp_bin_float_100");
std::cout << root_infos.size() << " floating-point types tested:" << std::endl;
#ifndef NDEBUG
std::cout << "Compiled in debug mode." << std::endl;
#else
std::cout << "Compiled in optimise mode." << std::endl;
#endif
for (size_t tp = 0; tp != root_infos.size(); tp++)
{ // For all types:
std::cout << std::endl;
std::cout << "Floating-point type = " << root_infos[tp].short_typename << std::endl;
std::cout << "Floating-point type = " << root_infos[tp].full_typename << std::endl;
std::cout << "Max_digits10 = " << root_infos[tp].max_digits10 << std::endl;
std::cout << "Binary digits = " << root_infos[tp].bin_digits << std::endl;
std::cout << "Accuracy digits = " << root_infos[tp].get_digits << std::endl;
std::cout << "min_time = " << root_infos[tp].min_time << std::endl;
std::cout << std::setprecision(root_infos[tp].max_digits10 ) << "Roots = ";
std::copy(root_infos[tp].full_results.begin(), root_infos[tp].full_results.end(), std::ostream_iterator<cpp_bin_float_100>(std::cout, " "));
std::cout << std::endl;
// Header row.
std::cout << "Algorithm " << "Iterations " << "Times " << "Norm_times " << "Distance" << std::endl;
std::vector<std::string>::iterator al_iter = algo_names.begin();
// Row for all algorithms.
for (int algo = 0; algo != algo_names.size(); algo++)
{
std::cout
<< std::left << std::setw(20) << algo_names[algo] << " "
<< std::setw(8) << std::setprecision(2) << root_infos[tp].iterations[algo] << " "
<< std::setw(8) << std::setprecision(5) << root_infos[tp].times[algo] << " "
<< std::setw(8) << std::setprecision(3) << root_infos[tp].normed_times[algo] << " "
<< std::setw(8) << std::setprecision(2) << root_infos[tp].distances[algo]
<< std::endl;
} // for algo
} // for tp
// Print info as Quickbook table.
fout << "[table:cbrt_5 Info for float, double, long double and cpp_bin_float_50\n"
<< "[[type name] [max_digits10] [binary digits] [required digits]]\n";// header.
for (size_t tp = 0; tp != root_infos.size(); tp++)
{ // For all types:
fout << "["
<< "[" << root_infos[tp].short_typename << "]"
<< "[" << root_infos[tp].max_digits10 << "]" // max_digits10
<< "[" << root_infos[tp].bin_digits << "]"// < "Binary digits
<< "[" << root_infos[tp].get_digits << "]]\n"; // Accuracy digits.
} // tp
fout << "] [/table cbrt_5] \n" << std::endl;
// Prepare Quickbook table of floating-point types.
fout << "[table:cbrt_4 Cube root(28) for float, double, long double and cpp_bin_float_50\n"
<< "[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]\n"
<< "[[Algorithm]";
for (size_t tp = 0; tp != root_infos.size(); tp++)
{ // For all types:
fout << "[Its]" << "[Times]" << "[Norm]" << "[Dis]" << "[ ]";
}
fout << "]" << std::endl;
// Row for all algorithms.
for (int algo = 0; algo != algo_names.size(); algo++)
{
fout << "[[" << std::left << std::setw(9) << algo_names[algo] << "]";
for (size_t tp = 0; tp != root_infos.size(); tp++)
{ // For all types:
fout
<< "[" << std::right << std::showpoint
<< std::setw(3) << std::setprecision(2) << root_infos[tp].iterations[algo] << "]["
<< std::setw(5) << std::setprecision(5) << root_infos[tp].times[algo] << "]["
<< std::setw(3) << std::setprecision(2) << root_infos[tp].normed_times[algo] << "]["
<< std::setw(3) << std::setprecision(2) << root_infos[tp].distances[algo] << "][ ]";
} // tp
fout <<"]" << std::endl;
} // for algo
fout << "] [/end of table cbrt_4]\n";
} // void table_root_info
int main()
{
using namespace boost::multiprecision;
using namespace boost::math;
try
{
std::cout << "Tests run with " << BOOST_COMPILER << ", "
<< BOOST_STDLIB << ", " << BOOST_PLATFORM << ", ";
if (fout.is_open())
{
std::cout << "\nOutput to " << filename << std::endl;
}
else
{ // Failed to open.
std::cout << " Open file " << filename << " for output failed!" << std::endl;
std::cout << "error" << errno << std::endl;
return boost::exit_failure;
}
fout <<
"[/""\n"
"Copyright 2015 Paul A. Bristow.""\n"
"Copyright 2015 John Maddock.""\n"
"Distributed under the Boost Software License, Version 1.0.""\n"
"(See accompanying file LICENSE_1_0.txt or copy at""\n"
"http://www.boost.org/LICENSE_1_0.txt).""\n"
"]""\n"
<< std::endl;
std::string debug_or_optimize;
#ifdef _DEBUG
#if (_DEBUG == 0)
debug_or_optimize = "Compiled in debug mode.";
#else
debug_or_optimize = "Compiled in optimise mode.";
#endif
#endif
// Print out the program/compiler/stdlib/platform names as a Quickbook comment:
fout << "\n[h5 Program " << sourcefilename << ", "
<< BOOST_COMPILER << ", "
<< BOOST_STDLIB << ", "
<< BOOST_PLATFORM << ", "
<< debug_or_optimize << "[br]"
<< count << " evaluations of each of " << algo_names.size() << " root_finding algorithms.[br]"
<< "Fraction of maximum possible bits of accuracy required is " << digits_accuracy
<< "]"
<< std::endl;
std::cout << count << " evaluations of root_finding." << std::endl;
BOOST_MATH_CONTROL_FP;
cpp_bin_float_100 full_value("28");
cpp_bin_float_100 full_answer ("3.036588971875662519420809578505669635581453977248111123242141654169177268411884961770250390838097895");
std::copy(max_digits10s.begin(), max_digits10s.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << std::endl;
table_root_info(full_value, full_answer);
return boost::exit_success;
}
catch (std::exception ex)
{
std::cout << "exception thrown: " << ex.what() << std::endl;
return boost::exit_failure;
}
} // int main()
/*
debug
1> float, maxdigits10 = 9
1> 6 algorithms used.
1> Digits required = 24.0000000
1> find root of 28.0000000, expected answer = 3.03658897
1> Times 156 312 18750 4375 3437 3906
1> Iterations: 0 0 8 6 4 5
1> Distance: 0 0 -1 0 0 0
1> Roots: 3.03658891 3.03658891 3.03658915 3.03658891 3.03658891 3.03658891
release
1> float, maxdigits10 = 9
1> 6 algorithms used.
1> Digits required = 24.0000000
1> find root of 28.0000000, expected answer = 3.03658897
1> Times 0 312 6875 937 937 937
1> Iterations: 0 0 8 6 4 5
1> Distance: 0 0 -1 0 0 0
1> Roots: 3.03658891 3.03658891 3.03658915 3.03658891 3.03658891 3.03658891
1>
1> 5 algorithms used:
1> 10 algorithms used:
1> boost::math::cbrt TOMS748 Newton Halley Shroeder boost::math::cbrt TOMS748 Newton Halley Shroeder
1> 2 types compared.
1> Precision of full type = 102 decimal digits
1> Find root of 28.000000000000000,
1> Expected answer = 3.0365889718756625
1> typeid(T).name()float, maxdigits10 = 9
1> find root of 28.0000000, expected answer = 3.03658897
1>
1> Iterations: 0 8 6 4 5
1> Times 468 8437 4375 3593 4062
1> Min Time 468
1> Normalized Times 1.00 18.0 9.35 7.68 8.68
1> Distance: 0 -1 0 0 0
1> Roots: 3.03658891 3.03658915 3.03658891 3.03658891 3.03658891
1> ==================================================================
1> typeid(T).name()double, maxdigits10 = 17
1> find root of 28.000000000000000, expected answer = 3.0365889718756625
1>
1> Iterations: 0 11 7 5 6
1> Times 312 15000 4531 3906 4375
1> Min Time 312
1> Normalized Times 1.00 48.1 14.5 12.5 14.0
1> Distance: 1 2 0 0 0
1> Roots: 3.0365889718756622 3.0365889718756618 3.0365889718756627 3.0365889718756627 3.0365889718756627
1> ==================================================================
Release
1> 5 algorithms used:
1> 10 algorithms used:
1> boost::math::cbrt TOMS748 Newton Halley Shroeder boost::math::cbrt TOMS748 Newton Halley Shroeder
1> 2 types compared.
1> Precision of full type = 102 decimal digits
1> Find root of 28.000000000000000,
1> Expected answer = 3.0365889718756625
1> typeid(T).name()float, maxdigits10 = 9
1> find root of 28.0000000, expected answer = 3.03658897
1>
1> Iterations: 0 8 6 4 5
1> Times 312 781 937 937 937
1> Min Time 312
1> Normalized Times 1.00 2.50 3.00 3.00 3.00
1> Distance: 0 -1 0 0 0
1> Roots: 3.03658891 3.03658915 3.03658891 3.03658891 3.03658891
1> ==================================================================
1> typeid(T).name()double, maxdigits10 = 17
1> find root of 28.000000000000000, expected answer = 3.0365889718756625
1>
1> Iterations: 0 11 7 5 6
1> Times 312 1093 937 937 937
1> Min Time 312
1> Normalized Times 1.00 3.50 3.00 3.00 3.00
1> Distance: 1 2 0 0 0
1> Roots: 3.0365889718756622 3.0365889718756618 3.0365889718756627 3.0365889718756627 3.0365889718756627
1> ==================================================================
1> 5 algorithms used:
1> 15 algorithms used:
1> boost::math::cbrt TOMS748 Newton Halley Shroeder boost::math::cbrt TOMS748 Newton Halley Shroeder boost::math::cbrt TOMS748 Newton Halley Shroeder
1> 3 types compared.
1> Precision of full type = 102 decimal digits
1> Find root of 28.00000000000000000000000000000000000000000000000000,
1> Expected answer = 3.036588971875662519420809578505669635581453977248111
1> typeid(T).name()float, maxdigits10 = 9
1> find root of 28.0000000, expected answer = 3.03658897
1>
1> Iterations: 0 8 6 4 5
1> Times 156 781 937 1093 937
1> Min Time 156
1> Normalized Times 1.00 5.01 6.01 7.01 6.01
1> Distance: 0 -1 0 0 0
1> Roots: 3.03658891 3.03658915 3.03658891 3.03658891 3.03658891
1> ==================================================================
1> typeid(T).name()double, maxdigits10 = 17
1> find root of 28.000000000000000, expected answer = 3.0365889718756625
1>
1> Iterations: 0 11 7 5 6
1> Times 312 1093 937 937 937
1> Min Time 312
1> Normalized Times 1.00 3.50 3.00 3.00 3.00
1> Distance: 1 2 0 0 0
1> Roots: 3.0365889718756622 3.0365889718756618 3.0365889718756627 3.0365889718756627 3.0365889718756627
1> ==================================================================
1> typeid(T).name()class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,0>, maxdigits10 = 52
1> find root of 28.00000000000000000000000000000000000000000000000000, expected answer = 3.036588971875662519420809578505669635581453977248111
1>
1> Iterations: 0 13 9 6 7
1> Times 8750 177343 30312 52968 58125
1> Min Time 8750
1> Normalized Times 1.00 20.3 3.46 6.05 6.64
1> Distance: 0 0 -1 0 0
1> Roots: 3.036588971875662519420809578505669635581453977248106 3.036588971875662519420809578505669635581453977248106 3.036588971875662519420809578505669635581453977248117 3.036588971875662519420809578505669635581453977248106 3.036588971875662519420809578505669635581453977248106
1> ==================================================================
Reduce accuracy required to 0.5
1> 5 algorithms used:
1> 15 algorithms used:
1> boost::math::cbrt TOMS748 Newton Halley Shroeder
1> 3 floating_point types compared.
1> Precision of full type = 102 decimal digits
1> Find root of 28.00000000000000000000000000000000000000000000000000,
1> Expected answer = 3.036588971875662519420809578505669635581453977248111
1> typeid(T).name() = float, maxdigits10 = 9
1> Digits accuracy fraction required = 0.500000000
1> find root of 28.0000000, expected answer = 3.03658897
1>
1> Iterations: 0 8 5 3 4
1> Times 156 5937 1406 1250 1250
1> Min Time 156
1> Normalized Times 1.0 38. 9.0 8.0 8.0
1> Distance: 0 -1 0 0 0
1> Roots: 3.03658891 3.03658915 3.03658891 3.03658891 3.03658891
1> ==================================================================
1> typeid(T).name() = double, maxdigits10 = 17
1> Digits accuracy fraction required = 0.50000000000000000
1> find root of 28.000000000000000, expected answer = 3.0365889718756625
1>
1> Iterations: 0 8 6 4 5
1> Times 156 6250 1406 1406 1250
1> Min Time 156
1> Normalized Times 1.0 40. 9.0 9.0 8.0
1> Distance: 1 3695766 0 0 0
1> Roots: 3.0365889718756622 3.0365889702344129 3.0365889718756627 3.0365889718756627 3.0365889718756627
1> ==================================================================
1> typeid(T).name() = class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,0>, maxdigits10 = 52
1> Digits accuracy fraction required = 0.5000000000000000000000000000000000000000000000000000
1> find root of 28.00000000000000000000000000000000000000000000000000, expected answer = 3.036588971875662519420809578505669635581453977248111
1>
1> Iterations: 0 11 8 5 6
1> Times 11562 239843 34843 47500 47812
1> Min Time 11562
1> Normalized Times 1.0 21. 3.0 4.1 4.1
1> Distance: 0 0 -1 0 0
1> Roots: 3.036588971875662519420809578505669635581453977248106 3.036588971875662519420809578505669635581453977248106 3.036588971875662519420809578505669635581453977248117 3.036588971875662519420809578505669635581453977248106 3.036588971875662519420809578505669635581453977248106
1> ==================================================================
*/

View File

@@ -12,10 +12,6 @@
// Note that this file contains Quickbook mark-up as well as code
// and comments, don't change any of the special comment mark-ups!
//#ifdef _MSC_VER
//# pragma warning(disable: 4180) // qualifier has no effect (in Fusion).
//#endif
//#define BOOST_MATH_INSTRUMENT
/*
@@ -27,8 +23,8 @@ It shows how use of derivatives can improve the speed.
implementation of `boost::math::cbrt`, mainly by using a better computed initial 'guess'
at `<boost/math/special_functions/cbrt.hpp>`).
Then we show how a high roots (fifth) can be computed,
and in root_finding_n_example.cpp a generic method
Then we show how a higher root (fifth) can be computed,
and in `root_finding_n_example.cpp` a generic method
for the ['n]th root that constructs the derivatives at compile-time,
These methods should be applicable to other functions that can be differentiated easily.
@@ -135,7 +131,7 @@ T cbrt_noderiv(T x)
int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
// Some fraction of digits is used to control how accurate to try to make the result.
int get_digits = (digits * 3) /4; // Near maximum (3/4) possible accuracy.
eps_tolerance<double> tol(get_digits); // Set the tolerance.
eps_tolerance<T> tol(get_digits); // Set the tolerance.
std::pair<T, T> r =
bracket_and_solve_root(cbrt_functor_noderiv<T>(x), guess, factor, is_rising, tol, it);
return r.first + (r.second - r.first)/2; // Midway between brackets.
@@ -156,12 +152,12 @@ So it may be wise to chose some reasonable estimate of how many iterations may b
if (it >= maxit)
{
std::cout << "Unable to locate solution in " << maxit << " iterations:"
" Current best guess is between " << r.first << " and " << r.second << std::endl;
std::cout << "Unable to locate solution in " << maxit << " iterations:"
" Current best guess is between " << r.first << " and " << r.second << std::endl;
}
else
{
std::cout << "Converged after " << it << " (from maximum of " << maxit << " iterations)." << std::endl;
std::cout << "Converged after " << it << " (from maximum of " << maxit << " iterations)." << std::endl;
}
for output like
@@ -200,10 +196,10 @@ To \'return\' two values, we use a `std::pair` of floating-point values:
template <class T>
struct cbrt_functor_deriv
{ // Functor also returning 1st derviative.
{ // Functor also returning 1st derivative.
cbrt_functor_deriv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor stores value a to find root of,
// for example: calling cbrt_functor_deriv<T>(x) to use to get cube root of x.
// for example: calling cbrt_functor_deriv<T>(a) to use to get cube root of a.
}
std::pair<T, T> operator()(T const& x)
{ // Return both f(x) and f'(x).
@@ -212,7 +208,7 @@ struct cbrt_functor_deriv
return std::make_pair(fx, dx); // 'return' both fx and dx.
}
private:
T a; // to be 'cube_rooted'.
T a; // Store value to be 'cube_rooted'.
};
/*`Our cube root function is now:*/
@@ -404,8 +400,8 @@ int main()
//[root_finding_main_1
try
{
double threecubed = 27.; // value that has an exactly representable integer cube root.
double threecubedp1 = 28.; // whose cube root is *not* exactly representable.
double threecubed = 27.; // Value that has an *exactly representable* integer cube root.
double threecubedp1 = 28.; // Value whose cube root is *not* exactly representable.
std::cout << "cbrt(28) " << boost::math::cbrt(28.) << std::endl; // boost::math:: version of cbrt.
std::cout << "std::cbrt(28) " << std::cbrt(28.) << std::endl; // std:: version of cbrt.

View File

@@ -162,7 +162,7 @@ template <class T>
T fifth_noderiv(T x)
{ //! \returns fifth root of x using bracket_and_solve (no derivatives).
using namespace std; // Help ADL of std functions.
using namespace boost::math; // For bracket_and_solve_root.
using namespace boost::math::tools; // For bracket_and_solve_root.
int exponent;
frexp(x, &exponent); // Get exponent of z (ignore mantissa).

View File

@@ -39,6 +39,8 @@
#include <tuple>
#include <utility> // pair, make_pair
// #define BUILTIN_POW_GUESS // define to use std::pow function to obtain a guess.
template <class T>
T cbrt_2deriv(T x)
{ // return cube root of x using 1st and 2nd derivatives and Halley.
@@ -46,21 +48,32 @@ T cbrt_2deriv(T x)
using namespace boost::math::tools; // For halley_iterate.
// If T is not a binary floating-point type, for example, cpp_dec_float_50
// then frexp is not defined, so it is necessary to compute the guess using a built-in type,
// then frexp may not be defined,
// so it may be necessary to compute the guess using a built-in type,
// probably quickest using double, but perhaps with float or long double.
typedef double guess_type;
// Note that the range of exponent may be restricted by a built-in-type for guess.
typedef long double guess_type;
#ifdef BUILTIN_POW_GUESS
guess_type pow_guess = std::pow(static_cast<guess_type>(x), static_cast<guess_type>(1) / 3);
T guess = pow_guess;
T min = pow_guess /2;
T max = pow_guess * 2;
#else
int exponent;
frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
T guess = ldexp(static_cast<guess_type>(1.), exponent / 3); // Rough guess is to divide the exponent by three.
T min = ldexp(static_cast<guess_type>(1.) / 2, exponent / 3); // Minimum possible value is half our guess.
T max = ldexp(static_cast<guess_type>(2.), exponent / 3); // Maximum possible value is twice our guess.
#endif
int digits = std::numeric_limits<T>::digits / 2; // Half maximum possible binary digits accuracy for type T.
const boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = halley_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, digits, it);
// Can show how many iterations (updated by halley_iterate).
// std::cout << "Iterations " << maxit << std::endl;
// std::cout << "Iterations " << it << " (from max of "<< maxit << ")." << std::endl;
return result;
} // cbrt_2deriv(x)
@@ -76,6 +89,7 @@ struct cbrt_functor_2deriv
std::tuple<T, T, T> operator()(T const& x)
{ // Return both f(x) and f'(x) and f''(x).
T fx = x*x*x - a; // Difference (estimate x^3 - value).
// std::cout << "x = " << x << "\nfx = " << fx << std::endl;
T dx = 3 * x*x; // 1st derivative = 3x^2.
T d2x = 6 * x; // 2nd derivative = 6x.
return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
@@ -124,7 +138,7 @@ T nth_2deriv(T x)
boost::uintmax_t it = maxit;
T result = halley_iterate(nth_functor_2deriv<n, T>(x), guess, min, max, digits, it);
// Can show how many iterations (updated by halley_iterate).
cout << it << " iterations (from max of " << maxit << ")" << endl;
std::cout << it << " iterations (from max of " << maxit << ")" << std::endl;
return result;
} // nth_2deriv(x)
@@ -203,6 +217,15 @@ int main()
/*
Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Release\root_finding_multiprecision.exe"
Multiprecision Root finding Example.
cbrt(2) = 1.2599210498948731647672106072782283505702514647015
cbrt(2) = 1.2599210498948731906665443602832965552806854248047
cbrt(2) = 1.2599210498948731647672106072782283505702514647015
cbrt(2) = 1.2599210498948731647672106072782283505702514647015
value = 2, cube root =1.25992104989487
value = 2, cube root =1.25992104989487
value = 2, cube root =1.2599210498948731647672106072782283505702514647015
*/

View File

@@ -26,7 +26,7 @@
#include <boost/multiprecision/cpp_dec_float.hpp> // For cpp_dec_float_50.
#include <boost/multiprecision/cpp_bin_float.hpp> // using boost::multiprecision::cpp_bin_float_50;
#ifndef _MSC_VER // float128 is not yet supported by Microsoft compiler at 2013.
#include <boost/multiprecision/float128.hpp>
# include <boost/multiprecision/float128.hpp>
#endif
#include <iostream>
@@ -73,14 +73,14 @@ std::cout << " x = " << x << ", fx = " << fx << ", dx = " << dx << ", dx2 = " <<
#endif
*/
// If T is a floating-point type, might be quick to compute the guess using a built-in type,
// If T is a floating-point type, might be quicker to compute the guess using a built-in type,
// probably quickest using double, but perhaps with float or long double, T.
// If T is not a floating-point type for which frexp and ldexp are not defined,
// If T is a type for which frexp and ldexp are not defined,
// then it is necessary to compute the guess using a built-in type,
// probably quickest (but limited range) using double,
// but perhaps with float or long double or a multiprecision T for greater range.
// typedef double guess_type;
// but perhaps with float or long double, or a multiprecision T for the full range of T.
// typedef double guess_type; is used to specify the this.
//[root_finding_nth_function_2deriv
@@ -95,7 +95,7 @@ T nth_2deriv(T x)
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
BOOST_STATIC_ASSERT_MSG((N > 1000) == false, "root N is too big!");
typedef double guess_type;
typedef double guess_type; // double may restrict (exponent) range for a multiprecision T?
int exponent;
frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
@@ -154,7 +154,7 @@ int main()
show_nth_root<5, double>(2.);
show_nth_root<5, long double>(2.);
#ifndef _MSC_VER // float128 is not supported by Microsoft compiler 2013.
show_nth_root<float128, 5>(2);
show_nth_root<5, float128>(2);
#endif
show_nth_root<5, cpp_dec_float_50>(2); // dec
show_nth_root<5, cpp_bin_float_50>(2); // bin
@@ -178,6 +178,7 @@ int main()
/*
//[root_finding_example_output_1
Using MSVC 2013
nth Root finding Example.
Type double value = 2, 5th root = 1.14869835499704
@@ -188,4 +189,24 @@ Type class boost::multiprecision::number<class boost::multiprecision::backends::
5th root = 1.1486983549970350067986269467779275894438508890978
//] [/root_finding_example_output_1]
*/
//[root_finding_example_output_2
Using GCC 4.91 (includes float_128 type)
nth Root finding Example.
Type d value = 2, 5th root = 1.14869835499704
Type e value = 2, 5th root = 1.14869835499703501
Type N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE value = 2, 5th root = 1.148698354997035006798626946777928
Type N5boost14multiprecision6numberINS0_8backends13cpp_dec_floatILj50EivEELNS0_26expression_template_optionE1EEE value = 2, 5th root = 1.1486983549970350067986269467779275894438508890978
Type N5boost14multiprecision6numberINS0_8backends13cpp_bin_floatILj50ELNS2_15digit_base_typeE10EviLi0ELi0EEELNS0_26expression_template_optionE0EEE value = 2, 5th root = 1.1486983549970350067986269467779275894438508890978
RUN SUCCESSFUL (total time: 63ms)
//] [/root_finding_example_output_2]
*/
/*
Throw out of range using GCC release mode :-(
*/

View File

@@ -0,0 +1,874 @@
// Copyright Paul A. Bristow 2015
// 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)
// Comparison of finding roots using TOMS748, Newton-Raphson, Halley & Schroeder algorithms.
// root_n_finding_algorithms.cpp Generalised for nth root version.
// http://en.wikipedia.org/wiki/Cube_root
// Note that this file contains Quickbook mark-up as well as code
// and comments, don't change any of the special comment mark-ups!
// This program also writes files in Quickbook tables mark-up format.
#include <boost/cstdlib.hpp>
#include <boost/config.hpp>
#include <boost/array.hpp>
#include <boost/type_traits/is_floating_point.hpp>
#include <boost/math/special_functions/math_fwd.hpp>
#include <boost/math/concepts/real_concept.hpp>
#include <boost/utility/enable_if.hpp>
#include <boost/math/tools/roots.hpp>
//using boost::math::policies::policy;
//using boost::math::tools::eps_tolerance; // Binary functor for specified number of bits.
//using boost::math::tools::bracket_and_solve_root;
//using boost::math::tools::toms748_solve;
//using boost::math::tools::halley_iterate;
//using boost::math::tools::newton_raphson_iterate;
//using boost::math::tools::schroeder_iterate;
#include <boost/math/special_functions/next.hpp> // For float_distance.
#include <boost/math/special_functions/pow.hpp> // For float_distance.
#include <boost/math/tools/tuple.hpp> // for tuple and make_tuple.
#include <boost/multiprecision/cpp_bin_float.hpp> // is binary.
using boost::multiprecision::cpp_bin_float_100;
using boost::multiprecision::cpp_bin_float_50;
#include <boost/timer/timer.hpp>
#include <boost/system/error_code.hpp>
#include <boost/multiprecision/cpp_bin_float/io.hpp>
#include <boost/preprocessor/stringize.hpp>
// STL
#include <iostream>
#include <iomanip>
#include <string>
#include <vector>
#include <limits>
#include <fstream> // std::ofstream
#include <cmath>
#include <typeinfo> // for type name using typid(thingy).name();
#ifdef __FILE__
std::string sourcefilename = __FILE__;
#else
std::string sourcefilename("");
#endif
#ifdef NDEBUG
std::string root = BOOST_STRINGIZE($(BOOST_ROOT));
#endif
#ifndef BOOST_ROOT
# define BOOST_ROOT i:/modular-boost/
#endif
#ifdef BOOST_ROOT
std::string boost_root = BOOST_STRINGIZE(BOOST_ROOT);
#endif
std::string fp_hardware; // Any hardware features like SEE or AVX
const std::string roots_name = "libs/math/doc/roots/";
const std::string full_roots_name(boost_root + "libs/math/doc/roots/");
const std::size_t nooftypes = 4;
const std::size_t noofalgos = 4;
const std::size_t noofroots = 3;
double digits_accuracy = 1.0; // 1 == maximum possible accuracy.
std::stringstream ss;
std::ofstream fout;
std::vector<std::string> algo_names =
{
"TOMS748", "Newton", "Halley", "Schroeder"
};
std::vector<std::string> names =
{
"float", "double", "long double", "cpp_bin_float50"
};
uintmax_t iters; // Global as value of iterations is not returned.
struct root_info
{ // for a floating-point type, float, double ...
std::size_t max_digits10; // for type.
std::string full_typename; // for type from type_id.name().
std::string short_typename; // for type "float", "double", "cpp_bin_float_50" ....
std::size_t bin_digits; // binary in floating-point type numeric_limits<T>::digits;
int get_digits; // fraction of maximum possible accuracy required.
// = digits * digits_accuracy
// Vector of values (4) for each algorithm, TOMS748, Newton, Halley & Schroeder.
//std::vector< boost::int_least64_t> times; converted to int.
std::vector<int> times; // arbirary units (ticks).
//boost::int_least64_t min_time = std::numeric_limits<boost::int_least64_t>::max(); // Used to normalize times (as int).
std::vector<double> normed_times;
int min_time = std::numeric_limits<int>::max(); // Used to normalize times.
std::vector<uintmax_t> iterations;
std::vector<long int> distances;
std::vector<cpp_bin_float_100> full_results;
}; // struct root_info
std::vector<root_info> root_infos; // One element for each floating-point type used.
inline std::string build_test_name(const char* type_name, const char* test_name)
{
std::string result(BOOST_COMPILER);
result += "|";
result += BOOST_STDLIB;
result += "|";
result += BOOST_PLATFORM;
result += "|";
result += type_name;
result += "|";
result += test_name;
#ifdef _DEBUG
// Assume preprocessor defines provided for MSVC and added for GCC -D_DEBUG=1 or
#if (_DEBUG == 0)
result += "|";
result += " debug";
#else // for GCC -D_DEBUG=1
result += "|";
result += " release";
#endif
#endif
result += "|";
return result;
} // std::string build_test_name
// Algorithms //////////////////////////////////////////////
// No derivatives - using TOMS748 internally.
template <int N, typename T = double>
struct nth_root_functor_noderiv
{ // Nth root of x using only function - no derivatives.
nth_root_functor_noderiv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor just stores value a to find root of.
}
T operator()(T const& x)
{
using boost::math::pow;
T fx = pow<N>(x) -a; // Difference (estimate x^n - a).
return fx;
}
private:
T a; // to be 'cube_rooted'.
}; // template <int N, class T> struct nth_root_functor_noderiv
template <int N, class T = double>
T nth_root_noderiv(T x)
{ // return Nth root of x using bracket_and_solve (using NO derivatives).
using namespace std; // Help ADL of std functions.
using namespace boost::math::tools; // For bracket_and_solve_root.
typedef double guess_type;
int exponent;
frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
T guess = static_cast<T>(ldexp(static_cast<guess_type>(1.), exponent / N)); // Rough guess is to divide the exponent by n.
//T min = static_cast<T>(ldexp(static_cast<guess_type>(1.) / 2, exponent / N)); // Minimum possible value is half our guess.
//T max = static_cast<T>(ldexp(static_cast<guess_type>(2.), exponent / N)); // Maximum possible value is twice our guess.
T factor = 2; // How big steps to take when searching.
const boost::uintmax_t maxit = 50; // Limit to maximum iterations.
boost::uintmax_t it = maxit; // Initally our chosen max iterations, but updated with actual.
bool is_rising = true; // So if result if guess^3 is too low, then try increasing guess.
int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
// Some fraction of digits is used to control how accurate to try to make the result.
int get_digits = static_cast<int>(digits * digits_accuracy);
eps_tolerance<T> tol(get_digits); // Set the tolerance.
std::pair<T, T> r;
r = bracket_and_solve_root(nth_root_functor_noderiv<N, T>(x), guess, factor, is_rising, tol, it);
iters = it;
T result = r.first + (r.second - r.first) / 2; // Midway between brackets.
return result;
} // template <class T> T nth_root_noderiv(T x)
// Using 1st derivative only Newton-Raphson
template <int N, class T = double>
struct nth_root_functor_1deriv
{ // Functor also returning 1st derviative.
BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
nth_root_functor_1deriv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor stores value a to find root of, for example:
}
std::pair<T, T> operator()(T const& x)
{ // Return both f(x) and f'(x).
using boost::math::pow; // // Compile-time integral power.
T fx = pow<N>(x) - a; // Difference (estimate x^n - a).
T dx = N * pow<N - 1>(x); // 1st derivative f'(x).
return std::make_pair(fx, dx); // 'return' both fx and dx.
}
private:
T a; // to be 'nth_rooted'.
}; // struct nthroot__functor_1deriv
template <int N, class T = double>
T nth_root_1deriv(T x)
{ // return nth root of x using 1st derivative and Newton_Raphson.
using namespace std; // Help ADL of std functions.
using namespace boost::math::tools; // For newton_raphson_iterate.
BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
BOOST_STATIC_ASSERT_MSG((N > 1000) == false, "root N is too big!");
typedef double guess_type;
int exponent;
frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
T guess = static_cast<T>(ldexp(static_cast<guess_type>(1.), exponent / N)); // Rough guess is to divide the exponent by n.
T min = static_cast<T>(ldexp(static_cast<guess_type>(1.) / 2, exponent / N)); // Minimum possible value is half our guess.
T max = static_cast<T>(ldexp(static_cast<guess_type>(2.), exponent / N)); // Maximum possible value is twice our guess.
int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
int get_digits = static_cast<int>(digits * digits_accuracy);
const boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = newton_raphson_iterate(nth_root_functor_1deriv<N, T>(x), guess, min, max, get_digits, it);
iters = it;
return result;
} // T nth_root_1_deriv Newton-Raphson
// Using 1st and 2nd derivatives with Halley algorithm.
template <int N, class T = double>
struct nth_root_functor_2deriv
{ // Functor returning both 1st and 2nd derivatives.
BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
nth_root_functor_2deriv(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor stores value a to find root of, for example:
}
// using boost::math::tuple; // to return three values.
std::tuple<T, T, T> operator()(T const& x)
{ // Return f(x), f'(x) and f''(x).
using boost::math::pow; // Compile-time integral power.
T fx = pow<N, T>(x) - a; // Difference (estimate x^n - a).
T dx = N * pow<N - 1, T>(x); // 1st derivative f'(x).
T d2x = N * (N - 1) * pow<N - 2, T>(x); // 2nd derivative f''(x).
return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
}
private:
T a; // to be 'nth_rooted'.
};
template <int N, class T = double>
T nth_root_2deriv(T x)
{ // return nth root of x using 1st and 2nd derivatives and Halley.
using namespace std; // Help ADL of std functions.
using namespace boost::math::tools; // For halley_iterate.
BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
BOOST_STATIC_ASSERT_MSG((N > 1000) == false, "root N is too big!");
typedef double guess_type;
int exponent;
frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
T guess = static_cast<T>(ldexp(static_cast<guess_type>(1.), exponent / N)); // Rough guess is to divide the exponent by n.
T min = static_cast<T>(ldexp(static_cast<guess_type>(1.) / 2, exponent / N)); // Minimum possible value is half our guess.
T max = static_cast<T>(ldexp(static_cast<guess_type>(2.), exponent / N)); // Maximum possible value is twice our guess.
int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
int get_digits = static_cast<int>(digits * digits_accuracy);
const boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = halley_iterate(nth_root_functor_2deriv<N, T>(x), guess, min, max, get_digits, it);
iters = it;
return result;
} // nth_2deriv Halley
// Using 1st and 2nd derivatives using Schroeder algorithm.
template <int N, class T = double>
struct nth_root_functor_2deriv_s
{ // Functor returning nth root using both 1st and 2nd derivatives.
BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
nth_root_functor_2deriv_s(T const& to_find_root_of) : a(to_find_root_of)
{ // Constructor stores value a to find root of, for example:
}
// using boost::math::tuple; // to return three values.
std::tuple<T, T, T> operator()(T const& x)
{ // Return f(x), f'(x) and f''(x).
using boost::math::pow;
T fx = pow<N>(x) -a; // Difference (estimate x^n - a).
T dx = N * pow<N - 1>(x); // 1st derivative f'(x).
T d2x = N * (N - 1) * pow<N - 2 >(x); // 2nd derivative f''(x).
return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
}
private:
T a; // to be 'nth_rooted'.
}; // template <int N, class T = double> struct nth_root_functor_2deriv_s
template <int N, class T = double>
T nth_root_2deriv_s(T x)
{ // return nth root of x using 1st and 2nd derivatives and Schroeder.
using namespace std; // Help ADL of std functions.
using namespace boost::math::tools; // For schroeder_iterate.
BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
BOOST_STATIC_ASSERT_MSG((N > 0) == true, "root N must be > 0!");
BOOST_STATIC_ASSERT_MSG((N > 1000) == false, "root N is too big!");
typedef double guess_type;
int exponent;
frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
T guess = static_cast<T>(ldexp(static_cast<guess_type>(1.), exponent / N)); // Rough guess is to divide the exponent by n.
T min = static_cast<T>(ldexp(static_cast<guess_type>(1.) / 2, exponent / N)); // Minimum possible value is half our guess.
T max = static_cast<T>(ldexp(static_cast<guess_type>(2.), exponent / N)); // Maximum possible value is twice our guess.
int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
int get_digits = static_cast<int>(digits * digits_accuracy);
const boost::uintmax_t maxit = 20;
boost::uintmax_t it = maxit;
T result = schroeder_iterate(nth_root_functor_2deriv_s<N, T>(x), guess, min, max, get_digits, it);
iters = it;
return result;
} // T nth_root_2deriv_s Schroder
//////////////////////////////////////////////////////// end of algorithms - perhaps in a separate .hpp?
//! Print 4 floating-point types info: max_digits10, digits and required accuracy digits as a Quickbook table.
int table_type_info(double digits_accuracy)
{
std::string qbk_name = full_roots_name; // Prefix by boost_root file.
qbk_name += "type_info_table";
std::stringstream ss;
ss.precision(3);
ss << "_" << digits_accuracy * 100;
qbk_name += ss.str();
#ifdef _MSC_VER
qbk_name += "_msvc.qbk";
#else // assume GCC
qbk_name += "_gcc.qbk";
#endif
// Example: type_info_table_100_msvc.qbk
fout.open(qbk_name, std::ios_base::out);
if (fout.is_open())
{
std::cout << "Output type table to " << qbk_name << std::endl;
}
else
{ // Failed to open.
std::cout << " Open file " << qbk_name << " for output failed!" << std::endl;
std::cout << "errno " << errno << std::endl;
return errno;
}
fout <<
"[/"
<< qbk_name
<< "\n"
"Copyright 2015 Paul A. Bristow.""\n"
"Copyright 2015 John Maddock.""\n"
"Distributed under the Boost Software License, Version 1.0.""\n"
"(See accompanying file LICENSE_1_0.txt or copy at""\n"
"http://www.boost.org/LICENSE_1_0.txt).""\n"
"]""\n"
<< std::endl;
fout << "[h6 Fraction of maximum possible bits of accuracy required is " << digits_accuracy << ".]\n" << std::endl;
std::string table_id("type_info");
table_id += ss.str(); // Fraction digits accuracy.
#ifdef _MSC_VER
table_id += "_msvc";
#else // assume GCC
table_id += "_gcc";
#endif
fout << "[table:" << table_id << " Digits for float, double, long double and cpp_bin_float_50\n"
<< "[[type name] [max_digits10] [binary digits] [required digits]]\n";// header.
// For all fout types:
fout << "[[" << "float" << "]"
<< "[" << std::numeric_limits<float>::max_digits10 << "]" // max_digits10
<< "[" << std::numeric_limits<float>::digits << "]"// < "Binary digits
<< "[" << static_cast<int>(std::numeric_limits<float>::digits * digits_accuracy) << "]]\n"; // Accuracy digits.
fout << "[[" << "float" << "]"
<< "[" << std::numeric_limits<double>::max_digits10 << "]" // max_digits10
<< "[" << std::numeric_limits<double>::digits << "]"// < "Binary digits
<< "[" << static_cast<int>(std::numeric_limits<double>::digits * digits_accuracy) << "]]\n"; // Accuracy digits.
fout << "[[" << "long double" << "]"
<< "[" << std::numeric_limits<long double>::max_digits10 << "]" // max_digits10
<< "[" << std::numeric_limits<long double>::digits << "]"// < "Binary digits
<< "[" << static_cast<int>(std::numeric_limits<long double>::digits * digits_accuracy) << "]]\n"; // Accuracy digits.
fout << "[[" << "cpp_bin_float_50" << "]"
<< "[" << std::numeric_limits<cpp_bin_float_50>::max_digits10 << "]" // max_digits10
<< "[" << std::numeric_limits<cpp_bin_float_50>::digits << "]"// < "Binary digits
<< "[" << static_cast<int>(std::numeric_limits<cpp_bin_float_50>::digits * digits_accuracy) << "]]\n"; // Accuracy digits.
fout << "] [/table table_id_msvc] \n" << std::endl; // End of table.
fout.close();
return 0;
} // type_table
//! Evaluate root N timing for each algorithm, and for one floating-point type T.
template <int N, typename T>
int test_root(cpp_bin_float_100 big_value, cpp_bin_float_100 answer, const char* type_name, std::size_t type_no)
{
std::size_t max_digits = 2 + std::numeric_limits<T>::digits * 3010 / 10000;
// For new versions use max_digits10
// std::cout.precision(std::numeric_limits<T>::max_digits10);
std::cout.precision(max_digits);
std::cout << std::showpoint << std::endl; // Show trailing zeros too.
root_infos.push_back(root_info());
root_infos[type_no].max_digits10 = max_digits;
root_infos[type_no].full_typename = typeid(T).name(); // Full typename.
root_infos[type_no].short_typename = type_name; // Short typename.
root_infos[type_no].bin_digits = std::numeric_limits<T>::digits;
root_infos[type_no].get_digits = static_cast<int>(std::numeric_limits<T>::digits * digits_accuracy);
T to_root = static_cast<T>(big_value);
T result; // root
T ans = static_cast<T>(answer);
using boost::timer::nanosecond_type;
using boost::timer::cpu_times;
using boost::timer::cpu_timer;
int eval_count = 1000000; // To give a sufficiently stable timing for the fast built-in types,
//int eval_count = 1000000; // To give a sufficiently stable timing for the fast built-in types,
// This takes an inconveniently long time for multiprecision cpp_bin_float_50 etc types.
cpu_times now; // Holds wall, user and system times.
{ // Evaluate times etc for each algorithm.
//algorithm_names.push_back("TOMS748"); //
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < eval_count; ++i)
{
result = nth_root_noderiv<N, T>(to_root); //
}
now = ti.elapsed();
int time = static_cast<int>(now.user / eval_count);
root_infos[type_no].times.push_back(time); // CPU time taken.
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
ti.stop();
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
{
// algorithm_names.push_back("Newton"); // algorithm
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < eval_count; ++i)
{
result = nth_root_1deriv<N, T>(to_root); //
}
now = ti.elapsed();
int time = static_cast<int>(now.user / eval_count);
root_infos[type_no].times.push_back(time); // CPU time taken.
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
ti.stop();
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
{
//algorithm_names.push_back("Halley"); // algorithm
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < eval_count; ++i)
{
result = nth_root_2deriv<N>(to_root); //
}
now = ti.elapsed();
int time = static_cast<int>(now.user / eval_count);
root_infos[type_no].times.push_back(time); // CPU time taken.
ti.stop();
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
{
// algorithm_names.push_back("Schroeder"); // algorithm
cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
ti.start();
for (long i = 0; i < eval_count; ++i)
{
result = nth_root_2deriv_s<N>(to_root); //
}
now = ti.elapsed();
int time = static_cast<int>(now.user / eval_count);
root_infos[type_no].times.push_back(time); // CPU time taken.
if (time < root_infos[type_no].min_time)
{
root_infos[type_no].min_time = time;
}
ti.stop();
long int distance = static_cast<int>(boost::math::float_distance<T>(result, ans));
root_infos[type_no].distances.push_back(distance);
root_infos[type_no].iterations.push_back(iters); //
root_infos[type_no].full_results.push_back(result);
}
for (size_t i = 0; i != root_infos[type_no].times.size(); i++) // For each time.
{ // Normalize times.
root_infos[type_no].normed_times.push_back(static_cast<double>(root_infos[type_no].times[i]) / root_infos[type_no].min_time);
}
return 4; // eval_count of how many algorithms used.
} // test_root
/*! Fill array of times, interations, etc for Nth root for all 4 types,
and write a table of results in Quickbook format.
*/
template <int N>
void table_root_info(cpp_bin_float_100 full_value)
{
std::cout << nooftypes << " floating-point types tested:" << std::endl;
#ifdef _DEBUG
#if (_DEBUG == 0)
std::cout << "Compiled in debug mode." << std::endl;
#else
std::cout << "Compiled in optimise mode." << std::endl;
#endif
#endif
std::cout << "FP hardware " << fp_hardware << std::endl;
// Compute the 'right' answer for root N at 100 decimal digits.
cpp_bin_float_100 full_answer = nth_root_noderiv<N, cpp_bin_float_100>(full_value);
int type_count = 0;
root_infos.clear(); // Erase any previous data.
// Fill the elements of the array for each floating-point type.
type_count = test_root<N, float>(full_value, full_answer, "float", 0);
type_count = test_root<N, double>(full_value, full_answer, "double", 1);
type_count = test_root<N, long double>(full_value, full_answer, "long double", 2);
type_count = test_root<N, cpp_bin_float_50>(full_value, full_answer, "cpp_bin_float_50", 3);
// Use info from 4 floating point types to
// Prepare Quickbook table for a single root
// with columns of times, iterations, distances repeated for various floating-point types,
// and 4 rows for each algorithm.
std::stringstream table_info;
table_info.precision(3);
table_info << "[table:root_" << N << " " << N << "th root(" << static_cast<float>(full_value) << ") for float, double, long double and cpp_bin_float_50 types";
if (fp_hardware != "")
{
table_info << ", using " << fp_hardware;
}
table_info << std::endl;
fout << table_info.str()
<< "[[][float][][][] [][double][][][] [][long d][][][] [][cpp50][][]]\n"
<< "[[Algo ]";
for (size_t tp = 0; tp != nooftypes; tp++)
{ // For all types:
fout << "[Its]" << "[Times]" << "[Norm]" << "[Dis]" << "[ ]";
}
fout << "]" << std::endl;
// Row for all algorithms.
for (std::size_t algo = 0; algo != noofalgos; algo++)
{
fout << "[[" << std::left << std::setw(9) << algo_names[algo] << "]";
for (size_t tp = 0; tp != nooftypes; tp++)
{ // For all types:
fout
<< "[" << std::right << std::showpoint
<< std::setw(3) << std::setprecision(2) << root_infos[tp].iterations[algo] << "]["
<< std::setw(5) << std::setprecision(5) << root_infos[tp].times[algo] << "][";
fout << std::setw(3) << std::setprecision(3);
double normed_time = root_infos[tp].normed_times[algo];
if (abs(normed_time - 1.00) <= 0.05)
{ // At or near the best time, so show as blue.
fout << "[role blue " << normed_time << "]";
}
else if (abs(normed_time) > 4.)
{ // markedly poor so show as red.
fout << "[role red " << normed_time << "]";
}
else
{ // Not the best, so normal black.
fout << normed_time;
}
fout << "]["
<< std::setw(3) << std::setprecision(2) << root_infos[tp].distances[algo] << "][ ]";
} // tp
fout << "]" << std::endl;
} // for algo
fout << "] [/end of table root]\n";
} // void table_root_info
/*! Output program header, table of type info, and tables for 4 algorithms and 4 floating-point types,
for Nth root required digits_accuracy.
*/
int roots_tables(cpp_bin_float_100 full_value, double digits_accuracy)
{
::digits_accuracy = digits_accuracy;
// Save globally so that it is available to root-finding algorithms. Ugly :-(
#ifdef _DEBUG
# if (_DEBUG == 0)
std::string debug_or_optimize("Compiled in debug mode.");
# elif (_DEBUG == 1)
std::string debug_or_optimize("Compiled in optimise mode.");
# endif
#else
# error _DEBUG is not defined in program run. Add _DEBUG=1 to preprocessor defines for GCC?
#endif
// Create filename for roots_table
std::string qbk_name = full_roots_name;
qbk_name += "roots_table";
std::stringstream ss;
ss.precision(3);
// ss << "_" << N // now put all the tables in one .qbk file?
ss << "_" << digits_accuracy * 100
<< std::flush;
// Assume only save optimize mode runs, so don't add any _DEBUG info.
qbk_name += ss.str();
#ifdef _MSC_VER
qbk_name += "_msvc";
#else // assume GCC
qbk_name += "_gcc";
#endif
if (fp_hardware != "")
{
qbk_name += fp_hardware;
}
qbk_name += ".qbk";
fout.open(qbk_name, std::ios_base::out);
if (fout.is_open())
{
std::cout << "Output root table to " << qbk_name << std::endl;
}
else
{ // Failed to open.
std::cout << " Open file " << qbk_name << " for output failed!" << std::endl;
std::cout << "errno " << errno << std::endl;
return errno;
}
fout <<
"[/"
<< qbk_name
<< "\n"
"Copyright 2015 Paul A. Bristow.""\n"
"Copyright 2015 John Maddock.""\n"
"Distributed under the Boost Software License, Version 1.0.""\n"
"(See accompanying file LICENSE_1_0.txt or copy at""\n"
"http://www.boost.org/LICENSE_1_0.txt).""\n"
"]""\n"
<< std::endl;
// Print out the program/compiler/stdlib/platform names as a Quickbook comment:
fout << "\n[h6 Program " << sourcefilename << ",\n "
<< BOOST_COMPILER << ", "
<< BOOST_STDLIB << ", "
<< BOOST_PLATFORM << "\n"
<< debug_or_optimize
<< ((fp_hardware != "") ? ", " + fp_hardware : "")
<< "]" // [h6 close].
<< std::endl;
fout << "Fraction of full accuracy " << digits_accuracy << std::endl;
table_root_info<5>(full_value);
table_root_info<7>(full_value);
table_root_info<11>(full_value);
fout.close();
// table_type_info(digits_accuracy);
return 0;
} // roots_tables
int main()
{
using namespace boost::multiprecision;
using namespace boost::math;
try
{
std::cout << "Tests run with " << BOOST_COMPILER << ", "
<< BOOST_STDLIB << ", " << BOOST_PLATFORM << ", ";
// How to: Configure Visual C++ Projects to Target 64-Bit Platforms
// https://msdn.microsoft.com/en-us/library/9yb4317s.aspx
#ifdef _M_X64 // Defined for compilations that target x64 processors.
std::cout << "X64 " << std::endl;
fp_hardware += "_X64";
#else
# ifdef _M_IX86
std::cout << "X32 " << std::endl;
fp_hardware += "_X86";
# endif
#endif
#ifdef _M_AMD64
std::cout << "AMD64 " << std::endl;
// fp_hardware += "_AMD64";
#endif
// https://msdn.microsoft.com/en-us/library/7t5yh4fd.aspx
// /arch (x86) options /arch:[IA32|SSE|SSE2|AVX|AVX2]
// default is to use SSE and SSE2 instructions by default.
// https://msdn.microsoft.com/en-us/library/jj620901.aspx
// /arch (x64) options /arch:AVX and /arch:AVX2
// MSVC doesn't bother to set these SSE macros!
// http://stackoverflow.com/questions/18563978/sse-sse2-is-enabled-control-in-visual-studio
// https://msdn.microsoft.com/en-us/library/b0084kay.aspx predefined macros.
// But some of these macros are *not* defined by MSVC,
// unlike AVX (but *are* defined by GCC and Clang).
// So the macro code above does define them.
#if (defined(_M_AMD64) || defined (_M_X64))
# define _M_X64
# define __SSE2__
#else
# ifdef _M_IX86_FP // Expands to an integer literal value indicating which /arch compiler option was used:
std::cout << "Floating-point _M_IX86_FP = " << _M_IX86_FP << std::endl;
# if (_M_IX86_FP == 2) // 2 if /arch:SSE2, /arch:AVX or /arch:AVX2
# define __SSE2__ // x32
# elif (_M_IX86_FP == 1) // 1 if /arch:SSE was used.
# define __SSE__ // x32
# elif (_M_IX86_FP == 0) // 0 if /arch:IA32 was used.
# define _X32 // No special FP instructions.
# endif
# endif
#endif
// Set the fp_hardware that is used in the .qbk filename.
#ifdef __AVX2__
std::cout << "Floating-point AVX2 " << std::endl;
fp_hardware += "_AVX2";
# else
# ifdef __AVX__
std::cout << "Floating-point AVX " << std::endl;
fp_hardware += "_AVX";
# else
# ifdef __SSE2__
std::cout << "Floating-point SSE2 " << std::endl;
fp_hardware += "_SSE2 ";
# else
# ifdef __SSE__
std::cout << "Floating-point SSE " << std::endl;
fp_hardware += "_SSE";
# endif
# endif
# endif
# endif
#ifdef _M_IX86
std::cout << "Floating-point X86 _M_IX86 = " << _M_IX86 << std::endl;
// https://msdn.microsoft.com/en-us/library/aa273918%28v=vs.60%29.aspx#_predir_table_1..3
// 600 = Pentium Pro
#endif
#ifdef _MSC_FULL_VER
std::cout << "Floating-point _MSC_FULL_VER " << _MSC_FULL_VER << std::endl;
#endif
#ifdef __MSVC_RUNTIME_CHECKS
std::cout << "Runtime __MSVC_RUNTIME_CHECKS " << std::endl;
#endif
BOOST_MATH_CONTROL_FP;
cpp_bin_float_100 full_value("28.");
// Compute full answer to more than precision of tests.
//T value = 28.; // integer (exactly representable as floating-point)
// whose cube root is *not* exactly representable.
// Wolfram Alpha command N[28 ^ (1 / 3), 100] computes cube root to 100 decimal digits.
// 3.036588971875662519420809578505669635581453977248111123242141654169177268411884961770250390838097895
std::cout.precision(100);
std::cout << "value " << full_value << std::endl;
// std::cout << ",\n""answer = " << full_answer << std::endl;
std::cout.precision(6);
// cbrt cpp_bin_float_100 full_answer("3.036588971875662519420809578505669635581453977248111123242141654169177268411884961770250390838097895");
// Output the table of types, maxdigits10 and digits and required digits for some accuracies.
// Output tables for some roots at full accuracy.
roots_tables(full_value, 1.);
// Output tables for some roots at less accuracy.
roots_tables(full_value, 0.75);
return boost::exit_success;
}
catch (std::exception ex)
{
std::cout << "exception thrown: " << ex.what() << std::endl;
return boost::exit_failure;
}
} // int main()
/*
*/

29
example/table_type.hpp Normal file
View File

@@ -0,0 +1,29 @@
// Copyright John Maddock 2012.
// 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)
#ifndef BOOST_MATH_TEST_TABLE_TYPE_HPP
#define BOOST_MATH_TEST_TABLE_TYPE_HPP
template <class T>
struct table_type
{
typedef T type;
};
namespace boost{ namespace math{ namespace concepts{
class real_concept;
}}}
template <>
struct table_type<boost::math::concepts::real_concept>
{
typedef long double type;
};
#endif

View File

@@ -24,7 +24,7 @@
#include <boost/multiprecision/cpp_dec_float.hpp>
/*`To define a 50 decimal digit type using `cpp_dec_float`,
/*`To define a 50 decimal digit type using `cpp_dec_float`,
you must pass two template parameters to `boost::multiprecision::number`.
It may be more legible to use a two-staged type definition such as this:
@@ -38,7 +38,7 @@ Here, we first define `mp_backend` as `cpp_dec_float` with 50 digits.
The second step passes this backend to `boost::multiprecision::number`
with `boost::multiprecision::et_off`, an enumerated type.
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off>
typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>, boost::multiprecision::et_off>
cpp_dec_float_50_noet;
You can reduce typing with a `using` directive `using namespace boost::multiprecision;`
@@ -46,19 +46,21 @@ if desired, as shown below.
*/
using namespace boost::multiprecision;
typedef number<cpp_dec_float<50>, et_off> cpp_dec_float_50_noet;
//`Now `cpp_dec_float_50_noet` can be used as a direct replacement for built-in types like `double` etc.
BOOST_AUTO_TEST_CASE(cpp_float_test_check_close)
{
/*`Now `cpp_dec_float_50_noet` or `cpp_dec_float_50_et`
can be used as a direct replacement for built-in types like `double` etc.
*/
BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_noet)
{ // No expression templates/
typedef number<cpp_dec_float<50>, et_off> cpp_dec_float_50_noet;
std::cout.precision(std::numeric_limits<cpp_dec_float_50_noet>::digits10); // All significant digits.
std::cout << std::showpoint << std::endl; // Show trailing zeros.
cpp_dec_float_50_noet a ("1.");
cpp_dec_float_50_noet b ("1.");
cpp_dec_float_50_noet a ("1.0");
cpp_dec_float_50_noet b ("1.0");
b += std::numeric_limits<cpp_dec_float_50_noet>::epsilon(); // Increment least significant decimal digit.
cpp_dec_float_50_noet eps = std::numeric_limits<cpp_dec_float_50_noet>::epsilon();
@@ -68,12 +70,33 @@ BOOST_AUTO_TEST_CASE(cpp_float_test_check_close)
BOOST_CHECK_CLOSE(a, b, eps * 100); // Expected to pass (because tolerance is as percent).
BOOST_CHECK_CLOSE_FRACTION(a, b, eps); // Expected to pass (because tolerance is as fraction).
/*`Using `cpp_dec_float_50` with the default expression template use switched on,
} // BOOST_AUTO_TEST_CASE(cpp_float_test_check_close)
BOOST_AUTO_TEST_CASE(cpp_float_test_check_close_et)
{ // Using expression templates.
typedef number<cpp_dec_float<50>, et_on> cpp_dec_float_50_et;
std::cout.precision(std::numeric_limits<cpp_dec_float_50_et>::digits10); // All significant digits.
std::cout << std::showpoint << std::endl; // Show trailing zeros.
cpp_dec_float_50_et a("1.0");
cpp_dec_float_50_et b("1.0");
b += std::numeric_limits<cpp_dec_float_50_et>::epsilon(); // Increment least significant decimal digit.
cpp_dec_float_50_et eps = std::numeric_limits<cpp_dec_float_50_et>::epsilon();
std::cout << "a = " << a << ",\nb = " << b << ",\neps = " << eps << std::endl;
BOOST_CHECK_CLOSE(a, b, eps * 100); // Expected to pass (because tolerance is as percent).
BOOST_CHECK_CLOSE_FRACTION(a, b, eps); // Expected to pass (because tolerance is as fraction).
/*`Using `cpp_dec_float_50` with the default expression template use switched on,
the compiler error message for `BOOST_CHECK_CLOSE_FRACTION(a, b, eps); would be:
*/
*/
// failure floating_point_comparison.hpp(59): error C2440: 'static_cast' :
// cannot convert from 'int' to 'boost::multiprecision::detail::expression<tag,Arg1,Arg2,Arg3,Arg4>'
//] [/expression_template_1]
} // BOOST_AUTO_TEST_CASE(cpp_float_test_check_close)
@@ -84,11 +107,11 @@ Output:
Description: Autorun "J:\Cpp\big_number\Debug\test_cpp_float_close_fraction.exe"
Running 1 test case...
a = 1.0000000000000000000000000000000000000000000000000,
b = 1.0000000000000000000000000000000000000000000000001,
eps = 1.0000000000000000000000000000000000000000000000000e-49
*** No errors detected

View File

@@ -12,6 +12,9 @@
#include <pch_light.hpp> // include /libs/math/src/
#include "test_cbrt.hpp"
#include <boost/math/special_functions/cbrt.hpp> // Added to avoid link failure missing cbrt variants.
// Assumes special functions library built rather than included?
//
// DESCRIPTION:
// ~~~~~~~~~~~~