summaryrefslogtreecommitdiffstats
path: root/src/boost/libs/math/example
diff options
context:
space:
mode:
Diffstat (limited to 'src/boost/libs/math/example')
-rw-r--r--src/boost/libs/math/example/HSO3.hpp509
-rw-r--r--src/boost/libs/math/example/HSO3SO4.cpp445
-rw-r--r--src/boost/libs/math/example/HSO4.hpp183
-rw-r--r--src/boost/libs/math/example/Jamfile.v2159
-rw-r--r--src/boost/libs/math/example/airy_zeros_example.cpp165
-rw-r--r--src/boost/libs/math/example/arcsine_example.cpp89
-rw-r--r--src/boost/libs/math/example/autodiff_black_scholes.cpp195
-rw-r--r--src/boost/libs/math/example/autodiff_black_scholes_brief.cpp70
-rw-r--r--src/boost/libs/math/example/autodiff_fourth_power.cpp34
-rw-r--r--src/boost/libs/math/example/autodiff_mixed_partials.cpp293
-rw-r--r--src/boost/libs/math/example/autodiff_multiprecision.cpp46
-rw-r--r--src/boost/libs/math/example/barycentric_interpolation_example.cpp92
-rw-r--r--src/boost/libs/math/example/barycentric_interpolation_example_2.cpp108
-rw-r--r--src/boost/libs/math/example/bernoulli_example.cpp207
-rw-r--r--src/boost/libs/math/example/bessel_errors_example.cpp171
-rw-r--r--src/boost/libs/math/example/bessel_zeros_example.cpp447
-rw-r--r--src/boost/libs/math/example/bessel_zeros_example_1.cpp213
-rw-r--r--src/boost/libs/math/example/bessel_zeros_interator_example.cpp88
-rw-r--r--src/boost/libs/math/example/big_seventh.cpp204
-rw-r--r--src/boost/libs/math/example/binomial_coinflip_example.cpp243
-rw-r--r--src/boost/libs/math/example/binomial_confidence_limits.cpp165
-rw-r--r--src/boost/libs/math/example/binomial_example_nag.cpp91
-rw-r--r--src/boost/libs/math/example/binomial_quiz_example.cpp525
-rw-r--r--src/boost/libs/math/example/binomial_sample_sizes.cpp176
-rw-r--r--src/boost/libs/math/example/brent_minimise_example.cpp730
-rw-r--r--src/boost/libs/math/example/c_error_policy_example.cpp83
-rw-r--r--src/boost/libs/math/example/cardinal_cubic_b_spline_example.cpp147
-rw-r--r--src/boost/libs/math/example/catmull_rom_example.cpp45
-rw-r--r--src/boost/libs/math/example/chi_square_std_dev_test.cpp555
-rw-r--r--src/boost/libs/math/example/constants_eg1.cpp192
-rw-r--r--src/boost/libs/math/example/continued_fractions.cpp150
-rw-r--r--src/boost/libs/math/example/cstdfloat_example.cpp488
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/bench.cpp489
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/bootstrap_chebyshev.cpp18
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/daubechies_coefficients.cpp267
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/daubechies_plots.cpp165
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_integer_grid.cpp213
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_memory_occupation.cpp59
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/daubechies_wavelet_plots.cpp160
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/find_best_daubechies_interpolator.cpp535
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/regress_daubechies_accuracy.cpp146
-rw-r--r--src/boost/libs/math/example/daubechies_wavelets/wavelet_transform.cpp46
-rw-r--r--src/boost/libs/math/example/distribution_construction.cpp295
-rw-r--r--src/boost/libs/math/example/double_exponential.cpp59
-rw-r--r--src/boost/libs/math/example/error_handling_example.cpp153
-rw-r--r--src/boost/libs/math/example/error_policies_example.cpp105
-rw-r--r--src/boost/libs/math/example/error_policy_example.cpp93
-rw-r--r--src/boost/libs/math/example/f_test.cpp250
-rw-r--r--src/boost/libs/math/example/factorial_example.cpp97
-rw-r--r--src/boost/libs/math/example/fft_sines_table.cpp270
-rw-r--r--src/boost/libs/math/example/find_location_example.cpp174
-rw-r--r--src/boost/libs/math/example/find_mean_and_sd_normal.cpp413
-rw-r--r--src/boost/libs/math/example/find_root_example.cpp169
-rw-r--r--src/boost/libs/math/example/find_scale_example.cpp180
-rw-r--r--src/boost/libs/math/example/float128_example.cpp289
-rw-r--r--src/boost/libs/math/example/float_comparison_example.cpp444
-rw-r--r--src/boost/libs/math/example/gauss_example.cpp142
-rw-r--r--src/boost/libs/math/example/geometric_examples.cpp364
-rw-r--r--src/boost/libs/math/example/handle_test_result.hpp220
-rw-r--r--src/boost/libs/math/example/hyperexponential_more_snips.cpp155
-rw-r--r--src/boost/libs/math/example/hyperexponential_snips.cpp103
-rw-r--r--src/boost/libs/math/example/inspect_fp.cpp224
-rw-r--r--src/boost/libs/math/example/inverse_chi_squared_bayes_eg.cpp338
-rw-r--r--src/boost/libs/math/example/inverse_chi_squared_example.cpp171
-rw-r--r--src/boost/libs/math/example/inverse_chi_squared_find_df_example.cpp186
-rw-r--r--src/boost/libs/math/example/inverse_gamma_distribution_example.cpp103
-rw-r--r--src/boost/libs/math/example/inverse_gamma_example.cpp57
-rw-r--r--src/boost/libs/math/example/inverse_gaussian_example.cpp513
-rw-r--r--src/boost/libs/math/example/jacobi_zeta_example.cpp104
-rw-r--r--src/boost/libs/math/example/lambert_w_basic_example.cpp30
-rw-r--r--src/boost/libs/math/example/lambert_w_diode.cpp165
-rw-r--r--src/boost/libs/math/example/lambert_w_diode_graph.cpp280
-rw-r--r--src/boost/libs/math/example/lambert_w_example.cpp239
-rw-r--r--src/boost/libs/math/example/lambert_w_graph.cpp286
-rw-r--r--src/boost/libs/math/example/lambert_w_precision_example.cpp263
-rw-r--r--src/boost/libs/math/example/lambert_w_simple_examples.cpp251
-rw-r--r--src/boost/libs/math/example/laplace_example.cpp169
-rw-r--r--src/boost/libs/math/example/legendre_stieltjes_example.cpp110
-rw-r--r--src/boost/libs/math/example/lexical_cast_native.cpp133
-rw-r--r--src/boost/libs/math/example/lexical_cast_nonfinite_facets.cpp133
-rw-r--r--src/boost/libs/math/example/naive_monte_carlo_example.cpp136
-rw-r--r--src/boost/libs/math/example/nc_chi_sq_example.cpp115
-rw-r--r--src/boost/libs/math/example/neg_binom_confidence_limits.cpp178
-rw-r--r--src/boost/libs/math/example/neg_binomial_sample_sizes.cpp209
-rw-r--r--src/boost/libs/math/example/negative_binomial_example1.cpp513
-rw-r--r--src/boost/libs/math/example/negative_binomial_example2.cpp182
-rw-r--r--src/boost/libs/math/example/neumann_zeros_example_1.cpp85
-rw-r--r--src/boost/libs/math/example/nonfinite_facet_simple.cpp269
-rw-r--r--src/boost/libs/math/example/nonfinite_facet_sstream.cpp132
-rw-r--r--src/boost/libs/math/example/nonfinite_legacy.cpp94
-rw-r--r--src/boost/libs/math/example/nonfinite_loopback_ok.cpp89
-rw-r--r--src/boost/libs/math/example/nonfinite_num_facet.cpp291
-rw-r--r--src/boost/libs/math/example/nonfinite_num_facet_serialization.cpp433
-rw-r--r--src/boost/libs/math/example/nonfinite_num_facet_trap.cpp115
-rw-r--r--src/boost/libs/math/example/nonfinite_serialization_archives.cpp136
-rw-r--r--src/boost/libs/math/example/nonfinite_signaling_NaN.cpp189
-rw-r--r--src/boost/libs/math/example/normal_misc_examples.cpp509
-rw-r--r--src/boost/libs/math/example/normal_tables.cpp566
-rw-r--r--src/boost/libs/math/example/numerical_derivative_example.cpp209
-rw-r--r--src/boost/libs/math/example/ooura_fourier_integrals_cosine_example.cpp83
-rw-r--r--src/boost/libs/math/example/ooura_fourier_integrals_example.cpp83
-rw-r--r--src/boost/libs/math/example/ooura_fourier_integrals_multiprecision_example.cpp98
-rw-r--r--src/boost/libs/math/example/owens_t_example.cpp113
-rw-r--r--src/boost/libs/math/example/policy_eg_1.cpp70
-rw-r--r--src/boost/libs/math/example/policy_eg_10.cpp183
-rw-r--r--src/boost/libs/math/example/policy_eg_2.cpp65
-rw-r--r--src/boost/libs/math/example/policy_eg_3.cpp55
-rw-r--r--src/boost/libs/math/example/policy_eg_4.cpp107
-rw-r--r--src/boost/libs/math/example/policy_eg_5.cpp66
-rw-r--r--src/boost/libs/math/example/policy_eg_6.cpp121
-rw-r--r--src/boost/libs/math/example/policy_eg_7.cpp73
-rw-r--r--src/boost/libs/math/example/policy_eg_8.cpp133
-rw-r--r--src/boost/libs/math/example/policy_eg_9.cpp313
-rw-r--r--src/boost/libs/math/example/policy_ref_snip1.cpp75
-rw-r--r--src/boost/libs/math/example/policy_ref_snip10.cpp40
-rw-r--r--src/boost/libs/math/example/policy_ref_snip11.cpp45
-rw-r--r--src/boost/libs/math/example/policy_ref_snip12.cpp55
-rw-r--r--src/boost/libs/math/example/policy_ref_snip13.cpp81
-rw-r--r--src/boost/libs/math/example/policy_ref_snip2.cpp47
-rw-r--r--src/boost/libs/math/example/policy_ref_snip3.cpp40
-rw-r--r--src/boost/libs/math/example/policy_ref_snip4.cpp41
-rw-r--r--src/boost/libs/math/example/policy_ref_snip5.cpp45
-rw-r--r--src/boost/libs/math/example/policy_ref_snip6.cpp38
-rw-r--r--src/boost/libs/math/example/policy_ref_snip7.cpp48
-rw-r--r--src/boost/libs/math/example/policy_ref_snip8.cpp47
-rw-r--r--src/boost/libs/math/example/policy_ref_snip9.cpp36
-rw-r--r--src/boost/libs/math/example/polynomial_arithmetic.cpp237
-rw-r--r--src/boost/libs/math/example/root_elliptic_finding.cpp878
-rw-r--r--src/boost/libs/math/example/root_finding_algorithms.cpp907
-rw-r--r--src/boost/libs/math/example/root_finding_example.cpp547
-rw-r--r--src/boost/libs/math/example/root_finding_fifth.cpp485
-rw-r--r--src/boost/libs/math/example/root_finding_multiprecision_example.cpp232
-rw-r--r--src/boost/libs/math/example/root_finding_n_example.cpp213
-rw-r--r--src/boost/libs/math/example/root_finding_start_locations.cpp449
-rw-r--r--src/boost/libs/math/example/root_n_finding_algorithms.cpp870
-rw-r--r--src/boost/libs/math/example/series.cpp107
-rw-r--r--src/boost/libs/math/example/sines.hpp47
-rw-r--r--src/boost/libs/math/example/skew_normal_example.cpp275
-rw-r--r--src/boost/libs/math/example/special_data.cpp84
-rw-r--r--src/boost/libs/math/example/students_t_example1.cpp101
-rw-r--r--src/boost/libs/math/example/students_t_example2.cpp126
-rw-r--r--src/boost/libs/math/example/students_t_example3.cpp120
-rw-r--r--src/boost/libs/math/example/students_t_single_sample.cpp424
-rw-r--r--src/boost/libs/math/example/students_t_two_samples.cpp245
-rw-r--r--src/boost/libs/math/example/table_type.hpp29
-rw-r--r--src/boost/libs/math/example/test_cpp_float_close_fraction.cpp119
-rw-r--r--src/boost/libs/math/example/test_nonfinite_loopback.cpp97
-rw-r--r--src/boost/libs/math/example/trapezoidal_example.cpp29
148 files changed, 30408 insertions, 0 deletions
diff --git a/src/boost/libs/math/example/HSO3.hpp b/src/boost/libs/math/example/HSO3.hpp
new file mode 100644
index 000000000..4e4ead7ab
--- /dev/null
+++ b/src/boost/libs/math/example/HSO3.hpp
@@ -0,0 +1,509 @@
+
+/********************************************************************************************/
+/* */
+/* HSO3.hpp header file */
+/* */
+/* This file is not currently part of the Boost library. It is simply an example of the use */
+/* quaternions can be put to. Hopefully it will be useful too. */
+/* */
+/* This file provides tools to convert between quaternions and R^3 rotation matrices. */
+/* */
+/********************************************************************************************/
+
+// (C) Copyright Hubert Holin 2001.
+// 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)
+
+#ifndef TEST_HSO3_HPP
+#define TEST_HSO3_HPP
+
+#include <algorithm>
+
+#if defined(__GNUC__) && (__GNUC__ < 3)
+#include <boost/limits.hpp>
+#else
+#include <limits>
+#endif
+
+#include <stdexcept>
+#include <string>
+
+#include <boost/math/quaternion.hpp>
+
+
+#if defined(__GNUC__) && (__GNUC__ < 3)
+// gcc 2.x ignores function scope using declarations, put them here instead:
+using namespace ::std;
+using namespace ::boost::math;
+#endif
+
+template<typename TYPE_FLOAT>
+struct R3_matrix
+{
+ TYPE_FLOAT a11, a12, a13;
+ TYPE_FLOAT a21, a22, a23;
+ TYPE_FLOAT a31, a32, a33;
+};
+
+
+// Note: the input quaternion need not be of norm 1 for the following function
+
+template<typename TYPE_FLOAT>
+R3_matrix<TYPE_FLOAT> quaternion_to_R3_rotation(::boost::math::quaternion<TYPE_FLOAT> const & q)
+{
+ using ::std::numeric_limits;
+
+ TYPE_FLOAT a = q.R_component_1();
+ TYPE_FLOAT b = q.R_component_2();
+ TYPE_FLOAT c = q.R_component_3();
+ TYPE_FLOAT d = q.R_component_4();
+
+ TYPE_FLOAT aa = a*a;
+ TYPE_FLOAT ab = a*b;
+ TYPE_FLOAT ac = a*c;
+ TYPE_FLOAT ad = a*d;
+ TYPE_FLOAT bb = b*b;
+ TYPE_FLOAT bc = b*c;
+ TYPE_FLOAT bd = b*d;
+ TYPE_FLOAT cc = c*c;
+ TYPE_FLOAT cd = c*d;
+ TYPE_FLOAT dd = d*d;
+
+ TYPE_FLOAT norme_carre = aa+bb+cc+dd;
+
+ if (norme_carre <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Argument to quaternion_to_R3_rotation is too small!");
+ ::std::underflow_error bad_argument(error_reporting);
+
+ throw(bad_argument);
+ }
+
+ R3_matrix<TYPE_FLOAT> out_matrix;
+
+ out_matrix.a11 = (aa+bb-cc-dd)/norme_carre;
+ out_matrix.a12 = 2*(-ad+bc)/norme_carre;
+ out_matrix.a13 = 2*(ac+bd)/norme_carre;
+ out_matrix.a21 = 2*(ad+bc)/norme_carre;
+ out_matrix.a22 = (aa-bb+cc-dd)/norme_carre;
+ out_matrix.a23 = 2*(-ab+cd)/norme_carre;
+ out_matrix.a31 = 2*(-ac+bd)/norme_carre;
+ out_matrix.a32 = 2*(ab+cd)/norme_carre;
+ out_matrix.a33 = (aa-bb-cc+dd)/norme_carre;
+
+ return(out_matrix);
+}
+
+
+ template<typename TYPE_FLOAT>
+ void find_invariant_vector( R3_matrix<TYPE_FLOAT> const & rot,
+ TYPE_FLOAT & x,
+ TYPE_FLOAT & y,
+ TYPE_FLOAT & z)
+ {
+ using ::std::sqrt;
+
+ using ::std::numeric_limits;
+
+ TYPE_FLOAT b11 = rot.a11 - static_cast<TYPE_FLOAT>(1);
+ TYPE_FLOAT b12 = rot.a12;
+ TYPE_FLOAT b13 = rot.a13;
+ TYPE_FLOAT b21 = rot.a21;
+ TYPE_FLOAT b22 = rot.a22 - static_cast<TYPE_FLOAT>(1);
+ TYPE_FLOAT b23 = rot.a23;
+ TYPE_FLOAT b31 = rot.a31;
+ TYPE_FLOAT b32 = rot.a32;
+ TYPE_FLOAT b33 = rot.a33 - static_cast<TYPE_FLOAT>(1);
+
+ TYPE_FLOAT minors[9] =
+ {
+ b11*b22-b12*b21,
+ b11*b23-b13*b21,
+ b12*b23-b13*b22,
+ b11*b32-b12*b31,
+ b11*b33-b13*b31,
+ b12*b33-b13*b32,
+ b21*b32-b22*b31,
+ b21*b33-b23*b31,
+ b22*b33-b23*b32
+ };
+
+ TYPE_FLOAT * where = ::std::max_element(minors, minors+9);
+
+ TYPE_FLOAT det = *where;
+
+ if (det <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Underflow error in find_invariant_vector!");
+ ::std::underflow_error processing_error(error_reporting);
+
+ throw(processing_error);
+ }
+
+ switch (where-minors)
+ {
+ case 0:
+
+ z = static_cast<TYPE_FLOAT>(1);
+
+ x = (-b13*b22+b12*b23)/det;
+ y = (-b11*b23+b13*b21)/det;
+
+ break;
+
+ case 1:
+
+ y = static_cast<TYPE_FLOAT>(1);
+
+ x = (-b12*b23+b13*b22)/det;
+ z = (-b11*b22+b12*b21)/det;
+
+ break;
+
+ case 2:
+
+ x = static_cast<TYPE_FLOAT>(1);
+
+ y = (-b11*b23+b13*b21)/det;
+ z = (-b12*b21+b11*b22)/det;
+
+ break;
+
+ case 3:
+
+ z = static_cast<TYPE_FLOAT>(1);
+
+ x = (-b13*b32+b12*b33)/det;
+ y = (-b11*b33+b13*b31)/det;
+
+ break;
+
+ case 4:
+
+ y = static_cast<TYPE_FLOAT>(1);
+
+ x = (-b12*b33+b13*b32)/det;
+ z = (-b11*b32+b12*b31)/det;
+
+ break;
+
+ case 5:
+
+ x = static_cast<TYPE_FLOAT>(1);
+
+ y = (-b11*b33+b13*b31)/det;
+ z = (-b12*b31+b11*b32)/det;
+
+ break;
+
+ case 6:
+
+ z = static_cast<TYPE_FLOAT>(1);
+
+ x = (-b23*b32+b22*b33)/det;
+ y = (-b21*b33+b23*b31)/det;
+
+ break;
+
+ case 7:
+
+ y = static_cast<TYPE_FLOAT>(1);
+
+ x = (-b22*b33+b23*b32)/det;
+ z = (-b21*b32+b22*b31)/det;
+
+ break;
+
+ case 8:
+
+ x = static_cast<TYPE_FLOAT>(1);
+
+ y = (-b21*b33+b23*b31)/det;
+ z = (-b22*b31+b21*b32)/det;
+
+ break;
+
+ default:
+
+ ::std::string error_reporting("Impossible condition in find_invariant_vector");
+ ::std::logic_error processing_error(error_reporting);
+
+ throw(processing_error);
+
+ break;
+ }
+
+ TYPE_FLOAT vecnorm = sqrt(x*x+y*y+z*z);
+
+ if (vecnorm <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Overflow error in find_invariant_vector!");
+ ::std::overflow_error processing_error(error_reporting);
+
+ throw(processing_error);
+ }
+
+ x /= vecnorm;
+ y /= vecnorm;
+ z /= vecnorm;
+ }
+
+
+ template<typename TYPE_FLOAT>
+ void find_orthogonal_vector( TYPE_FLOAT x,
+ TYPE_FLOAT y,
+ TYPE_FLOAT z,
+ TYPE_FLOAT & u,
+ TYPE_FLOAT & v,
+ TYPE_FLOAT & w)
+ {
+ using ::std::abs;
+ using ::std::sqrt;
+
+ using ::std::numeric_limits;
+
+ TYPE_FLOAT vecnormsqr = x*x+y*y+z*z;
+
+ if (vecnormsqr <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Underflow error in find_orthogonal_vector!");
+ ::std::underflow_error processing_error(error_reporting);
+
+ throw(processing_error);
+ }
+
+ TYPE_FLOAT lambda;
+
+ TYPE_FLOAT components[3] =
+ {
+ abs(x),
+ abs(y),
+ abs(z)
+ };
+
+ TYPE_FLOAT * where = ::std::min_element(components, components+3);
+
+ switch (where-components)
+ {
+ case 0:
+
+ if (*where <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ v =
+ w = static_cast<TYPE_FLOAT>(0);
+ u = static_cast<TYPE_FLOAT>(1);
+ }
+ else
+ {
+ lambda = -x/vecnormsqr;
+
+ u = static_cast<TYPE_FLOAT>(1) + lambda*x;
+ v = lambda*y;
+ w = lambda*z;
+ }
+
+ break;
+
+ case 1:
+
+ if (*where <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ u =
+ w = static_cast<TYPE_FLOAT>(0);
+ v = static_cast<TYPE_FLOAT>(1);
+ }
+ else
+ {
+ lambda = -y/vecnormsqr;
+
+ u = lambda*x;
+ v = static_cast<TYPE_FLOAT>(1) + lambda*y;
+ w = lambda*z;
+ }
+
+ break;
+
+ case 2:
+
+ if (*where <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ u =
+ v = static_cast<TYPE_FLOAT>(0);
+ w = static_cast<TYPE_FLOAT>(1);
+ }
+ else
+ {
+ lambda = -z/vecnormsqr;
+
+ u = lambda*x;
+ v = lambda*y;
+ w = static_cast<TYPE_FLOAT>(1) + lambda*z;
+ }
+
+ break;
+
+ default:
+
+ ::std::string error_reporting("Impossible condition in find_invariant_vector");
+ ::std::logic_error processing_error(error_reporting);
+
+ throw(processing_error);
+
+ break;
+ }
+
+ TYPE_FLOAT vecnorm = sqrt(u*u+v*v+w*w);
+
+ if (vecnorm <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Underflow error in find_orthogonal_vector!");
+ ::std::underflow_error processing_error(error_reporting);
+
+ throw(processing_error);
+ }
+
+ u /= vecnorm;
+ v /= vecnorm;
+ w /= vecnorm;
+ }
+
+
+ // Note: we want [[v, v, w], [r, s, t], [x, y, z]] to be a direct orthogonal basis
+ // of R^3. It might not be orthonormal, however, and we do not check if the
+ // two input vectors are colinear or not.
+
+ template<typename TYPE_FLOAT>
+ void find_vector_for_BOD(TYPE_FLOAT x,
+ TYPE_FLOAT y,
+ TYPE_FLOAT z,
+ TYPE_FLOAT u,
+ TYPE_FLOAT v,
+ TYPE_FLOAT w,
+ TYPE_FLOAT & r,
+ TYPE_FLOAT & s,
+ TYPE_FLOAT & t)
+ {
+ r = +y*w-z*v;
+ s = -x*w+z*u;
+ t = +x*v-y*u;
+ }
+
+
+
+template<typename TYPE_FLOAT>
+inline bool is_R3_rotation_matrix(R3_matrix<TYPE_FLOAT> const & mat)
+{
+ using ::std::abs;
+
+ using ::std::numeric_limits;
+
+ return (
+ !(
+ (abs(mat.a11*mat.a11+mat.a21*mat.a21+mat.a31*mat.a31 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a12*mat.a12+mat.a22*mat.a22+mat.a32*mat.a32 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a13*mat.a13+mat.a23*mat.a23+mat.a33*mat.a33 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())
+ )
+ );
+}
+
+
+template<typename TYPE_FLOAT>
+::boost::math::quaternion<TYPE_FLOAT> R3_rotation_to_quaternion( R3_matrix<TYPE_FLOAT> const & rot,
+ ::boost::math::quaternion<TYPE_FLOAT> const * hint = 0)
+{
+ using ::boost::math::abs;
+
+ using ::std::abs;
+ using ::std::sqrt;
+
+ using ::std::numeric_limits;
+
+ if (!is_R3_rotation_matrix(rot))
+ {
+ ::std::string error_reporting("Argument to R3_rotation_to_quaternion is not an R^3 rotation matrix!");
+ ::std::range_error bad_argument(error_reporting);
+
+ throw(bad_argument);
+ }
+
+ ::boost::math::quaternion<TYPE_FLOAT> q;
+
+ if (
+ (abs(rot.a11 - static_cast<TYPE_FLOAT>(1)) <= numeric_limits<TYPE_FLOAT>::epsilon())&&
+ (abs(rot.a22 - static_cast<TYPE_FLOAT>(1)) <= numeric_limits<TYPE_FLOAT>::epsilon())&&
+ (abs(rot.a33 - static_cast<TYPE_FLOAT>(1)) <= numeric_limits<TYPE_FLOAT>::epsilon())
+ )
+ {
+ q = ::boost::math::quaternion<TYPE_FLOAT>(1);
+ }
+ else
+ {
+ TYPE_FLOAT cos_theta = (rot.a11+rot.a22+rot.a33-static_cast<TYPE_FLOAT>(1))/static_cast<TYPE_FLOAT>(2);
+ TYPE_FLOAT stuff = (cos_theta+static_cast<TYPE_FLOAT>(1))/static_cast<TYPE_FLOAT>(2);
+ TYPE_FLOAT cos_theta_sur_2 = sqrt(stuff);
+ TYPE_FLOAT sin_theta_sur_2 = sqrt(1-stuff);
+
+ TYPE_FLOAT x;
+ TYPE_FLOAT y;
+ TYPE_FLOAT z;
+
+ find_invariant_vector(rot, x, y, z);
+
+ TYPE_FLOAT u;
+ TYPE_FLOAT v;
+ TYPE_FLOAT w;
+
+ find_orthogonal_vector(x, y, z, u, v, w);
+
+ TYPE_FLOAT r;
+ TYPE_FLOAT s;
+ TYPE_FLOAT t;
+
+ find_vector_for_BOD(x, y, z, u, v, w, r, s, t);
+
+ TYPE_FLOAT ru = rot.a11*u+rot.a12*v+rot.a13*w;
+ TYPE_FLOAT rv = rot.a21*u+rot.a22*v+rot.a23*w;
+ TYPE_FLOAT rw = rot.a31*u+rot.a32*v+rot.a33*w;
+
+ TYPE_FLOAT angle_sign_determinator = r*ru+s*rv+t*rw;
+
+ if (angle_sign_determinator > +numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ q = ::boost::math::quaternion<TYPE_FLOAT>(cos_theta_sur_2, +x*sin_theta_sur_2, +y*sin_theta_sur_2, +z*sin_theta_sur_2);
+ }
+ else if (angle_sign_determinator < -numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ q = ::boost::math::quaternion<TYPE_FLOAT>(cos_theta_sur_2, -x*sin_theta_sur_2, -y*sin_theta_sur_2, -z*sin_theta_sur_2);
+ }
+ else
+ {
+ TYPE_FLOAT desambiguator = u*ru+v*rv+w*rw;
+
+ if (desambiguator >= static_cast<TYPE_FLOAT>(1))
+ {
+ q = ::boost::math::quaternion<TYPE_FLOAT>(0, +x, +y, +z);
+ }
+ else
+ {
+ q = ::boost::math::quaternion<TYPE_FLOAT>(0, -x, -y, -z);
+ }
+ }
+ }
+
+ if ((hint != 0) && (abs(*hint+q) < abs(*hint-q)))
+ {
+ return(-q);
+ }
+
+ return(q);
+}
+
+#endif /* TEST_HSO3_HPP */
+
diff --git a/src/boost/libs/math/example/HSO3SO4.cpp b/src/boost/libs/math/example/HSO3SO4.cpp
new file mode 100644
index 000000000..c4462c793
--- /dev/null
+++ b/src/boost/libs/math/example/HSO3SO4.cpp
@@ -0,0 +1,445 @@
+// test file for HSO3.hpp and HSO4.hpp
+
+// (C) Copyright Hubert Holin 2001.
+// 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)
+
+
+#include <iostream>
+
+#include <boost/math/quaternion.hpp>
+
+#include "HSO3.hpp"
+#include "HSO4.hpp"
+
+
+const int number_of_intervals = 5;
+
+const float pi = ::std::atan(1.0f)*4;
+
+
+
+void test_SO3();
+
+void test_SO4();
+
+
+int main()
+
+{
+ test_SO3();
+
+ test_SO4();
+
+ ::std::cout << "That's all folks!" << ::std::endl;
+}
+
+
+//
+// Test of quaternion and R^3 rotation relationship
+//
+
+void test_SO3_spherical()
+{
+ ::std::cout << "Testing spherical:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ const float rho = 1.0f;
+
+ float theta;
+ float phi1;
+ float phi2;
+
+ for (int idxphi2 = 0; idxphi2 <= number_of_intervals; idxphi2++)
+ {
+ phi2 = (-pi/2)+(idxphi2*pi)/number_of_intervals;
+
+ for (int idxphi1 = 0; idxphi1 <= number_of_intervals; idxphi1++)
+ {
+ phi1 = (-pi/2)+(idxphi1*pi)/number_of_intervals;
+
+ for (int idxtheta = 0; idxtheta <= number_of_intervals; idxtheta++)
+ {
+ theta = -pi+(idxtheta*(2*pi))/number_of_intervals;
+
+ ::std::cout << "theta = " << theta << " ; ";
+ ::std::cout << "phi1 = " << phi1 << " ; ";
+ ::std::cout << "phi2 = " << phi2;
+ ::std::cout << ::std::endl;
+
+ ::boost::math::quaternion<float> q = ::boost::math::spherical(rho, theta, phi1, phi2);
+
+ ::std::cout << "q = " << q << ::std::endl;
+
+ R3_matrix<float> rot = quaternion_to_R3_rotation(q);
+
+ ::std::cout << "rot = ";
+ ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
+
+ ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
+
+ ::std::cout << "p = " << p << ::std::endl;
+
+ ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
+
+ ::std::cout << ::std::endl;
+ }
+ }
+ }
+
+ ::std::cout << ::std::endl;
+}
+
+
+void test_SO3_semipolar()
+{
+ ::std::cout << "Testing semipolar:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ const float rho = 1.0f;
+
+ float alpha;
+ float theta1;
+ float theta2;
+
+ for (int idxalpha = 0; idxalpha <= number_of_intervals; idxalpha++)
+ {
+ alpha = (idxalpha*(pi/2))/number_of_intervals;
+
+ for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
+ {
+ theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
+
+ for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
+ {
+ theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
+
+ ::std::cout << "alpha = " << alpha << " ; ";
+ ::std::cout << "theta1 = " << theta1 << " ; ";
+ ::std::cout << "theta2 = " << theta2;
+ ::std::cout << ::std::endl;
+
+ ::boost::math::quaternion<float> q = ::boost::math::semipolar(rho, alpha, theta1, theta2);
+
+ ::std::cout << "q = " << q << ::std::endl;
+
+ R3_matrix<float> rot = quaternion_to_R3_rotation(q);
+
+ ::std::cout << "rot = ";
+ ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
+
+ ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
+
+ ::std::cout << "p = " << p << ::std::endl;
+
+ ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
+
+ ::std::cout << ::std::endl;
+ }
+ }
+ }
+
+ ::std::cout << ::std::endl;
+}
+
+
+void test_SO3_multipolar()
+{
+ ::std::cout << "Testing multipolar:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ float rho1;
+ float rho2;
+
+ float theta1;
+ float theta2;
+
+ for (int idxrho = 0; idxrho <= number_of_intervals; idxrho++)
+ {
+ rho1 = (idxrho*1.0f)/number_of_intervals;
+ rho2 = ::std::sqrt(1.0f-rho1*rho1);
+
+ for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
+ {
+ theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
+
+ for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
+ {
+ theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
+
+ ::std::cout << "rho1 = " << rho1 << " ; ";
+ ::std::cout << "theta1 = " << theta1 << " ; ";
+ ::std::cout << "theta2 = " << theta2;
+ ::std::cout << ::std::endl;
+
+ ::boost::math::quaternion<float> q = ::boost::math::multipolar(rho1, theta1, rho2, theta2);
+
+ ::std::cout << "q = " << q << ::std::endl;
+
+ R3_matrix<float> rot = quaternion_to_R3_rotation(q);
+
+ ::std::cout << "rot = ";
+ ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
+
+ ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
+
+ ::std::cout << "p = " << p << ::std::endl;
+
+ ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
+
+ ::std::cout << ::std::endl;
+ }
+ }
+ }
+
+ ::std::cout << ::std::endl;
+}
+
+
+void test_SO3_cylindrospherical()
+{
+ ::std::cout << "Testing cylindrospherical:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ float t;
+
+ float radius;
+ float longitude;
+ float latitude;
+
+ for (int idxt = 0; idxt <= number_of_intervals; idxt++)
+ {
+ t = -1.0f+(idxt*2.0f)/number_of_intervals;
+ radius = ::std::sqrt(1.0f-t*t);
+
+ for (int idxlatitude = 0; idxlatitude <= number_of_intervals; idxlatitude++)
+ {
+ latitude = (-pi/2)+(idxlatitude*pi)/number_of_intervals;
+
+ for (int idxlongitude = 0; idxlongitude <= number_of_intervals; idxlongitude++)
+ {
+ longitude = -pi+(idxlongitude*(2*pi))/number_of_intervals;
+
+ ::std::cout << "t = " << t << " ; ";
+ ::std::cout << "longitude = " << longitude;
+ ::std::cout << "latitude = " << latitude;
+ ::std::cout << ::std::endl;
+
+ ::boost::math::quaternion<float> q = ::boost::math::cylindrospherical(t, radius, longitude, latitude);
+
+ ::std::cout << "q = " << q << ::std::endl;
+
+ R3_matrix<float> rot = quaternion_to_R3_rotation(q);
+
+ ::std::cout << "rot = ";
+ ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
+
+ ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
+
+ ::std::cout << "p = " << p << ::std::endl;
+
+ ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
+
+ ::std::cout << ::std::endl;
+ }
+ }
+ }
+
+ ::std::cout << ::std::endl;
+}
+
+
+void test_SO3_cylindrical()
+{
+ ::std::cout << "Testing cylindrical:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ float r;
+ float angle;
+
+ float h1;
+ float h2;
+
+ for (int idxh2 = 0; idxh2 <= number_of_intervals; idxh2++)
+ {
+ h2 = -1.0f+(idxh2*2.0f)/number_of_intervals;
+
+ for (int idxh1 = 0; idxh1 <= number_of_intervals; idxh1++)
+ {
+ h1 = ::std::sqrt(1.0f-h2*h2)*(-1.0f+(idxh2*2.0f)/number_of_intervals);
+ r = ::std::sqrt(1.0f-h1*h1-h2*h2);
+
+ for (int idxangle = 0; idxangle <= number_of_intervals; idxangle++)
+ {
+ angle = -pi+(idxangle*(2*pi))/number_of_intervals;
+
+ ::std::cout << "angle = " << angle << " ; ";
+ ::std::cout << "h1 = " << h1;
+ ::std::cout << "h2 = " << h2;
+ ::std::cout << ::std::endl;
+
+ ::boost::math::quaternion<float> q = ::boost::math::cylindrical(r, angle, h1, h2);
+
+ ::std::cout << "q = " << q << ::std::endl;
+
+ R3_matrix<float> rot = quaternion_to_R3_rotation(q);
+
+ ::std::cout << "rot = ";
+ ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << ::std::endl;
+
+ ::boost::math::quaternion<float> p = R3_rotation_to_quaternion(rot, &q);
+
+ ::std::cout << "p = " << p << ::std::endl;
+
+ ::std::cout << "round trip discrepancy: " << ::boost::math::abs(q-p) << ::std::endl;
+
+ ::std::cout << ::std::endl;
+ }
+ }
+ }
+
+ ::std::cout << ::std::endl;
+}
+
+
+void test_SO3()
+{
+ ::std::cout << "Testing SO3:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ test_SO3_spherical();
+
+ test_SO3_semipolar();
+
+ test_SO3_multipolar();
+
+ test_SO3_cylindrospherical();
+
+ test_SO3_cylindrical();
+}
+
+
+//
+// Test of quaternion and R^4 rotation relationship
+//
+
+void test_SO4_spherical()
+{
+ ::std::cout << "Testing spherical:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ const float rho1 = 1.0f;
+ const float rho2 = 1.0f;
+
+ float theta1;
+ float phi11;
+ float phi21;
+
+ float theta2;
+ float phi12;
+ float phi22;
+
+ for (int idxphi21 = 0; idxphi21 <= number_of_intervals; idxphi21++)
+ {
+ phi21 = (-pi/2)+(idxphi21*pi)/number_of_intervals;
+
+ for (int idxphi22 = 0; idxphi22 <= number_of_intervals; idxphi22++)
+ {
+ phi22 = (-pi/2)+(idxphi22*pi)/number_of_intervals;
+
+ for (int idxphi11 = 0; idxphi11 <= number_of_intervals; idxphi11++)
+ {
+ phi11 = (-pi/2)+(idxphi11*pi)/number_of_intervals;
+
+ for (int idxphi12 = 0; idxphi12 <= number_of_intervals; idxphi12++)
+ {
+ phi12 = (-pi/2)+(idxphi12*pi)/number_of_intervals;
+
+ for (int idxtheta1 = 0; idxtheta1 <= number_of_intervals; idxtheta1++)
+ {
+ theta1 = -pi+(idxtheta1*(2*pi))/number_of_intervals;
+
+ for (int idxtheta2 = 0; idxtheta2 <= number_of_intervals; idxtheta2++)
+ {
+ theta2 = -pi+(idxtheta2*(2*pi))/number_of_intervals;
+
+ ::std::cout << "theta1 = " << theta1 << " ; ";
+ ::std::cout << "phi11 = " << phi11 << " ; ";
+ ::std::cout << "phi21 = " << phi21;
+ ::std::cout << "theta2 = " << theta2 << " ; ";
+ ::std::cout << "phi12 = " << phi12 << " ; ";
+ ::std::cout << "phi22 = " << phi22;
+ ::std::cout << ::std::endl;
+
+ ::boost::math::quaternion<float> p1 = ::boost::math::spherical(rho1, theta1, phi11, phi21);
+
+ ::std::cout << "p1 = " << p1 << ::std::endl;
+
+ ::boost::math::quaternion<float> q1 = ::boost::math::spherical(rho2, theta2, phi12, phi22);
+
+ ::std::cout << "q1 = " << q1 << ::std::endl;
+
+ ::std::pair< ::boost::math::quaternion<float> , ::boost::math::quaternion<float> > pq1 =
+ ::std::make_pair(p1,q1);
+
+ R4_matrix<float> rot = quaternions_to_R4_rotation(pq1);
+
+ ::std::cout << "rot = ";
+ ::std::cout << "\t" << rot.a11 << "\t" << rot.a12 << "\t" << rot.a13 << "\t" << rot.a14 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a21 << "\t" << rot.a22 << "\t" << rot.a23 << "\t" << rot.a24 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a31 << "\t" << rot.a32 << "\t" << rot.a33 << "\t" << rot.a34 << ::std::endl;
+ ::std::cout << "\t";
+ ::std::cout << "\t" << rot.a41 << "\t" << rot.a42 << "\t" << rot.a43 << "\t" << rot.a44 << ::std::endl;
+
+ ::std::pair< ::boost::math::quaternion<float> , ::boost::math::quaternion<float> > pq2 =
+ R4_rotation_to_quaternions(rot, &pq1);
+
+ ::std::cout << "p1 = " << pq2.first << ::std::endl;
+ ::std::cout << "p2 = " << pq2.second << ::std::endl;
+
+ ::std::cout << "round trip discrepancy: " << ::std::sqrt(::boost::math::norm(pq1.first-pq2.first)+::boost::math::norm(pq1.second-pq2.second)) << ::std::endl;
+
+ ::std::cout << ::std::endl;
+ }
+ }
+ }
+ }
+ }
+ }
+
+ ::std::cout << ::std::endl;
+}
+
+
+void test_SO4()
+{
+ ::std::cout << "Testing SO4:" << ::std::endl;
+ ::std::cout << ::std::endl;
+
+ test_SO4_spherical();
+}
+
+
diff --git a/src/boost/libs/math/example/HSO4.hpp b/src/boost/libs/math/example/HSO4.hpp
new file mode 100644
index 000000000..e7171b815
--- /dev/null
+++ b/src/boost/libs/math/example/HSO4.hpp
@@ -0,0 +1,183 @@
+
+/********************************************************************************************/
+/* */
+/* HSO4.hpp header file */
+/* */
+/* This file is not currently part of the Boost library. It is simply an example of the use */
+/* quaternions can be put to. Hopefully it will be useful too. */
+/* */
+/* This file provides tools to convert between quaternions and R^4 rotation matrices. */
+/* */
+/********************************************************************************************/
+
+// (C) Copyright Hubert Holin 2001.
+// 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)
+
+#ifndef TEST_HSO4_HPP
+#define TEST_HSO4_HPP
+
+#include <utility>
+
+#include "HSO3.hpp"
+
+
+template<typename TYPE_FLOAT>
+struct R4_matrix
+{
+ TYPE_FLOAT a11, a12, a13, a14;
+ TYPE_FLOAT a21, a22, a23, a24;
+ TYPE_FLOAT a31, a32, a33, a34;
+ TYPE_FLOAT a41, a42, a43, a44;
+};
+
+
+// Note: the input quaternions need not be of norm 1 for the following function
+
+template<typename TYPE_FLOAT>
+R4_matrix<TYPE_FLOAT> quaternions_to_R4_rotation(::std::pair< ::boost::math::quaternion<TYPE_FLOAT> , ::boost::math::quaternion<TYPE_FLOAT> > const & pq)
+{
+ using ::std::numeric_limits;
+
+ TYPE_FLOAT a0 = pq.first.R_component_1();
+ TYPE_FLOAT b0 = pq.first.R_component_2();
+ TYPE_FLOAT c0 = pq.first.R_component_3();
+ TYPE_FLOAT d0 = pq.first.R_component_4();
+
+ TYPE_FLOAT norme_carre0 = a0*a0+b0*b0+c0*c0+d0*d0;
+
+ if (norme_carre0 <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Argument to quaternions_to_R4_rotation is too small!");
+ ::std::underflow_error bad_argument(error_reporting);
+
+ throw(bad_argument);
+ }
+
+ TYPE_FLOAT a1 = pq.second.R_component_1();
+ TYPE_FLOAT b1 = pq.second.R_component_2();
+ TYPE_FLOAT c1 = pq.second.R_component_3();
+ TYPE_FLOAT d1 = pq.second.R_component_4();
+
+ TYPE_FLOAT norme_carre1 = a1*a1+b1*b1+c1*c1+d1*d1;
+
+ if (norme_carre1 <= numeric_limits<TYPE_FLOAT>::epsilon())
+ {
+ ::std::string error_reporting("Argument to quaternions_to_R4_rotation is too small!");
+ ::std::underflow_error bad_argument(error_reporting);
+
+ throw(bad_argument);
+ }
+
+ TYPE_FLOAT prod_norm = norme_carre0*norme_carre1;
+
+ TYPE_FLOAT a0a1 = a0*a1;
+ TYPE_FLOAT a0b1 = a0*b1;
+ TYPE_FLOAT a0c1 = a0*c1;
+ TYPE_FLOAT a0d1 = a0*d1;
+ TYPE_FLOAT b0a1 = b0*a1;
+ TYPE_FLOAT b0b1 = b0*b1;
+ TYPE_FLOAT b0c1 = b0*c1;
+ TYPE_FLOAT b0d1 = b0*d1;
+ TYPE_FLOAT c0a1 = c0*a1;
+ TYPE_FLOAT c0b1 = c0*b1;
+ TYPE_FLOAT c0c1 = c0*c1;
+ TYPE_FLOAT c0d1 = c0*d1;
+ TYPE_FLOAT d0a1 = d0*a1;
+ TYPE_FLOAT d0b1 = d0*b1;
+ TYPE_FLOAT d0c1 = d0*c1;
+ TYPE_FLOAT d0d1 = d0*d1;
+
+ R4_matrix<TYPE_FLOAT> out_matrix;
+
+ out_matrix.a11 = (+a0a1+b0b1+c0c1+d0d1)/prod_norm;
+ out_matrix.a12 = (+a0b1-b0a1-c0d1+d0c1)/prod_norm;
+ out_matrix.a13 = (+a0c1+b0d1-c0a1-d0b1)/prod_norm;
+ out_matrix.a14 = (+a0d1-b0c1+c0b1-d0a1)/prod_norm;
+ out_matrix.a21 = (-a0b1+b0a1-c0d1+d0c1)/prod_norm;
+ out_matrix.a22 = (+a0a1+b0b1-c0c1-d0d1)/prod_norm;
+ out_matrix.a23 = (-a0d1+b0c1+c0b1-d0a1)/prod_norm;
+ out_matrix.a24 = (+a0c1+b0d1+c0a1+d0b1)/prod_norm;
+ out_matrix.a31 = (-a0c1+b0d1+c0a1-d0b1)/prod_norm;
+ out_matrix.a32 = (+a0d1+b0c1+c0b1+d0a1)/prod_norm;
+ out_matrix.a33 = (+a0a1-b0b1+c0c1-d0d1)/prod_norm;
+ out_matrix.a34 = (-a0b1-b0a1+c0d1+d0c1)/prod_norm;
+ out_matrix.a41 = (-a0d1-b0c1+c0b1+d0a1)/prod_norm;
+ out_matrix.a42 = (-a0c1+b0d1-c0a1+d0b1)/prod_norm;
+ out_matrix.a43 = (+a0b1+b0a1+c0d1+d0c1)/prod_norm;
+ out_matrix.a44 = (+a0a1-b0b1-c0c1+d0d1)/prod_norm;
+
+ return(out_matrix);
+}
+
+
+template<typename TYPE_FLOAT>
+inline bool is_R4_rotation_matrix(R4_matrix<TYPE_FLOAT> const & mat)
+{
+ using ::std::abs;
+
+ using ::std::numeric_limits;
+
+ return (
+ !(
+ (abs(mat.a11*mat.a11+mat.a21*mat.a21+mat.a31*mat.a31+mat.a41*mat.a41 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32+mat.a41*mat.a42 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33+mat.a41*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a11*mat.a14+mat.a21*mat.a24+mat.a31*mat.a34+mat.a41*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a11*mat.a12+mat.a21*mat.a22+mat.a31*mat.a32+mat.a41*mat.a42 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a12*mat.a12+mat.a22*mat.a22+mat.a32*mat.a32+mat.a42*mat.a42 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33+mat.a42*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a12*mat.a14+mat.a22*mat.a24+mat.a32*mat.a34+mat.a42*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a11*mat.a13+mat.a21*mat.a23+mat.a31*mat.a33+mat.a41*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a12*mat.a13+mat.a22*mat.a23+mat.a32*mat.a33+mat.a42*mat.a43 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a13*mat.a13+mat.a23*mat.a23+mat.a33*mat.a33+mat.a43*mat.a43 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a13*mat.a14+mat.a23*mat.a24+mat.a33*mat.a34+mat.a43*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a11*mat.a14+mat.a21*mat.a24+mat.a31*mat.a34+mat.a41*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a12*mat.a14+mat.a22*mat.a24+mat.a32*mat.a34+mat.a42*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ //(abs(mat.a13*mat.a14+mat.a23*mat.a24+mat.a33*mat.a34+mat.a43*mat.a44 - static_cast<TYPE_FLOAT>(0)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())||
+ (abs(mat.a14*mat.a14+mat.a24*mat.a24+mat.a34*mat.a34+mat.a44*mat.a44 - static_cast<TYPE_FLOAT>(1)) > static_cast<TYPE_FLOAT>(10)*numeric_limits<TYPE_FLOAT>::epsilon())
+ )
+ );
+}
+
+
+template<typename TYPE_FLOAT>
+::std::pair< ::boost::math::quaternion<TYPE_FLOAT> , ::boost::math::quaternion<TYPE_FLOAT> > R4_rotation_to_quaternions( R4_matrix<TYPE_FLOAT> const & rot,
+ ::std::pair< ::boost::math::quaternion<TYPE_FLOAT> , ::boost::math::quaternion<TYPE_FLOAT> > const * hint = 0)
+{
+ if (!is_R4_rotation_matrix(rot))
+ {
+ ::std::string error_reporting("Argument to R4_rotation_to_quaternions is not an R^4 rotation matrix!");
+ ::std::range_error bad_argument(error_reporting);
+
+ throw(bad_argument);
+ }
+
+ R3_matrix<TYPE_FLOAT> mat;
+
+ mat.a11 = -rot.a31*rot.a42+rot.a32*rot.a41+rot.a22*rot.a11-rot.a21*rot.a12;
+ mat.a12 = -rot.a31*rot.a43+rot.a33*rot.a41+rot.a23*rot.a11-rot.a21*rot.a13;
+ mat.a13 = -rot.a31*rot.a44+rot.a34*rot.a41+rot.a24*rot.a11-rot.a21*rot.a14;
+ mat.a21 = -rot.a31*rot.a12-rot.a22*rot.a41+rot.a32*rot.a11+rot.a21*rot.a42;
+ mat.a22 = -rot.a31*rot.a13-rot.a23*rot.a41+rot.a33*rot.a11+rot.a21*rot.a43;
+ mat.a23 = -rot.a31*rot.a14-rot.a24*rot.a41+rot.a34*rot.a11+rot.a21*rot.a44;
+ mat.a31 = +rot.a31*rot.a22-rot.a12*rot.a41+rot.a42*rot.a11-rot.a21*rot.a32;
+ mat.a32 = +rot.a31*rot.a23-rot.a13*rot.a41+rot.a43*rot.a11-rot.a21*rot.a33;
+ mat.a33 = +rot.a31*rot.a24-rot.a14*rot.a41+rot.a44*rot.a11-rot.a21*rot.a34;
+
+ ::boost::math::quaternion<TYPE_FLOAT> q = R3_rotation_to_quaternion(mat);
+
+ ::boost::math::quaternion<TYPE_FLOAT> p =
+ ::boost::math::quaternion<TYPE_FLOAT>(rot.a11,rot.a12,rot.a13,rot.a14)*q;
+
+ if ((hint != 0) && (abs(hint->second+q) < abs(hint->second-q)))
+ {
+ return(::std::make_pair(-p,-q));
+ }
+
+ return(::std::make_pair(p,q));
+}
+
+#endif /* TEST_HSO4_HPP */
+
diff --git a/src/boost/libs/math/example/Jamfile.v2 b/src/boost/libs/math/example/Jamfile.v2
new file mode 100644
index 000000000..fd40f3982
--- /dev/null
+++ b/src/boost/libs/math/example/Jamfile.v2
@@ -0,0 +1,159 @@
+# \libs\math\example\jamfile.v2
+# Runs statistics and floating-point examples.
+# Copyright 2007 John Maddock
+# Copyright Paul A. Bristow 2007, 2010, 2011.
+# 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)
+
+# bring in the rules for testing
+import testing ;
+import ../../config/checks/config : requires ;
+
+project
+ : requirements
+ <toolset>gcc:<cxxflags>-Wno-missing-braces
+ <toolset>darwin:<cxxflags>-Wno-missing-braces
+ <toolset>acc:<cxxflags>+W2068,2461,2236,4070
+ <toolset>intel:<cxxflags>-Qwd264,239
+ <toolset>msvc:<warnings>all
+ <toolset>msvc:<asynch-exceptions>on
+ <toolset>msvc:<define>_CRT_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_DEPRECATE
+ <toolset>msvc:<define>_SCL_SECURE_NO_WARNINGS
+ <toolset>msvc:<define>_CRT_SECURE_NO_WARNINGS
+ <toolset>msvc:<cxxflags>/wd4996
+ <toolset>msvc:<cxxflags>/wd4512
+ <toolset>msvc:<cxxflags>/wd4610
+ <toolset>msvc:<cxxflags>/wd4510
+ <toolset>msvc:<cxxflags>/wd4127
+ <toolset>msvc:<cxxflags>/wd4701
+ <toolset>msvc:<cxxflags>/wd4127
+ <toolset>msvc:<cxxflags>/wd4305
+ <toolset>msvc:<cxxflags>/wd4459
+ <toolset>msvc:<cxxflags>/wd4456 # declaration of hides previous local declaration.
+ #-<toolset>msvc:<cxxflags>/Za # nonfinite Serialization examples fail link if disable MS extensions,
+ # because serialization library is built with MS extensions enabled (default).
+ <toolset>clang:<cxxflags>-Wno-unknown-pragmas
+ <toolset>clang:<cxxflags>-Wno-language-extension-token
+
+ <include>../../..
+ <include>../include_private
+ <exception-handling>off:<source>../test//no_eh
+ ;
+
+test-suite examples :
+ [ run bessel_zeros_example_1.cpp : : : <exception-handling>off:<build>no ]
+ [ run bessel_zeros_interator_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run neumann_zeros_example_1.cpp : : : <exception-handling>off:<build>no ]
+
+ [ run test_cpp_float_close_fraction.cpp ../../test/build//boost_unit_test_framework/<link>static : : : <exception-handling>off:<build>no ]
+ [ run binomial_coinflip_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run binomial_confidence_limits.cpp ]
+ [ run binomial_example_nag.cpp ]
+ [ run binomial_quiz_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run binomial_sample_sizes.cpp ]
+ [ run brent_minimise_example.cpp : : : [ requires cxx11_hdr_tuple ] ]
+
+ [ run c_error_policy_example.cpp ]
+ [ run chi_square_std_dev_test.cpp : : : <exception-handling>off:<build>no ]
+ [ run distribution_construction.cpp : : : <exception-handling>off:<build>no ]
+ [ run error_handling_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run error_policies_example.cpp ]
+ [ run error_policy_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run f_test.cpp ]
+ # [ run fft_sines_table.cpp : : : [ requires cxx11_numeric_limits ] ]
+ # No need to re-run this routinely as it only creates a table of sines for a documentation example.
+
+ [ run find_location_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run find_mean_and_sd_normal.cpp : : : <exception-handling>off:<build>no ]
+ [ run find_root_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run find_scale_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run geometric_examples.cpp : : : <exception-handling>off:<build>no ]
+ [ run hyperexponential_snips.cpp ]
+ [ run hyperexponential_more_snips.cpp ]
+ [ run inverse_chi_squared_example.cpp ]
+ [ run legendre_stieltjes_example.cpp : : : [ requires cxx11_auto_declarations cxx11_defaulted_functions cxx11_lambdas ] ]
+ #[ # run inverse_chi_squared_find_df_example.cpp ]
+ #[ run lambert_w_basic_example.cpp ]
+ [ run lambert_w_basic_example.cpp : : : [ requires cxx11_numeric_limits ] ]
+ [ run lambert_w_simple_examples.cpp : : : [ requires cxx11_numeric_limits ] ]
+ [ run lambert_w_precision_example.cpp : : : [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_numeric_limits cxx11_explicit_conversion_operators ] ]
+
+ [ run inverse_gamma_example.cpp ]
+ [ run inverse_gamma_distribution_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run laplace_example.cpp : : : <exception-handling>off:<build>no ]
+ [ run nc_chi_sq_example.cpp ]
+ [ run neg_binom_confidence_limits.cpp ]
+ [ run neg_binomial_sample_sizes.cpp ]
+ [ run negative_binomial_example1.cpp : : : <exception-handling>off:<build>no ]
+ [ run negative_binomial_example2.cpp ]
+
+ [ run nonfinite_num_facet.cpp ]
+ [ run nonfinite_facet_simple.cpp ]
+ [ run nonfinite_num_facet_serialization.cpp ../../serialization/build//boost_serialization : : : <exception-handling>off:<build>no <toolset>gcc-mingw:<link>static ]
+ #[ # run lexical_cast_native.cpp ] # Expected to fail on some (but not all) platforms.
+ [ run lexical_cast_nonfinite_facets.cpp ]
+ [ run nonfinite_loopback_ok.cpp ]
+ [ run nonfinite_serialization_archives.cpp ../../serialization/build//boost_serialization : : : <exception-handling>off:<build>no <toolset>gcc-mingw:<link>static ]
+ [ run nonfinite_facet_sstream.cpp ]
+
+ [ run constants_eg1.cpp ]
+
+ [ run normal_misc_examples.cpp : : : <exception-handling>off:<build>no ]
+ [ run owens_t_example.cpp ]
+ [ run policy_eg_1.cpp ]
+ [ run policy_eg_10.cpp : : : <target-os>vxworks:<build>no ] # VxWorks' complex.h has conflicting declaration of real
+ [ run policy_eg_2.cpp ]
+ [ run policy_eg_3.cpp ]
+ [ run policy_eg_4.cpp ]
+ [ run policy_eg_5.cpp ]
+ [ run policy_eg_6.cpp ]
+ [ run policy_eg_7.cpp ]
+ [ run policy_eg_8.cpp ]
+ [ run policy_eg_9.cpp ]
+ [ run policy_ref_snip1.cpp : : : <exception-handling>off:<build>no ]
+ [ run policy_ref_snip10.cpp ]
+ [ run policy_ref_snip11.cpp ]
+ [ run policy_ref_snip12.cpp ]
+ [ run policy_ref_snip13.cpp : : : <exception-handling>off:<build>no ] # Fails clang-win - thrown exception from no Cauchy mean.
+ [ run policy_ref_snip2.cpp ]
+ [ run policy_ref_snip3.cpp : : : <exception-handling>off:<build>no ]
+ [ run policy_ref_snip4.cpp ]
+ [ run policy_ref_snip5.cpp : : : <target-os>vxworks:<build>no ]
+ [ run policy_ref_snip6.cpp ]
+ [ run policy_ref_snip7.cpp ]
+ [ run policy_ref_snip8.cpp ]
+ [ run policy_ref_snip9.cpp ]
+ [ run skew_normal_example.cpp ]
+ [ run students_t_example1.cpp ]
+ [ run students_t_example2.cpp ]
+ [ run students_t_example3.cpp ]
+ [ run students_t_single_sample.cpp ]
+ [ run students_t_two_samples.cpp ]
+ [ run HSO3SO4.cpp ]
+ [ run series.cpp ]
+ [ run continued_fractions.cpp ]
+
+ [ run barycentric_interpolation_example.cpp : : : [ requires cxx11_smart_ptr cxx11_function_template_default_args cxx11_unified_initialization_syntax cxx11_defaulted_functions cxx11_allocator cxx11_auto_declarations cxx11_lambdas ] ]
+ [ run barycentric_interpolation_example_2.cpp : : : [ requires cxx11_smart_ptr cxx11_function_template_default_args cxx11_unified_initialization_syntax cxx11_defaulted_functions cxx11_allocator cxx11_auto_declarations cxx11_lambdas ] ]
+ [ run cardinal_cubic_b_spline_example.cpp : : : [ requires cxx11_smart_ptr cxx11_hdr_random cxx11_defaulted_functions ] ]
+ [ compile naive_monte_carlo_example.cpp : [ requires cxx11_auto_declarations cxx11_lambdas cxx11_unified_initialization_syntax cxx11_hdr_thread cxx11_hdr_atomic cxx11_decltype cxx11_hdr_future cxx11_hdr_chrono cxx11_hdr_random cxx11_allocator ] ] # requires user input, can't run it, take a long time too!
+ [ run catmull_rom_example.cpp : : : [ requires cxx17_if_constexpr cxx11_auto_declarations cxx17_std_apply ] ] # Actually the C++17 features used is std::size, not if constexpr; looks like there isn't yet a test for it.
+ [ run autodiff_black_scholes_brief.cpp : : : [ requires cxx11_inline_namespaces ] ]
+ [ run autodiff_black_scholes.cpp : : : [ requires cxx11_inline_namespaces ] ]
+ [ run autodiff_fourth_power.cpp : : : [ requires cxx11_inline_namespaces ] ]
+ [ run autodiff_mixed_partials.cpp : : : [ requires cxx11_inline_namespaces ] ]
+ [ run autodiff_multiprecision.cpp : : : [ requires cxx11_inline_namespaces ] ]
+ [ run ooura_fourier_integrals_example.cpp : : : [ requires cxx11_hdr_mutex cxx11_lambdas cxx11_inline_namespaces cxx11_auto_declarations ] ]
+ [ run ooura_fourier_integrals_cosine_example.cpp : : : [ requires cxx11_hdr_mutex cxx11_inline_namespaces cxx11_auto_declarations cxx17_std_apply ] ]
+ [ run ooura_fourier_integrals_multiprecision_example.cpp : : : [ check-target-builds ../config//has_float128 "GCC libquadmath and __float128 support" : <linkflags>-lquadmath ] [ requires cxx11_hdr_mutex cxx11_inline_namespaces cxx11_auto_declarations cxx17_std_apply ] ]
+
+;
+
+run root_elliptic_finding.cpp /boost/timer : : : release <link>static [ requires cxx11_unified_initialization_syntax cxx11_defaulted_functions ] <target-os>freebsd:<linkflags>"-lrt" <target-os>linux:<linkflags>"-lrt -lpthread" ;
+run root_finding_algorithms.cpp /boost/timer : : : release <link>static [ requires cxx11_hdr_tuple cxx11_unified_initialization_syntax ] <target-os>freebsd:<linkflags>"-lrt" <target-os>linux:<linkflags>"-lrt -lpthread" ;
+run root_n_finding_algorithms.cpp /boost/timer : : : release <link>static [ requires cxx11_unified_initialization_syntax cxx11_defaulted_functions ] <target-os>freebsd:<linkflags>"-lrt" <target-os>linux:<linkflags>"-lrt -lpthread" ;
+
+explicit root_elliptic_finding ;
+explicit root_finding_algorithms ;
+explicit root_n_finding_algorithms ;
diff --git a/src/boost/libs/math/example/airy_zeros_example.cpp b/src/boost/libs/math/example/airy_zeros_example.cpp
new file mode 100644
index 000000000..3ab2c77d5
--- /dev/null
+++ b/src/boost/libs/math/example/airy_zeros_example.cpp
@@ -0,0 +1,165 @@
+
+// Copyright Christopher Kormanyos 2013.
+// Copyright Paul A. Bristow 2013.
+// Copyright John Maddock 2013.
+
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated.
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+
+// Weisstein, Eric W. "Bessel Function Zeros." From MathWorld--A Wolfram Web Resource.
+// http://mathworld.wolfram.com/BesselFunctionZeros.html
+// Test values can be calculated using [@wolframalpha.com WolframAplha]
+// See also http://dlmf.nist.gov/10.21
+
+//[airy_zeros_example_1
+
+/*`This example demonstrates calculating zeros of the Airy functions.
+It also shows how Boost.Math and Boost.Multiprecision can be combined to provide
+a many decimal digit precision. For 50 decimal digit precision we need to include
+*/
+
+ #include <boost/multiprecision/cpp_dec_float.hpp>
+
+/*`and a `typedef` for `float_type` may be convenient
+(allowing a quick switch to re-compute at built-in `double` or other precision)
+*/
+ typedef boost::multiprecision::cpp_dec_float_50 float_type;
+
+//`To use the functions for finding zeros of the functions we need
+
+ #include <boost/math/special_functions/airy.hpp>
+
+/*`This example shows obtaining both a single zero of the Airy functions,
+and then placing multiple zeros into a container like `std::vector` by providing an iterator.
+The signature of the single-value Airy Ai function is:
+
+ template <class T>
+ T airy_ai_zero(unsigned m); // 1-based index of the zero.
+
+The signature of multiple zeros Airy Ai function is:
+
+ template <class T, class OutputIterator>
+ OutputIterator airy_ai_zero(
+ unsigned start_index, // 1-based index of the zero.
+ unsigned number_of_zeros, // How many zeros to generate.
+ OutputIterator out_it); // Destination for zeros.
+
+There are also versions which allows control of the __policy_section for error handling and precision.
+
+ template <class T, class OutputIterator, class Policy>
+ OutputIterator airy_ai_zero(
+ unsigned start_index, // 1-based index of the zero.
+ unsigned number_of_zeros, // How many zeros to generate.
+ OutputIterator out_it, // Destination for zeros.
+ const Policy& pol); // Policy to use.
+*/
+//] [/airy_zeros_example_1]
+
+int main()
+{
+ try
+ {
+//[airy_zeros_example_2
+
+/*`[tip It is always wise to place code using Boost.Math inside `try'n'catch` blocks;
+this will ensure that helpful error messages are shown when exceptional conditions arise.]
+
+First, evaluate a single Airy zero.
+
+The precision is controlled by the template parameter `T`,
+so this example has `double` precision, at least 15 but up to 17 decimal digits
+(for the common 64-bit double).
+*/
+ double aiz1 = boost::math::airy_ai_zero<double>(1);
+ std::cout << "boost::math::airy_ai_zero<double>(1) = " << aiz1 << std::endl;
+ double aiz2 = boost::math::airy_ai_zero<double>(2);
+ std::cout << "boost::math::airy_ai_zero<double>(2) = " << aiz2 << std::endl;
+ double biz3 = boost::math::airy_bi_zero<double>(3);
+ std::cout << "boost::math::airy_bi_zero<double>(3) = " << biz3 << std::endl;
+
+/*`Other versions of `airy_ai_zero` and `airy_bi_zero`
+allow calculation of multiple zeros with one call,
+placing the results in a container, often `std::vector`.
+For example, generate and display the first five `double` roots
+[@http://mathworld.wolfram.com/AiryFunctionZeros.html Wolfram Airy Functions Zeros].
+*/
+ unsigned int n_roots = 5U;
+ std::vector<double> roots;
+ boost::math::airy_ai_zero<double>(1U, n_roots, std::back_inserter(roots));
+ std::cout << "airy_ai_zeros:" << std::endl;
+ std::copy(roots.begin(),
+ roots.end(),
+ std::ostream_iterator<double>(std::cout, "\n"));
+
+/*`The first few real roots of Ai(x) are approximately -2.33811, -4.08795, -5.52056, -6.7867144, -7.94413, -9.02265 ...
+
+Or we can use Boost.Multiprecision to generate 50 decimal digit roots.
+
+We set the precision of the output stream, and show trailing zeros to display a fixed 50 decimal digits.
+*/
+ std::cout.precision(std::numeric_limits<float_type>::digits10); // float_type has 50 decimal digits.
+ std::cout << std::showpoint << std::endl; // Show trailing zeros too.
+
+ unsigned int m = 1U;
+ float_type r = boost::math::airy_ai_zero<float_type>(1U); // 1st root.
+ std::cout << "boost::math::airy_bi_zero<float_type>(" << m << ") = " << r << std::endl;
+ m = 2;
+ r = boost::math::airy_ai_zero<float_type>(2U); // 2nd root.
+ std::cout << "boost::math::airy_bi_zero<float_type>(" << m << ") = " << r << std::endl;
+ m = 7U;
+ r = boost::math::airy_bi_zero<float_type>(7U); // 7th root.
+ std::cout << "boost::math::airy_bi_zero<float_type>(" << m << ") = " << r << std::endl;
+
+ std::vector<float_type> zeros;
+ boost::math::airy_ai_zero<float_type>(1U, 3, std::back_inserter(zeros));
+ std::cout << "airy_ai_zeros:" << std::endl;
+ // Print the roots to the output stream.
+ std::copy(zeros.begin(), zeros.end(),
+ std::ostream_iterator<float_type>(std::cout, "\n"));
+//] [/airy_zeros_example_2]
+ }
+ catch (std::exception ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ } // int main()
+
+/*
+
+ Output:
+
+ Description: Autorun "J:\Cpp\big_number\Debug\airy_zeros_example.exe"
+ boost::math::airy_ai_zero<double>(1) = -2.33811
+ boost::math::airy_ai_zero<double>(2) = -4.08795
+ boost::math::airy_bi_zero<double>(3) = -4.83074
+ airy_ai_zeros:
+ -2.33811
+ -4.08795
+ -5.52056
+ -6.78671
+ -7.94413
+
+ boost::math::airy_bi_zero<float_type>(1) = -2.3381074104597670384891972524467354406385401456711
+ boost::math::airy_bi_zero<float_type>(2) = -4.0879494441309706166369887014573910602247646991085
+ boost::math::airy_bi_zero<float_type>(7) = -9.5381943793462388866329885451560196208390720763825
+ airy_ai_zeros:
+ -2.3381074104597670384891972524467354406385401456711
+ -4.0879494441309706166369887014573910602247646991085
+ -5.5205598280955510591298555129312935737972142806175
+
+*/
+
diff --git a/src/boost/libs/math/example/arcsine_example.cpp b/src/boost/libs/math/example/arcsine_example.cpp
new file mode 100644
index 000000000..aa757f3ea
--- /dev/null
+++ b/src/boost/libs/math/example/arcsine_example.cpp
@@ -0,0 +1,89 @@
+// arcsine_example.cpp
+
+// Copyright John Maddock 2014.
+// Copyright Paul A. Bristow 2014.
+
+// 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)
+
+// Example for the arcsine Distribution.
+
+// Note: Contains Quickbook snippets in comments.
+
+//[arcsine_snip_1
+#include <boost/math/distributions/arcsine.hpp> // For arcsine_distribution.
+//] [/arcsine_snip_1]
+
+#include <iostream>
+#include <exception>
+#include <boost/assert.hpp>
+
+int main()
+{
+ std::cout << "Examples of Arcsine distribution." << std::endl;
+ std::cout.precision(3); // Avoid uninformative decimal digits.
+
+ using boost::math::arcsine;
+
+ arcsine as; // Construct a default `double` standard [0, 1] arcsine distribution.
+
+//[arcsine_snip_2
+ std::cout << pdf(as, 1. / 2) << std::endl; // 0.637
+ // pdf has a minimum at x = 0.5
+//] [/arcsine_snip_2]
+
+//[arcsine_snip_3
+ std::cout << pdf(as, 1. / 4) << std::endl; // 0.735
+//] [/arcsine_snip_3]
+
+
+//[arcsine_snip_4
+ std::cout << cdf(as, 0.05) << std::endl; // 0.144
+//] [/arcsine_snip_4]
+
+//[arcsine_snip_5
+ std::cout << 2 * cdf(as, 1 - 0.975) << std::endl; // 0.202
+//] [/arcsine_snip_5]
+
+
+//[arcsine_snip_6
+ std::cout << 2 * cdf(complement(as, 0.975)) << std::endl; // 0.202
+//] [/arcsine_snip_6]
+
+//[arcsine_snip_7
+ std::cout << quantile(as, 1 - 0.2 / 2) << std::endl; // 0.976
+
+ std::cout << quantile(complement(as, 0.2 / 2)) << std::endl; // 0.976
+//] [/arcsine_snip_7]
+
+{
+//[arcsine_snip_8
+ using boost::math::arcsine_distribution;
+
+ arcsine_distribution<> as(2, 5); // Constructs a double arcsine distribution.
+ BOOST_ASSERT(as.x_min() == 2.); // as.x_min() returns 2.
+ BOOST_ASSERT(as.x_max() == 5.); // as.x_max() returns 5.
+//] [/arcsine_snip_8]
+}
+ return 0;
+
+} // int main()
+
+/*
+[arcsine_output
+
+Example of Arcsine distribution
+0.637
+0.735
+0.144
+0.202
+0.202
+0.976
+0.976
+
+] [/arcsine_output]
+*/
+
+
diff --git a/src/boost/libs/math/example/autodiff_black_scholes.cpp b/src/boost/libs/math/example/autodiff_black_scholes.cpp
new file mode 100644
index 000000000..b7fcd9c0a
--- /dev/null
+++ b/src/boost/libs/math/example/autodiff_black_scholes.cpp
@@ -0,0 +1,195 @@
+// Copyright Matthew Pulver 2018 - 2019.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/math/differentiation/autodiff.hpp>
+#include <iostream>
+#include <stdexcept>
+
+using namespace boost::math::constants;
+using namespace boost::math::differentiation;
+
+// Equations and function/variable names are from
+// https://en.wikipedia.org/wiki/Greeks_(finance)#Formulas_for_European_option_Greeks
+
+// Standard normal probability density function
+template <typename X>
+X phi(X const& x) {
+ return one_div_root_two_pi<X>() * exp(-0.5 * x * x);
+}
+
+// Standard normal cumulative distribution function
+template <typename X>
+X Phi(X const& x) {
+ return 0.5 * erfc(-one_div_root_two<X>() * x);
+}
+
+enum class CP { call, put };
+
+// Assume zero annual dividend yield (q=0).
+template <typename Price, typename Sigma, typename Tau, typename Rate>
+promote<Price, Sigma, Tau, Rate> black_scholes_option_price(CP cp,
+ double K,
+ Price const& S,
+ Sigma const& sigma,
+ Tau const& tau,
+ Rate const& r) {
+ using namespace std;
+ auto const d1 = (log(S / K) + (r + sigma * sigma / 2) * tau) / (sigma * sqrt(tau));
+ auto const d2 = (log(S / K) + (r - sigma * sigma / 2) * tau) / (sigma * sqrt(tau));
+ switch (cp) {
+ case CP::call:
+ return S * Phi(d1) - exp(-r * tau) * K * Phi(d2);
+ case CP::put:
+ return exp(-r * tau) * K * Phi(-d2) - S * Phi(-d1);
+ default:
+ throw std::runtime_error("Invalid CP value.");
+ }
+}
+
+int main() {
+ double const K = 100.0; // Strike price.
+ auto const variables = make_ftuple<double, 3, 3, 1, 1>(105, 5, 30.0 / 365, 1.25 / 100);
+ auto const& S = std::get<0>(variables); // Stock price.
+ auto const& sigma = std::get<1>(variables); // Volatility.
+ auto const& tau = std::get<2>(variables); // Time to expiration in years. (30 days).
+ auto const& r = std::get<3>(variables); // Interest rate.
+ auto const call_price = black_scholes_option_price(CP::call, K, S, sigma, tau, r);
+ auto const put_price = black_scholes_option_price(CP::put, K, S, sigma, tau, r);
+
+ double const d1 = static_cast<double>((log(S / K) + (r + sigma * sigma / 2) * tau) / (sigma * sqrt(tau)));
+ double const d2 = static_cast<double>((log(S / K) + (r - sigma * sigma / 2) * tau) / (sigma * sqrt(tau)));
+ double const formula_call_delta = +Phi(+d1);
+ double const formula_put_delta = -Phi(-d1);
+ double const formula_vega = static_cast<double>(S * phi(d1) * sqrt(tau));
+ double const formula_call_theta =
+ static_cast<double>(-S * phi(d1) * sigma / (2 * sqrt(tau)) - r * K * exp(-r * tau) * Phi(+d2));
+ double const formula_put_theta =
+ static_cast<double>(-S * phi(d1) * sigma / (2 * sqrt(tau)) + r * K * exp(-r * tau) * Phi(-d2));
+ double const formula_call_rho = static_cast<double>(+K * tau * exp(-r * tau) * Phi(+d2));
+ double const formula_put_rho = static_cast<double>(-K * tau * exp(-r * tau) * Phi(-d2));
+ double const formula_gamma = static_cast<double>(phi(d1) / (S * sigma * sqrt(tau)));
+ double const formula_vanna = static_cast<double>(-phi(d1) * d2 / sigma);
+ double const formula_charm =
+ static_cast<double>(phi(d1) * (d2 * sigma * sqrt(tau) - 2 * r * tau) / (2 * tau * sigma * sqrt(tau)));
+ double const formula_vomma = static_cast<double>(S * phi(d1) * sqrt(tau) * d1 * d2 / sigma);
+ double const formula_veta = static_cast<double>(-S * phi(d1) * sqrt(tau) *
+ (r * d1 / (sigma * sqrt(tau)) - (1 + d1 * d2) / (2 * tau)));
+ double const formula_speed =
+ static_cast<double>(-phi(d1) * (d1 / (sigma * sqrt(tau)) + 1) / (S * S * sigma * sqrt(tau)));
+ double const formula_zomma = static_cast<double>(phi(d1) * (d1 * d2 - 1) / (S * sigma * sigma * sqrt(tau)));
+ double const formula_color =
+ static_cast<double>(-phi(d1) / (2 * S * tau * sigma * sqrt(tau)) *
+ (1 + (2 * r * tau - d2 * sigma * sqrt(tau)) * d1 / (sigma * sqrt(tau))));
+ double const formula_ultima =
+ -formula_vega * static_cast<double>((d1 * d2 * (1 - d1 * d2) + d1 * d1 + d2 * d2) / (sigma * sigma));
+
+ std::cout << std::setprecision(std::numeric_limits<double>::digits10)
+ << "autodiff black-scholes call price = " << call_price.derivative(0, 0, 0, 0) << '\n'
+ << "autodiff black-scholes put price = " << put_price.derivative(0, 0, 0, 0) << '\n'
+ << "\n## First-order Greeks\n"
+ << "autodiff call delta = " << call_price.derivative(1, 0, 0, 0) << '\n'
+ << " formula call delta = " << formula_call_delta << '\n'
+ << "autodiff call vega = " << call_price.derivative(0, 1, 0, 0) << '\n'
+ << " formula call vega = " << formula_vega << '\n'
+ << "autodiff call theta = " << -call_price.derivative(0, 0, 1, 0)
+ << '\n' // minus sign due to tau = T-time
+ << " formula call theta = " << formula_call_theta << '\n'
+ << "autodiff call rho = " << call_price.derivative(0, 0, 0, 1) << '\n'
+ << " formula call rho = " << formula_call_rho << '\n'
+ << '\n'
+ << "autodiff put delta = " << put_price.derivative(1, 0, 0, 0) << '\n'
+ << " formula put delta = " << formula_put_delta << '\n'
+ << "autodiff put vega = " << put_price.derivative(0, 1, 0, 0) << '\n'
+ << " formula put vega = " << formula_vega << '\n'
+ << "autodiff put theta = " << -put_price.derivative(0, 0, 1, 0) << '\n'
+ << " formula put theta = " << formula_put_theta << '\n'
+ << "autodiff put rho = " << put_price.derivative(0, 0, 0, 1) << '\n'
+ << " formula put rho = " << formula_put_rho << '\n'
+ << "\n## Second-order Greeks\n"
+ << "autodiff call gamma = " << call_price.derivative(2, 0, 0, 0) << '\n'
+ << "autodiff put gamma = " << put_price.derivative(2, 0, 0, 0) << '\n'
+ << " formula gamma = " << formula_gamma << '\n'
+ << "autodiff call vanna = " << call_price.derivative(1, 1, 0, 0) << '\n'
+ << "autodiff put vanna = " << put_price.derivative(1, 1, 0, 0) << '\n'
+ << " formula vanna = " << formula_vanna << '\n'
+ << "autodiff call charm = " << -call_price.derivative(1, 0, 1, 0) << '\n'
+ << "autodiff put charm = " << -put_price.derivative(1, 0, 1, 0) << '\n'
+ << " formula charm = " << formula_charm << '\n'
+ << "autodiff call vomma = " << call_price.derivative(0, 2, 0, 0) << '\n'
+ << "autodiff put vomma = " << put_price.derivative(0, 2, 0, 0) << '\n'
+ << " formula vomma = " << formula_vomma << '\n'
+ << "autodiff call veta = " << call_price.derivative(0, 1, 1, 0) << '\n'
+ << "autodiff put veta = " << put_price.derivative(0, 1, 1, 0) << '\n'
+ << " formula veta = " << formula_veta << '\n'
+ << "\n## Third-order Greeks\n"
+ << "autodiff call speed = " << call_price.derivative(3, 0, 0, 0) << '\n'
+ << "autodiff put speed = " << put_price.derivative(3, 0, 0, 0) << '\n'
+ << " formula speed = " << formula_speed << '\n'
+ << "autodiff call zomma = " << call_price.derivative(2, 1, 0, 0) << '\n'
+ << "autodiff put zomma = " << put_price.derivative(2, 1, 0, 0) << '\n'
+ << " formula zomma = " << formula_zomma << '\n'
+ << "autodiff call color = " << call_price.derivative(2, 0, 1, 0) << '\n'
+ << "autodiff put color = " << put_price.derivative(2, 0, 1, 0) << '\n'
+ << " formula color = " << formula_color << '\n'
+ << "autodiff call ultima = " << call_price.derivative(0, 3, 0, 0) << '\n'
+ << "autodiff put ultima = " << put_price.derivative(0, 3, 0, 0) << '\n'
+ << " formula ultima = " << formula_ultima << '\n';
+ return 0;
+}
+/*
+Output:
+autodiff black-scholes call price = 56.5136030677739
+autodiff black-scholes put price = 51.4109161009333
+
+## First-order Greeks
+autodiff call delta = 0.773818444921273
+ formula call delta = 0.773818444921274
+autodiff call vega = 9.05493427705736
+ formula call vega = 9.05493427705736
+autodiff call theta = -275.73013426444
+ formula call theta = -275.73013426444
+autodiff call rho = 2.03320550539396
+ formula call rho = 2.03320550539396
+
+autodiff put delta = -0.226181555078726
+ formula put delta = -0.226181555078726
+autodiff put vega = 9.05493427705736
+ formula put vega = 9.05493427705736
+autodiff put theta = -274.481417851526
+ formula put theta = -274.481417851526
+autodiff put rho = -6.17753255212599
+ formula put rho = -6.17753255212599
+
+## Second-order Greeks
+autodiff call gamma = 0.00199851912993254
+autodiff put gamma = 0.00199851912993254
+ formula gamma = 0.00199851912993254
+autodiff call vanna = 0.0410279463126531
+autodiff put vanna = 0.0410279463126531
+ formula vanna = 0.0410279463126531
+autodiff call charm = -1.2505564233679
+autodiff put charm = -1.2505564233679
+ formula charm = -1.2505564233679
+autodiff call vomma = -0.928114149313108
+autodiff put vomma = -0.928114149313108
+ formula vomma = -0.928114149313107
+autodiff call veta = 26.7947073115641
+autodiff put veta = 26.7947073115641
+ formula veta = 26.7947073115641
+
+## Third-order Greeks
+autodiff call speed = -2.90117322380992e-05
+autodiff put speed = -2.90117322380992e-05
+ formula speed = -2.90117322380992e-05
+autodiff call zomma = -0.000604548369901419
+autodiff put zomma = -0.000604548369901419
+ formula zomma = -0.000604548369901419
+autodiff call color = -0.0184014426606065
+autodiff put color = -0.0184014426606065
+ formula color = -0.0184014426606065
+autodiff call ultima = -0.0922426864775683
+autodiff put ultima = -0.0922426864775683
+ formula ultima = -0.0922426864775685
+**/
diff --git a/src/boost/libs/math/example/autodiff_black_scholes_brief.cpp b/src/boost/libs/math/example/autodiff_black_scholes_brief.cpp
new file mode 100644
index 000000000..7078217b6
--- /dev/null
+++ b/src/boost/libs/math/example/autodiff_black_scholes_brief.cpp
@@ -0,0 +1,70 @@
+// Copyright Matthew Pulver 2018 - 2019.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/math/differentiation/autodiff.hpp>
+#include <iostream>
+#include <stdexcept>
+
+using namespace boost::math::constants;
+using namespace boost::math::differentiation;
+
+// Equations and function/variable names are from
+// https://en.wikipedia.org/wiki/Greeks_(finance)#Formulas_for_European_option_Greeks
+
+// Standard normal cumulative distribution function
+template <typename X>
+X Phi(X const& x) {
+ return 0.5 * erfc(-one_div_root_two<X>() * x);
+}
+
+enum class CP { call, put };
+
+// Assume zero annual dividend yield (q=0).
+template <typename Price, typename Sigma, typename Tau, typename Rate>
+promote<Price, Sigma, Tau, Rate> black_scholes_option_price(CP cp,
+ double K,
+ Price const& S,
+ Sigma const& sigma,
+ Tau const& tau,
+ Rate const& r) {
+ using namespace std;
+ auto const d1 = (log(S / K) + (r + sigma * sigma / 2) * tau) / (sigma * sqrt(tau));
+ auto const d2 = (log(S / K) + (r - sigma * sigma / 2) * tau) / (sigma * sqrt(tau));
+ switch (cp) {
+ case CP::call:
+ return S * Phi(d1) - exp(-r * tau) * K * Phi(d2);
+ case CP::put:
+ return exp(-r * tau) * K * Phi(-d2) - S * Phi(-d1);
+ default:
+ throw std::runtime_error("Invalid CP value.");
+ }
+}
+
+int main() {
+ double const K = 100.0; // Strike price.
+ auto const S = make_fvar<double, 2>(105); // Stock price.
+ double const sigma = 5; // Volatility.
+ double const tau = 30.0 / 365; // Time to expiration in years. (30 days).
+ double const r = 1.25 / 100; // Interest rate.
+ auto const call_price = black_scholes_option_price(CP::call, K, S, sigma, tau, r);
+ auto const put_price = black_scholes_option_price(CP::put, K, S, sigma, tau, r);
+
+ std::cout << "black-scholes call price = " << call_price.derivative(0) << '\n'
+ << "black-scholes put price = " << put_price.derivative(0) << '\n'
+ << "call delta = " << call_price.derivative(1) << '\n'
+ << "put delta = " << put_price.derivative(1) << '\n'
+ << "call gamma = " << call_price.derivative(2) << '\n'
+ << "put gamma = " << put_price.derivative(2) << '\n';
+ return 0;
+}
+/*
+Output:
+black-scholes call price = 56.5136
+black-scholes put price = 51.4109
+call delta = 0.773818
+put delta = -0.226182
+call gamma = 0.00199852
+put gamma = 0.00199852
+**/
diff --git a/src/boost/libs/math/example/autodiff_fourth_power.cpp b/src/boost/libs/math/example/autodiff_fourth_power.cpp
new file mode 100644
index 000000000..50f280b6b
--- /dev/null
+++ b/src/boost/libs/math/example/autodiff_fourth_power.cpp
@@ -0,0 +1,34 @@
+// Copyright Matthew Pulver 2018 - 2019.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/math/differentiation/autodiff.hpp>
+#include <iostream>
+
+template <typename T>
+T fourth_power(T const& x) {
+ T x4 = x * x; // retval in operator*() uses x4's memory via NRVO.
+ x4 *= x4; // No copies of x4 are made within operator*=() even when squaring.
+ return x4; // x4 uses y's memory in main() via NRVO.
+}
+
+int main() {
+ using namespace boost::math::differentiation;
+
+ constexpr unsigned Order = 5; // Highest order derivative to be calculated.
+ auto const x = make_fvar<double, Order>(2.0); // Find derivatives at x=2.
+ auto const y = fourth_power(x);
+ for (unsigned i = 0; i <= Order; ++i)
+ std::cout << "y.derivative(" << i << ") = " << y.derivative(i) << std::endl;
+ return 0;
+}
+/*
+Output:
+y.derivative(0) = 16
+y.derivative(1) = 32
+y.derivative(2) = 48
+y.derivative(3) = 48
+y.derivative(4) = 24
+y.derivative(5) = 0
+**/
diff --git a/src/boost/libs/math/example/autodiff_mixed_partials.cpp b/src/boost/libs/math/example/autodiff_mixed_partials.cpp
new file mode 100644
index 000000000..551429e01
--- /dev/null
+++ b/src/boost/libs/math/example/autodiff_mixed_partials.cpp
@@ -0,0 +1,293 @@
+// Copyright Matthew Pulver 2018 - 2019.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/lexical_cast.hpp>
+#include <boost/math/differentiation/autodiff.hpp>
+#include <boost/mp11/tuple.hpp>
+#include <boost/mp11/utility.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+#include <iostream>
+
+using namespace boost::math::differentiation;
+
+struct f {
+ template <typename W, typename X, typename Y, typename Z>
+ promote<W, X, Y, Z> operator()(W const& w, X const& x, Y const& y, Z const& z) const {
+ return exp(w * sin(x * log(y) / z) + sqrt(w * z / (x * y))) + w * w / tan(z);
+ }
+};
+
+// Derivatives calculated from symbolic differentiation by Mathematica for comparison. Script:
+// mixed_partials.nb
+static constexpr std::array<char const*, 240> answers{
+ {"19878.40628980434922342465374997798674242532797789489",
+ "20731.74838274939517275508122761443159515217855975002",
+ "14667.60767623939014840117674691707821648144188283774",
+ "1840.559936449813118734351750381849294157477519107602",
+ "-9219.318005237072129605008516120710807803827373819700",
+ "-7272.300634012811783845589472196110804386170683300081",
+ "-2135.296370062283924160196772166043360841114107521292",
+ "3095.081027251846799545897828297310835169325417217168",
+ "4249.026762908615627428402369471953790564918480025345",
+ "2063.989061062734416582172072883742097425754355167541",
+ "-885.5284114876496084068555333811894392182458751895290",
+ "-1962.133420441743158021558423645064067562765178375508",
+ "-1846.899830787084518564013512948598850243350915531775",
+ "-160.9590127603295755195950112199107484483554942817846",
+ "1091.039412341633994110997652976585409621806446647794",
+ "452.4395574345229946707651998323417632800605985181691",
+ "666.4013922727704990031159406121675703174518834914461",
+ "-415.6464114333629107803309520898363153301435468382605",
+ "-625.1464179039986361267627631122900331946746137220517",
+ "369.9491669772617110087494756677334192842413470837587",
+ "-24330.89613849389343130420303653062335840497802221681",
+ "-18810.41605175626752065686192937776868736029049989926",
+ "-4890.406122702359099863022925593448420259414896197252",
+ "8833.005054768976417065486877649473665597894570245307",
+ "8484.350739681613747819854384228795938450532463850094",
+ "3097.204151240398893507362023543393154680147349049848",
+ "-3255.045136783440612110181337652522080890693968833148",
+ "-4342.778553332193097878812792875447018366988006584840",
+ "-2407.987237906523486012534085031032446996713414362131",
+ "861.1173916470300084261504495377425043024739914571554",
+ "2436.743725763308619092960749816106318692933687303014",
+ "-19.24649610733827783846392798978023489104363382129689",
+ "187.7855148870511714395275130898958731897480766620821",
+ "-1259.466063335212195169531010871023748854744563232277",
+ "-709.6860523972158261343923419671629587637051060458295",
+ "1423.000558608604536932163648918899935569543711292466",
+ "484.9208133389233959103861107714757012185008046446372",
+ "763.9746885074453180462508029718247316712990115789154",
+ "-327.4162918228055568224139277603073169658358026440432",
+ "-1122.337707248494521123614369562896901904418640152220",
+ "23973.06007192346989337502250398494874845408708506720",
+ "8840.543151778796869949670401421984604862699128880003",
+ "-9082.571033221549378277312292526023838132689941236879",
+ "-12270.27378289258717737657881957466807305650429436397",
+ "-4320.434071420599854743576892819691675331049612545664",
+ "3281.351967707280898543984556670710235259118405463698",
+ "5880.336263083418767219493592767818708317492833223933",
+ "-1288.482785219706549809211085113790275109642879331959",
+ "-803.9713537626580526627976840414468844364935388365037",
+ "-2986.387245331698390346145949708414455858834967096376",
+ "-586.7316859822658306283656047992829723003491823675739",
+ "3929.073189280739356198769778905960586080418779863615",
+ "1453.728280983826630077825553258703050898056317382483",
+ "1037.878071685953829685046234106860743366780050925514",
+ "-1482.745805277401336553926171580259185140208053329753",
+ "-1877.134792933828810602377451370316364621357891989679",
+ "-931.7138710369298207131581126980851620513905805624544",
+ "254.6565590420322632851077818917210811815919344882311",
+ "1391.248064745611663849820246430123214796614030838600",
+ "-431.4820563154137955051720207563800896297257103310465",
+ "16975.34005365179555009050533000516107937041784876054",
+ "19662.60356303341709846238790020024593550984564081068",
+ "15765.85130704020004301064240357947656083104783442825",
+ "3972.155036195937013764185795634749937308876197976202",
+ "-8681.748539789720512499473840242996096730194203989543",
+ "-7703.183042460387656743498394861780784700076575106134",
+ "-3049.708696569518774040135942468704911634779352213044",
+ "2971.469685992270876159892302788930292108129670398058",
+ "4370.196499857550025657084783894747734031876677385611",
+ "2524.632473357435670756946837415389227139966527203701",
+ "-656.6080000236679071742450437463693211275208125750923",
+ "-2423.452917325258132591368397957959217829861665178601",
+ "-2074.987664204263204162199830716851483704870169031179",
+ "-381.2253794988132984501358802316138392247470857452486",
+ "1219.507245791997351017860252538035146744682380716428",
+ "805.3802239840836877339667281819652171888443003165988",
+ "838.4004190058912380470543219448821914235443115661655",
+ "-390.6125197108983831575656956558201636111305409512701",
+ "-828.2085489298235758253219930356006757081473789845849",
+ "293.8999854454994790079171865082094494146506490533363",
+ "-22965.85985843951977785883587223006628792405076928067",
+ "-20026.69101529929621743747554537576887048069629325374",
+ "-7316.092745063355996548975300169565482331369744607021",
+ "8632.466133972614659252310985982644793465043032940318",
+ "8987.046882870452266200748127338744248816756004290490",
+ "4199.925399536137541108783465785304128965582292174062",
+ "-2958.429850896062893179851696175634522187021390095560",
+ "-5665.563891218624062243686482808197054863235184904433",
+ "-2945.404552250341615883104643651287431663294281737652",
+ "555.6566272478262524735403145861484390537770707372992",
+ "2936.796403550079139218970638242013974322758744804216",
+ "651.5191650747110008135060635556227666232180743487328",
+ "444.7629427486155148584918602702161457622049333694568",
+ "-1390.989671799095801316658971275073184600067187023729",
+ "-1142.861468946763860859271224968631944511098747155437",
+ "1541.978723117340843491920690654997335632919116206279",
+ "455.7146063293814470171599782651235242129856311098151",
+ "998.7943503940357037260061331795191352937661538946216",
+ "-204.8485581981121295383497187536442450324011940647949",
+ "-1560.354115460478786113711476250386112014306509906244",
+ "25278.29450605247223516529112562423587288781657290275",
+ "11873.22337179046469888005044109378787446671408425048",
+ "-8242.187303368878103323785658604027555126374435611949",
+ "-15939.98056417465751946455567789306872745912255628512",
+ "-5648.833539698031486810309720694416837861242341227280",
+ "2751.513926122717118525029734574022921057261239749143",
+ "7349.432002479077129245930487320138527887196396579062",
+ "194.9972545980371127390142753318206783334452047502143",
+ "-402.8156857682688265622049800462325595907987257153782",
+ "-3518.871908683063371167722463713374376552181380727802",
+ "-1494.304793474682619087166400375396721307777439607909",
+ "4640.927509426080087451995953783429589632369803588940",
+ "1585.757705203227141964561144798400703219894640413562",
+ "1565.169992404407137888592924342582799362959736185298",
+ "-1513.259809733540018859089666188672238777297615451800",
+ "-2974.437872674680092826212901753475972242208819679978",
+ "-1203.236292653823441598437153564865951527142648802876",
+ "72.52425949879153384040698301599842998884036742649047",
+ "1871.625274253419949517250818647194858608124560073483",
+ "-2.489984337379681666361341362948045621969765070197429",
+ "14462.74423518633102580192225823524237502860825596609",
+ "18367.74740916432711689913219912502810575714860430297",
+ "16565.76324499673961400925630526921000337443450249297",
+ "6054.315252651102952034254100792777051580892954459740",
+ "-8084.981271982030146065497115893934803061545998433631",
+ "-7988.314359128201297240919364015959817416101519999194",
+ "-3989.319346941492698525859335371231602272119870228687",
+ "2616.721186534649016680934493970036169897788778926434",
+ "4420.859270970486562095630193355634655337290952862363",
+ "2973.033519764547909146474824627687039969488363657908",
+ "-324.1453016982713707989332262410969595194473127209825",
+ "-2843.242039958969221918101261762794653424879358390111",
+ "-2281.461806143289517702658392470195144560150025832652",
+ "-642.9353229582055924928927665183236308235598082837497",
+ "1299.287274176955358490409470855361289523321919337117",
+ "1238.597083372069762230817383681570828675426312803376",
+ "1021.334042770848165110529668635291528449691525937968",
+ "-329.0529345069271079573348500899329811170455711610811",
+ "-1046.254301544052075124857362060924818517694048905299",
+ "134.7343039554480655186788228552325941588620079791654",
+ "-21431.41643507661192392650726158493697457993678274754",
+ "-20856.88281479015784660571401663659059349708627445067",
+ "-9829.261970591930907585958999196966814861251125275804",
+ "7806.858647077811827981774785577363365546600234846335",
+ "9319.700085649568180114405924685286453652118439999060",
+ "5319.898768025758256383579171601100187435481641933401",
+ "-2387.954826466841736373447020403170264502066930376059",
+ "-6958.298525165359760665355886221309296550746152109847",
+ "-3468.539106391972560670887295398968213297736424267559",
+ "130.4167253342709401698825285623058661085645012029873",
+ "3371.139930235175987370940343096776588915600470241960",
+ "1569.232678004908105313880673484968847566948896728142",
+ "750.0912101179065245750415609380442359608197763310413",
+ "-1462.257209626597452197736652121394535208578921869658",
+ "-1661.577809630240615684355192771059515041884351493459",
+ "1509.628528603869133250456671040505284128185908768108",
+ "383.8950902580816259502239917715884779698864996879279",
+ "1248.051096343638013308778159911906703363730187986273",
+ "17.18569564265260274901760034571610990094333217519021",
+ "-2038.024598002604853054532645991188063394308018947374",
+ "26118.98132017823514803387529120810044029492871875474",
+ "14943.61943482227903328457116850255971625430735856355",
+ "-6650.686262276131072415580833374348889422387492668440",
+ "-19519.81529547404067945704333355155941895199228108631",
+ "-6983.190236500848647457042860591724089812405118922223",
+ "1899.297502873688983038424995203515277346497811783168",
+ "8715.003652642963488202943622358986745434720576722170",
+ "2368.150690681864301926962120618658083737878227231428",
+ "136.8920793093482831910443246272238406481527839521448",
+ "-3954.732706163417141961077488373290331419627965482785",
+ "-2673.556440231186786375595871506657802723673830409989",
+ "5078.483935249043594670125721926702845818403229980691",
+ "1643.459143721204817182772630730123271413273760820347",
+ "2182.216979506380293664703833586468523416961563720645",
+ "-1345.838830963620501537777318021157952722412472356094",
+ "-4309.285350629108413525304135326225818270616857298235",
+ "-1488.050869922417817689426519211523527088509094291312",
+ "-228.0584943070343720919835603886532454450555855354340",
+ "2373.398940425709177876367020236623713151456855728138",
+ "773.8481328103928058186643458500631723389600248582833",
+ "12294.40387737855548614823173849184004455244840062464",
+ "16977.34966571858301862913845572077593071467784570724",
+ "17057.17475622503175013658695220988017704387344177727",
+ "8121.189758511830935868344768490586007624092305459885",
+ "-7458.443541406284389918808653948439156033975014107187",
+ "-8134.131160882738058651976911725365291142418949378248",
+ "-4912.881158613784419581465435995807691111897279859302",
+ "2030.653136098933717888434825960516061206391833398177",
+ "4407.490527709412730881592594976776779312299897714205",
+ "3392.434568825892752350943548729559313328141534290860",
+ "104.0372355841506198680609232049783930050635078746762",
+ "-3180.817620484463214391157460812371170723810181051096",
+ "-2460.523987075069437321629265332968914260047631079537",
+ "-938.2209314069133432825590545267820890922150850657831",
+ "1315.246905571876456706320919211807375254975062430487",
+ "1735.862392405992188189147617586418269768276241147998",
+ "1209.759657223166954850207025399731503326968841680649",
+ "-227.3320054566642297128407910803774238020746116287390",
+ "-1266.126209991929259396966729664100401813091860201682",
+ "-123.0794572338149156803989321165094334755661021559442",
+ "-19806.90794333834685506732819834090525250045748665845",
+ "-21314.81635440575229337844631555492486744407550254908",
+ "-12317.58384430130805020250005527399703840208659666608",
+ "6349.418659888281474363154227419204673663621492760982",
+ "9489.819687696527735093973063679592839666155440941289",
+ "6409.538948456309994399374417972222747225748405617373",
+ "-1550.281799013125267606263057621300789555474258987989",
+ "-8109.711199785217512061886243157800006692908759687186",
+ "-3957.840330296874877742767473517819198882831790006004",
+ "-404.0796555836667858753163727999380679499192203780272",
+ "3693.614351301181980145006883746936633676934626580499",
+ "2716.146658322790064799415509615557123789406209068981",
+ "1094.591086641398900496318896947912437274250932576747",
+ "-1456.269645549946420883827817869876763706452982413420",
+ "-2244.380608735636962338392373719455877272151458411079",
+ "1268.593891556261871090883000459505759446497182073132",
+ "265.2206730327749346649809229271069944357537135668622",
+ "1496.091578778639488439197917198148587432113387871024",
+ "354.6137351047722781932932090799444060236757625488818",
+ "-2508.477110048684129181005769771219369377836598443263",
+ "26517.86140875157324686379805134248778305979287686214",
+ "17922.98387741915144079932445041215068937644694653527",
+ "-4328.259142127668040873054918170572859673703425721293",
+ "-22704.70245940080949074466622805971940616027152354999",
+ "-8268.613747173738971390434576274225941735552759965376",
+ "740.4056074392611464740778308961471299437619012164253",
+ "9848.900182836035080973766381422758538530595451048714",
+ "5213.598341476210337710365441072904970861063876340963",
+ "801.2462923723508233330997243930793458484750729415321",
+ "-4241.870133920767845856621968904769727964770527614244",
+ "-4092.241355868550570635569815488217469506874233892269",
+ "5074.435909206083943809967780457349942315503368249477",
+ "1607.765329254820915989772546102530187884674235100928",
+ "2861.155651116567526208762405651011317435252198548496",
+ "-918.9310546317296090214320737728927500362088478158839",
+ "-5803.211323646092019259074499814222806376618363553826",
+ "-1767.541897994477314401145980308432268207111761980100",
+ "-663.0646207520075726320417301262932382663072876188661",
+ "2837.903194613938414496183429129769829434890424213252",
+ "1976.319600747797717779881875290418720908121189218755"}};
+
+int main() {
+ using float50 = boost::multiprecision::cpp_bin_float_50;
+ constexpr std::size_t Nw = 3; // Max order of derivative to calculate for w
+ constexpr std::size_t Nx = 2; // Max order of derivative to calculate for x
+ constexpr std::size_t Ny = 4; // Max order of derivative to calculate for y
+ constexpr std::size_t Nz = 3; // Max order of derivative to calculate for z
+ auto const variables = make_ftuple<float50, Nw, Nx, Ny, Nz>(11, 12, 13, 14);
+ auto const v = boost::mp11::tuple_apply(f{}, variables);
+ std::size_t ia = 0;
+ double max_relative_error = 0;
+ for (std::size_t iw = 0; iw <= Nw; ++iw)
+ for (std::size_t ix = 0; ix <= Nx; ++ix)
+ for (std::size_t iy = 0; iy <= Ny; ++iy)
+ for (std::size_t iz = 0; iz <= Nz; ++iz) {
+ float50 const value = v.derivative(iw, ix, iy, iz);
+ float50 const answer = boost::lexical_cast<float50>(answers[ia++]);
+ double const error = static_cast<double>(fabs(value / answer - 1));
+ max_relative_error = (std::max)(error, max_relative_error);
+ }
+ std::cout << "max_relative_error = " << std::setprecision(3) << max_relative_error << " out of " << ia
+ << " calculated values." << std::endl;
+ return 0;
+}
+/*
+Output:
+max_relative_error = 6.82e-13 out of 240 calculated values. (for double)
+max_relative_error = 3.36e-47 out of 240 calculated values. (for cpp_bin_float_50)
+**/
diff --git a/src/boost/libs/math/example/autodiff_multiprecision.cpp b/src/boost/libs/math/example/autodiff_multiprecision.cpp
new file mode 100644
index 000000000..81c7c27c5
--- /dev/null
+++ b/src/boost/libs/math/example/autodiff_multiprecision.cpp
@@ -0,0 +1,46 @@
+// Copyright Matthew Pulver 2018 - 2019.
+// Distributed under the Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt or copy at
+// https://www.boost.org/LICENSE_1_0.txt)
+
+#include <boost/math/differentiation/autodiff.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+#include <iostream>
+
+using namespace boost::math::differentiation;
+
+template <typename W, typename X, typename Y, typename Z>
+promote<W, X, Y, Z> f(const W& w, const X& x, const Y& y, const Z& z) {
+ using namespace std;
+ return exp(w * sin(x * log(y) / z) + sqrt(w * z / (x * y))) + w * w / tan(z);
+}
+
+int main() {
+ using float50 = boost::multiprecision::cpp_bin_float_50;
+
+ constexpr unsigned Nw = 3; // Max order of derivative to calculate for w
+ constexpr unsigned Nx = 2; // Max order of derivative to calculate for x
+ constexpr unsigned Ny = 4; // Max order of derivative to calculate for y
+ constexpr unsigned Nz = 3; // Max order of derivative to calculate for z
+ // Declare 4 independent variables together into a std::tuple.
+ auto const variables = make_ftuple<float50, Nw, Nx, Ny, Nz>(11, 12, 13, 14);
+ auto const& w = std::get<0>(variables); // Up to Nw derivatives at w=11
+ auto const& x = std::get<1>(variables); // Up to Nx derivatives at x=12
+ auto const& y = std::get<2>(variables); // Up to Ny derivatives at y=13
+ auto const& z = std::get<3>(variables); // Up to Nz derivatives at z=14
+ auto const v = f(w, x, y, z);
+ // Calculated from Mathematica symbolic differentiation.
+ float50 const answer("1976.319600747797717779881875290418720908121189218755");
+ std::cout << std::setprecision(std::numeric_limits<float50>::digits10)
+ << "mathematica : " << answer << '\n'
+ << "autodiff : " << v.derivative(Nw, Nx, Ny, Nz) << '\n'
+ << std::setprecision(3)
+ << "relative error: " << (v.derivative(Nw, Nx, Ny, Nz) / answer - 1) << '\n';
+ return 0;
+}
+/*
+Output:
+mathematica : 1976.3196007477977177798818752904187209081211892188
+autodiff : 1976.3196007477977177798818752904187209081211892188
+relative error: 2.67e-50
+**/
diff --git a/src/boost/libs/math/example/barycentric_interpolation_example.cpp b/src/boost/libs/math/example/barycentric_interpolation_example.cpp
new file mode 100644
index 000000000..263e20f19
--- /dev/null
+++ b/src/boost/libs/math/example/barycentric_interpolation_example.cpp
@@ -0,0 +1,92 @@
+
+// Copyright Nick Thompson, 2017
+
+// 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).
+
+#include <iostream>
+#include <limits>
+#include <vector>
+
+//[barycentric_rational_example
+
+/*`
+This example shows how to use barycentric rational interpolation, using Walter Kohn's classic paper
+"Solution of the Schrodinger Equation in Periodic Lattices with an Application to Metallic Lithium"
+In this paper, Kohn needs to repeatedly solve an ODE (the radial Schrodinger equation) given a potential
+which is only known at non-equally samples data.
+
+If he'd only had the barycentric rational interpolant of Boost.Math!
+
+References: Kohn, W., and N. Rostoker. "Solution of the Schrodinger equation in periodic lattices with an application to metallic lithium." Physical Review 94.5 (1954): 1111.
+*/
+
+#include <boost/math/interpolators/barycentric_rational.hpp>
+
+int main()
+{
+ // The lithium potential is given in Kohn's paper, Table I:
+ std::vector<double> r(45);
+ std::vector<double> mrV(45);
+
+ // We'll skip the code for filling the above vectors with data for now...
+ //<-
+
+ r[0] = 0.02; mrV[0] = 5.727;
+ r[1] = 0.04, mrV[1] = 5.544;
+ r[2] = 0.06, mrV[2] = 5.450;
+ r[3] = 0.08, mrV[3] = 5.351;
+ r[4] = 0.10, mrV[4] = 5.253;
+ r[5] = 0.12, mrV[5] = 5.157;
+ r[6] = 0.14, mrV[6] = 5.058;
+ r[7] = 0.16, mrV[7] = 4.960;
+ r[8] = 0.18, mrV[8] = 4.862;
+ r[9] = 0.20, mrV[9] = 4.762;
+ r[10] = 0.24, mrV[10] = 4.563;
+ r[11] = 0.28, mrV[11] = 4.360;
+ r[12] = 0.32, mrV[12] = 4.1584;
+ r[13] = 0.36, mrV[13] = 3.9463;
+ r[14] = 0.40, mrV[14] = 3.7360;
+ r[15] = 0.44, mrV[15] = 3.5429;
+ r[16] = 0.48, mrV[16] = 3.3797;
+ r[17] = 0.52, mrV[17] = 3.2417;
+ r[18] = 0.56, mrV[18] = 3.1209;
+ r[19] = 0.60, mrV[19] = 3.0138;
+ r[20] = 0.68, mrV[20] = 2.8342;
+ r[21] = 0.76, mrV[21] = 2.6881;
+ r[22] = 0.84, mrV[22] = 2.5662;
+ r[23] = 0.92, mrV[23] = 2.4242;
+ r[24] = 1.00, mrV[24] = 2.3766;
+ r[25] = 1.08, mrV[25] = 2.3058;
+ r[26] = 1.16, mrV[26] = 2.2458;
+ r[27] = 1.24, mrV[27] = 2.2035;
+ r[28] = 1.32, mrV[28] = 2.1661;
+ r[29] = 1.40, mrV[29] = 2.1350;
+ r[30] = 1.48, mrV[30] = 2.1090;
+ r[31] = 1.64, mrV[31] = 2.0697;
+ r[32] = 1.80, mrV[32] = 2.0466;
+ r[33] = 1.96, mrV[33] = 2.0325;
+ r[34] = 2.12, mrV[34] = 2.0288;
+ r[35] = 2.28, mrV[35] = 2.0292;
+ r[36] = 2.44, mrV[36] = 2.0228;
+ r[37] = 2.60, mrV[37] = 2.0124;
+ r[38] = 2.76, mrV[38] = 2.0065;
+ r[39] = 2.92, mrV[39] = 2.0031;
+ r[40] = 3.08, mrV[40] = 2.0015;
+ r[41] = 3.24, mrV[41] = 2.0008;
+ r[42] = 3.40, mrV[42] = 2.0004;
+ r[43] = 3.56, mrV[43] = 2.0002;
+ r[44] = 3.72, mrV[44] = 2.0001;
+ //->
+
+ // Now we want to interpolate this potential at any r:
+ boost::math::barycentric_rational<double> b(r.data(), mrV.data(), r.size());
+
+ for (size_t i = 1; i < 8; ++i)
+ {
+ double r = i*0.5;
+ std::cout << "(r, V) = (" << r << ", " << -b(r)/r << ")\n";
+ }
+}
+//] [/barycentric_rational_example]
diff --git a/src/boost/libs/math/example/barycentric_interpolation_example_2.cpp b/src/boost/libs/math/example/barycentric_interpolation_example_2.cpp
new file mode 100644
index 000000000..4128f95ba
--- /dev/null
+++ b/src/boost/libs/math/example/barycentric_interpolation_example_2.cpp
@@ -0,0 +1,108 @@
+
+// Copyright Nick Thompson, 2017
+
+// 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).
+
+#include <iostream>
+#include <limits>
+#include <map>
+
+//[barycentric_rational_example2
+
+/*`This further example shows how to use the iterator based constructor, and then uses the
+function object in our root finding algorithms to locate the points where the potential
+achieves a specific value.
+*/
+
+#include <boost/math/interpolators/barycentric_rational.hpp>
+#include <boost/range/adaptors.hpp>
+#include <boost/math/tools/roots.hpp>
+
+int main()
+{
+ // The lithium potential is given in Kohn's paper, Table I.
+ // (We could equally easily use an unordered_map, a list of tuples or pairs, or a 2-dimensional array).
+ std::map<double, double> r;
+
+ r[0.02] = 5.727;
+ r[0.04] = 5.544;
+ r[0.06] = 5.450;
+ r[0.08] = 5.351;
+ r[0.10] = 5.253;
+ r[0.12] = 5.157;
+ r[0.14] = 5.058;
+ r[0.16] = 4.960;
+ r[0.18] = 4.862;
+ r[0.20] = 4.762;
+ r[0.24] = 4.563;
+ r[0.28] = 4.360;
+ r[0.32] = 4.1584;
+ r[0.36] = 3.9463;
+ r[0.40] = 3.7360;
+ r[0.44] = 3.5429;
+ r[0.48] = 3.3797;
+ r[0.52] = 3.2417;
+ r[0.56] = 3.1209;
+ r[0.60] = 3.0138;
+ r[0.68] = 2.8342;
+ r[0.76] = 2.6881;
+ r[0.84] = 2.5662;
+ r[0.92] = 2.4242;
+ r[1.00] = 2.3766;
+ r[1.08] = 2.3058;
+ r[1.16] = 2.2458;
+ r[1.24] = 2.2035;
+ r[1.32] = 2.1661;
+ r[1.40] = 2.1350;
+ r[1.48] = 2.1090;
+ r[1.64] = 2.0697;
+ r[1.80] = 2.0466;
+ r[1.96] = 2.0325;
+ r[2.12] = 2.0288;
+ r[2.28] = 2.0292;
+ r[2.44] = 2.0228;
+ r[2.60] = 2.0124;
+ r[2.76] = 2.0065;
+ r[2.92] = 2.0031;
+ r[3.08] = 2.0015;
+ r[3.24] = 2.0008;
+ r[3.40] = 2.0004;
+ r[3.56] = 2.0002;
+ r[3.72] = 2.0001;
+
+ // Let's discover the absissa that will generate a potential of exactly 3.0,
+ // start by creating 2 ranges for the x and y values:
+ auto x_range = boost::adaptors::keys(r);
+ auto y_range = boost::adaptors::values(r);
+ boost::math::barycentric_rational<double> b(x_range.begin(), x_range.end(), y_range.begin());
+ //
+ // We'll use a lambda expression to provide the functor to our root finder, since we want
+ // the abscissa value that yields 3, not zero. We pass the functor b by value to the
+ // lambda expression since barycentric_rational is trivial to copy.
+ // Here we're using simple bisection to find the root:
+ boost::uintmax_t iterations = (std::numeric_limits<boost::uintmax_t>::max)();
+ double abscissa_3 = boost::math::tools::bisect([=](double x) { return b(x) - 3; }, 0.44, 1.24, boost::math::tools::eps_tolerance<double>(), iterations).first;
+ std::cout << "Abscissa value that yields a potential of 3 = " << abscissa_3 << std::endl;
+ std::cout << "Root was found in " << iterations << " iterations." << std::endl;
+ //
+ // However, we have a more efficient root finding algorithm than simple bisection:
+ iterations = (std::numeric_limits<boost::uintmax_t>::max)();
+ abscissa_3 = boost::math::tools::bracket_and_solve_root([=](double x) { return b(x) - 3; }, 0.6, 1.2, false, boost::math::tools::eps_tolerance<double>(), iterations).first;
+ std::cout << "Abscissa value that yields a potential of 3 = " << abscissa_3 << std::endl;
+ std::cout << "Root was found in " << iterations << " iterations." << std::endl;
+}
+//] [/barycentric_rational_example2]
+
+
+//[barycentric_rational_example2_out
+/*` Program output is:
+[pre
+Abscissa value that yields a potential of 3 = 0.604728
+Root was found in 54 iterations.
+Abscissa value that yields a potential of 3 = 0.604728
+Root was found in 10 iterations.
+]
+*/
+//]
diff --git a/src/boost/libs/math/example/bernoulli_example.cpp b/src/boost/libs/math/example/bernoulli_example.cpp
new file mode 100644
index 000000000..5a2c58969
--- /dev/null
+++ b/src/boost/libs/math/example/bernoulli_example.cpp
@@ -0,0 +1,207 @@
+// Copyright Paul A. Bristow 2013.
+// Copyright Nakhar Agrawal 2013.
+// Copyright John Maddock 2013.
+// Copyright Christopher Kormanyos 2013.
+
+// 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)
+
+#pragma warning (disable : 4100) // unreferenced formal parameter.
+#pragma warning (disable : 4127) // conditional expression is constant.
+
+//#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
+
+#include <boost/multiprecision/cpp_dec_float.hpp>
+#include <boost/math/special_functions/bernoulli.hpp>
+
+#include <iostream>
+
+/* First 50 from 2 to 100 inclusive: */
+/* TABLE[N[BernoulliB[n], 200], {n,2,100,2}] */
+
+//SC_(0.1666666666666666666666666666666666666666),
+//SC_(-0.0333333333333333333333333333333333333333),
+//SC_(0.0238095238095238095238095238095238095238),
+//SC_(-0.0333333333333333333333333333333333333333),
+//SC_(0.0757575757575757575757575757575757575757),
+//SC_(-0.2531135531135531135531135531135531135531),
+//SC_(1.1666666666666666666666666666666666666666),
+//SC_(-7.0921568627450980392156862745098039215686),
+//SC_(54.9711779448621553884711779448621553884711),
+
+int main()
+{
+ //[bernoulli_example_1
+
+/*`A simple example computes the value of B[sub 4] where the return type is `double`,
+note that the argument to bernoulli_b2n is ['2] not ['4] since it computes B[sub 2N].
+
+
+*/
+ try
+ { // It is always wise to use try'n'catch blocks around Boost.Math functions
+ // so that any informative error messages can be displayed in the catch block.
+ std::cout
+ << std::setprecision(std::numeric_limits<double>::digits10)
+ << boost::math::bernoulli_b2n<double>(2) << std::endl;
+
+/*`So B[sub 4] == -1/30 == -0.0333333333333333
+
+If we use Boost.Multiprecision and its 50 decimal digit floating-point type `cpp_dec_float_50`,
+we can calculate the value of much larger numbers like B[sub 200]
+and also obtain much higher precision.
+*/
+
+ std::cout
+ << std::setprecision(std::numeric_limits<boost::multiprecision::cpp_dec_float_50>::digits10)
+ << boost::math::bernoulli_b2n<boost::multiprecision::cpp_dec_float_50>(100) << std::endl;
+
+//] //[/bernoulli_example_1]
+
+//[bernoulli_example_2
+/*`We can compute and save all the float-precision Bernoulli numbers from one call.
+*/
+ std::vector<float> bn; // Space for 32-bit `float` precision Bernoulli numbers.
+
+ // Start with Bernoulli number 0.
+ boost::math::bernoulli_b2n<float>(0, 32, std::back_inserter(bn)); // Fill vector with even Bernoulli numbers.
+
+ for(size_t i = 0; i < bn.size(); i++)
+ { // Show vector of even Bernoulli numbers, showing all significant decimal digits.
+ std::cout << std::setprecision(std::numeric_limits<float>::digits10)
+ << i*2 << ' '
+ << bn[i]
+ << std::endl;
+ }
+//] //[/bernoulli_example_2]
+
+ }
+ catch(const std::exception& ex)
+ {
+ std::cout << "Thrown Exception caught: " << ex.what() << std::endl;
+ }
+
+
+//[bernoulli_example_3
+/*`Of course, for any floating-point type, there is a maximum Bernoulli number that can be computed
+ before it overflows the exponent.
+ By default policy, if we try to compute too high a Bernoulli number, an exception will be thrown.
+*/
+ try
+ {
+ std::cout
+ << std::setprecision(std::numeric_limits<float>::digits10)
+ << "Bernoulli number " << 33 * 2 <<std::endl;
+
+ std::cout << boost::math::bernoulli_b2n<float>(33) << std::endl;
+ }
+ catch (std::exception ex)
+ {
+ std::cout << "Thrown Exception caught: " << ex.what() << std::endl;
+ }
+
+/*`
+and we will get a helpful error message (provided try'n'catch blocks are used).
+*/
+
+//] //[/bernoulli_example_3]
+
+//[bernoulli_example_4
+/*For example:
+*/
+ std::cout << "boost::math::max_bernoulli_b2n<float>::value = " << boost::math::max_bernoulli_b2n<float>::value << std::endl;
+ std::cout << "Maximum Bernoulli number using float is " << boost::math::bernoulli_b2n<float>( boost::math::max_bernoulli_b2n<float>::value) << std::endl;
+ std::cout << "boost::math::max_bernoulli_b2n<double>::value = " << boost::math::max_bernoulli_b2n<double>::value << std::endl;
+ std::cout << "Maximum Bernoulli number using double is " << boost::math::bernoulli_b2n<double>( boost::math::max_bernoulli_b2n<double>::value) << std::endl;
+ //] //[/bernoulli_example_4]
+
+//[tangent_example_1
+
+/*`We can compute and save a few Tangent numbers.
+*/
+ std::vector<float> tn; // Space for some `float` precision Tangent numbers.
+
+ // Start with Bernoulli number 0.
+ boost::math::tangent_t2n<float>(1, 6, std::back_inserter(tn)); // Fill vector with even Tangent numbers.
+
+ for(size_t i = 0; i < tn.size(); i++)
+ { // Show vector of even Tangent numbers, showing all significant decimal digits.
+ std::cout << std::setprecision(std::numeric_limits<float>::digits10)
+ << " "
+ << tn[i];
+ }
+ std::cout << std::endl;
+
+//] [/tangent_example_1]
+
+// 1, 2, 16, 272, 7936, 353792, 22368256, 1903757312
+
+
+
+} // int main()
+
+/*
+
+//[bernoulli_output_1
+ -3.6470772645191354362138308865549944904868234686191e+215
+//] //[/bernoulli_output_1]
+
+//[bernoulli_output_2
+
+ 0 1
+ 2 0.166667
+ 4 -0.0333333
+ 6 0.0238095
+ 8 -0.0333333
+ 10 0.0757576
+ 12 -0.253114
+ 14 1.16667
+ 16 -7.09216
+ 18 54.9712
+ 20 -529.124
+ 22 6192.12
+ 24 -86580.3
+ 26 1.42552e+006
+ 28 -2.72982e+007
+ 30 6.01581e+008
+ 32 -1.51163e+010
+ 34 4.29615e+011
+ 36 -1.37117e+013
+ 38 4.88332e+014
+ 40 -1.92966e+016
+ 42 8.41693e+017
+ 44 -4.03381e+019
+ 46 2.11507e+021
+ 48 -1.20866e+023
+ 50 7.50087e+024
+ 52 -5.03878e+026
+ 54 3.65288e+028
+ 56 -2.84988e+030
+ 58 2.38654e+032
+ 60 -2.14e+034
+ 62 2.0501e+036
+//] //[/bernoulli_output_2]
+
+//[bernoulli_output_3
+ Bernoulli number 66
+ Thrown Exception caught: Error in function boost::math::bernoulli_b2n<float>(n):
+ Overflow evaluating function at 33
+//] //[/bernoulli_output_3]
+//[bernoulli_output_4
+ boost::math::max_bernoulli_b2n<float>::value = 32
+ Maximum Bernoulli number using float is -2.0938e+038
+ boost::math::max_bernoulli_b2n<double>::value = 129
+ Maximum Bernoulli number using double is 1.33528e+306
+//] //[/bernoulli_output_4]
+
+
+//[tangent_output_1
+ 1 2 16 272 7936 353792
+//] [/tangent_output_1]
+
+
+
+*/
+
+
diff --git a/src/boost/libs/math/example/bessel_errors_example.cpp b/src/boost/libs/math/example/bessel_errors_example.cpp
new file mode 100644
index 000000000..1b7729269
--- /dev/null
+++ b/src/boost/libs/math/example/bessel_errors_example.cpp
@@ -0,0 +1,171 @@
+// Copyright Christopher Kormanyos 2013.
+// Copyright Paul A. Bristow 2013.
+// Copyright John Maddock 2013.
+
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated.
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <exception>
+
+// Weisstein, Eric W. "Bessel Function Zeros." From MathWorld--A Wolfram Web Resource.
+// http://mathworld.wolfram.com/BesselFunctionZeros.html
+// Test values can be calculated using [@wolframalpha.com WolframAplha]
+// See also http://dlmf.nist.gov/10.21
+
+//[bessel_errors_example_1
+
+/*`[h5 Error messages from 'bad' input]
+
+Another example demonstrates calculating zeros of the Bessel functions
+showing the error messages from 'bad' input is handled by throwing exceptions.
+
+To use the functions for finding zeros of the functions we need:
+*/
+ #include <boost/math/special_functions/bessel.hpp>
+ #include <boost/math/special_functions/airy.hpp>
+
+//] [/bessel_errors_example_1]
+
+int main()
+{
+//[bessel_errors_example_2
+
+/*`[tip It is always wise to place all code using Boost.Math inside try'n'catch blocks;
+this will ensure that helpful error messages can be shown when exceptional conditions arise.]
+
+Examples below show messages from several 'bad' arguments that throw a `domain_error` exception.
+*/
+ try
+ { // Try a zero order v.
+ float dodgy_root = boost::math::cyl_bessel_j_zero(0.F, 0);
+ std::cout << "boost::math::cyl_bessel_j_zero(0.F, 0) " << dodgy_root << std::endl;
+ // Thrown exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int):
+ // Requested the 0'th zero of J0, but the rank must be > 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+/*`[note The type shown in the error message is the type [*after promotion],
+using __precision_policy and __promotion_policy, from `float` to `double` in this case.]
+
+In this example the promotion goes:
+
+# Arguments are `float` and `int`.
+# Treat `int` "as if" it were a `double`, so arguments are `float` and `double`.
+# Common type is `double` - so that's the precision we want (and the type that will be returned).
+# Evaluate internally as `double` for full `float` precision.
+
+See full code for other examples that promote from `double` to `long double`.
+
+Other examples of 'bad' inputs like infinity and NaN are below.
+Some compiler warnings indicate that 'bad' values are detected at compile time.
+*/
+
+ try
+ { // order v = inf
+ std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << std::endl;
+ double inf = std::numeric_limits<double>::infinity();
+ double inf_root = boost::math::cyl_bessel_j_zero(inf, 1);
+ std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << inf_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, unsigned):
+ // Order argument is 1.#INF, but must be finite >= 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // order v = NaN, rank m = 1
+ std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << std::endl;
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ double nan_root = boost::math::cyl_bessel_j_zero(nan, 1);
+ std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << nan_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, unsigned):
+ // Order argument is 1.#QNAN, but must be finite >= 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+/*`The output from other examples are shown appended to the full code listing.
+*/
+//] [/bessel_errors_example_2]
+ try
+ { // Try a zero rank m.
+ std::cout << "boost::math::cyl_neumann_zero(0.0, 0) " << std::endl;
+ double dodgy_root = boost::math::cyl_bessel_j_zero(0.0, 0);
+ // warning C4146: unary minus operator applied to unsigned type, result still unsigned.
+ std::cout << "boost::math::cyl_neumann_zero(0.0, -1) " << dodgy_root << std::endl;
+ // boost::math::cyl_neumann_zero(0.0, -1) 6.74652e+009
+ // This *should* fail because m is unreasonably large.
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // m = inf
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, inf) " << std::endl;
+ double inf = std::numeric_limits<double>::infinity();
+ double inf_root = boost::math::cyl_bessel_j_zero(0.0, inf);
+ // warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data.
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, inf) " << inf_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int):
+ // Requested the 0'th zero, but must be > 0 !
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // m = NaN
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ double nan_root = boost::math::airy_ai_zero<double>(nan);
+ // warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data.
+ std::cout << "boost::math::airy_ai_zero<double>(nan) " << nan_root << std::endl;
+ // Thrown exception Error in function boost::math::airy_ai_zero<double>(double,double):
+ // The requested rank of the zero is 0, but must be 1 or more !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+ } // int main()
+
+/*
+Output:
+
+ Description: Autorun "J:\Cpp\big_number\Debug\bessel_errors_example.exe"
+ Thrown exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int): Requested the 0'th zero of J0, but the rank must be > 0 !
+ boost::math::cyl_bessel_j_zero(inf, 1)
+ Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Order argument is 1.#INF, but must be finite >= 0 !
+ boost::math::cyl_bessel_j_zero(nan, 1)
+ Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Order argument is 1.#QNAN, but must be finite >= 0 !
+ boost::math::cyl_neumann_zero(0.0, 0)
+ Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the 0'th zero of J0, but the rank must be > 0 !
+ boost::math::cyl_bessel_j_zero(0.0, inf)
+ Thrown exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the -2147483648'th zero, but the rank must be positive !
+ Thrown exception Error in function boost::math::airy_ai_zero<double>(double,double): The requested rank of the zero is 0, but must be 1 or more !
+
+
+*/
+
diff --git a/src/boost/libs/math/example/bessel_zeros_example.cpp b/src/boost/libs/math/example/bessel_zeros_example.cpp
new file mode 100644
index 000000000..0d3ec3ccc
--- /dev/null
+++ b/src/boost/libs/math/example/bessel_zeros_example.cpp
@@ -0,0 +1,447 @@
+// Copyright Christopher Kormanyos 2013.
+// Copyright Paul A. Bristow 2013.
+// Copyright John Maddock 2013.
+
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated.
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+
+// Weisstein, Eric W. "Bessel Function Zeros." From MathWorld--A Wolfram Web Resource.
+// http://mathworld.wolfram.com/BesselFunctionZeros.html
+// Test values can be calculated using [@wolframalpha.com WolframAplha]
+// See also http://dlmf.nist.gov/10.21
+
+//[bessel_zero_example_1
+
+/*`This example demonstrates calculating zeros of the Bessel, Neumann and Airy functions.
+It also shows how Boost.Math and Boost.Multiprecision can be combined to provide
+a many decimal digit precision. For 50 decimal digit precision we need to include
+*/
+
+ #include <boost/multiprecision/cpp_dec_float.hpp>
+
+/*`and a `typedef` for `float_type` may be convenient
+(allowing a quick switch to re-compute at built-in `double` or other precision)
+*/
+ typedef boost::multiprecision::cpp_dec_float_50 float_type;
+
+//`To use the functions for finding zeros of the functions we need
+
+ #include <boost/math/special_functions/bessel.hpp>
+
+//`This file includes the forward declaration signatures for the zero-finding functions:
+
+// #include <boost/math/special_functions/math_fwd.hpp>
+
+/*`but more details are in the full documentation, for example at
+[@http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/bessel/bessel_over.html Boost.Math Bessel functions]
+*/
+
+/*`This example shows obtaining both a single zero of the Bessel function,
+and then placing multiple zeros into a container like `std::vector` by providing an iterator.
+The signature of the single value function is:
+
+ template <class T>
+ inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type
+ cyl_bessel_j_zero(T v, // Floating-point value for Jv.
+ int m); // start index.
+
+The result type is controlled by the floating-point type of parameter `v`
+(but subject to the usual __precision_policy and __promotion_policy).
+
+The signature of multiple zeros function is:
+
+ template <class T, class OutputIterator>
+ inline OutputIterator cyl_bessel_j_zero(T v, // Floating-point value for Jv.
+ int start_index, // 1-based start index.
+ unsigned number_of_zeros,
+ OutputIterator out_it); // iterator into container for zeros.
+
+There is also a version which allows control of the __policy_section for error handling and precision.
+
+ template <class T, class OutputIterator, class Policy>
+ inline OutputIterator cyl_bessel_j_zero(T v, // Floating-point value for Jv.
+ int start_index, // 1-based start index.
+ unsigned number_of_zeros,
+ OutputIterator out_it,
+ const Policy& pol); // iterator into container for zeros.
+
+*/
+//] [/bessel_zero_example_1]
+
+//[bessel_zero_example_iterator_1]
+/*`We use the `cyl_bessel_j_zero` output iterator parameter `out_it`
+to create a sum of 1/zeros[super 2] by defining a custom output iterator:
+*/
+
+template <class T>
+struct output_summation_iterator
+{
+ output_summation_iterator(T* p) : p_sum(p)
+ {}
+ output_summation_iterator& operator*()
+ { return *this; }
+ output_summation_iterator& operator++()
+ { return *this; }
+ output_summation_iterator& operator++(int)
+ { return *this; }
+ output_summation_iterator& operator = (T const& val)
+ {
+ *p_sum += 1./ (val * val); // Summing 1/zero^2.
+ return *this;
+ }
+private:
+ T* p_sum;
+};
+
+
+//] [/bessel_zero_example_iterator_1]
+
+int main()
+{
+ try
+ {
+//[bessel_zero_example_2]
+
+/*`[tip It is always wise to place code using Boost.Math inside try'n'catch blocks;
+this will ensure that helpful error messages can be shown when exceptional conditions arise.]
+
+First, evaluate a single Bessel zero.
+
+The precision is controlled by the float-point type of template parameter `T` of `v`
+so this example has `double` precision, at least 15 but up to 17 decimal digits (for the common 64-bit double).
+*/
+ double root = boost::math::cyl_bessel_j_zero(0.0, 1);
+ // Displaying with default precision of 6 decimal digits:
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, 1) " << root << std::endl; // 2.40483
+ // And with all the guaranteed (15) digits:
+ std::cout.precision(std::numeric_limits<double>::digits10);
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, 1) " << root << std::endl; // 2.40482555769577
+/*`But note that because the parameter `v` controls the precision of the result,
+`v` [*must be a floating-point type].
+So if you provide an integer type, say 0, rather than 0.0, then it will fail to compile thus:
+``
+ root = boost::math::cyl_bessel_j_zero(0, 1);
+``
+with this error message
+``
+ error C2338: Order must be a floating-point type.
+``
+
+Optionally, we can use a policy to ignore errors, C-style, returning some value
+perhaps infinity or NaN, or the best that can be done. (See __user_error_handling).
+
+To create a (possibly unwise!) policy that ignores all errors:
+*/
+
+ typedef boost::math::policies::policy
+ <
+ boost::math::policies::domain_error<boost::math::policies::ignore_error>,
+ boost::math::policies::overflow_error<boost::math::policies::ignore_error>,
+ boost::math::policies::underflow_error<boost::math::policies::ignore_error>,
+ boost::math::policies::denorm_error<boost::math::policies::ignore_error>,
+ boost::math::policies::pole_error<boost::math::policies::ignore_error>,
+ boost::math::policies::evaluation_error<boost::math::policies::ignore_error>
+ > ignore_all_policy;
+
+ double inf = std::numeric_limits<double>::infinity();
+ double nan = std::numeric_limits<double>::quiet_NaN();
+
+ std::cout << "boost::math::cyl_bessel_j_zero(-1.0, 0) " << std::endl;
+ double dodgy_root = boost::math::cyl_bessel_j_zero(-1.0, 0, ignore_all_policy());
+ std::cout << "boost::math::cyl_bessel_j_zero(-1.0, 1) " << dodgy_root << std::endl; // 1.#QNAN
+ double inf_root = boost::math::cyl_bessel_j_zero(inf, 1, ignore_all_policy());
+ std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << inf_root << std::endl; // 1.#QNAN
+ double nan_root = boost::math::cyl_bessel_j_zero(nan, 1, ignore_all_policy());
+ std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << nan_root << std::endl; // 1.#QNAN
+
+/*`Another version of `cyl_bessel_j_zero` allows calculation of multiple zeros with one call,
+placing the results in a container, often `std::vector`.
+For example, generate five `double` roots of J[sub v] for integral order 2.
+
+showing the same results as column J[sub 2](x) in table 1 of
+[@ http://mathworld.wolfram.com/BesselFunctionZeros.html Wolfram Bessel Function Zeros].
+
+*/
+ unsigned int n_roots = 5U;
+ std::vector<double> roots;
+ boost::math::cyl_bessel_j_zero(2.0, 1, n_roots, std::back_inserter(roots));
+ std::copy(roots.begin(),
+ roots.end(),
+ std::ostream_iterator<double>(std::cout, "\n"));
+
+/*`Or generate 50 decimal digit roots of J[sub v] for non-integral order `v = 71/19`.
+
+We set the precision of the output stream and show trailing zeros to display a fixed 50 decimal digits.
+*/
+ std::cout.precision(std::numeric_limits<float_type>::digits10); // 50 decimal digits.
+ std::cout << std::showpoint << std::endl; // Show trailing zeros.
+
+ float_type x = float_type(71) / 19;
+ float_type r = boost::math::cyl_bessel_j_zero(x, 1); // 1st root.
+ std::cout << "x = " << x << ", r = " << r << std::endl;
+
+ r = boost::math::cyl_bessel_j_zero(x, 20U); // 20th root.
+ std::cout << "x = " << x << ", r = " << r << std::endl;
+
+ std::vector<float_type> zeros;
+ boost::math::cyl_bessel_j_zero(x, 1, 3, std::back_inserter(zeros));
+
+ std::cout << "cyl_bessel_j_zeros" << std::endl;
+ // Print the roots to the output stream.
+ std::copy(zeros.begin(), zeros.end(),
+ std::ostream_iterator<float_type>(std::cout, "\n"));
+
+/*`The Neumann function zeros are evaluated very similarly:
+*/
+ using boost::math::cyl_neumann_zero;
+
+ double zn = cyl_neumann_zero(2., 1);
+
+ std::cout << "cyl_neumann_zero(2., 1) = " << std::endl;
+ //double zn0 = zn;
+ // std::cout << "zn0 = " << std::endl;
+ // std::cout << zn0 << std::endl;
+ //
+ std::cout << zn << std::endl;
+ // std::cout << cyl_neumann_zero(2., 1) << std::endl;
+
+ std::vector<float> nzeros(3); // Space for 3 zeros.
+ cyl_neumann_zero<float>(2.F, 1, nzeros.size(), nzeros.begin());
+
+ std::cout << "cyl_neumann_zero<float>(2.F, 1, " << std::endl;
+ // Print the zeros to the output stream.
+ std::copy(nzeros.begin(), nzeros.end(),
+ std::ostream_iterator<float>(std::cout, "\n"));
+
+ std::cout << cyl_neumann_zero(static_cast<float_type>(220)/100, 1) << std::endl;
+ // 3.6154383428745996706772556069431792744372398748422
+
+/*`Finally we show how the output iterator can be used to compute a sum of zeros.
+
+(See [@https://doi.org/10.1017/S2040618500034067 Ian N. Sneddon, Infinite Sums of Bessel Zeros],
+page 150 equation 40).
+*/
+//] [/bessel_zero_example_2]
+
+ {
+//[bessel_zero_example_iterator_2]
+/*`The sum is calculated for many values, converging on the analytical exact value of `1/8`.
+*/
+ using boost::math::cyl_bessel_j_zero;
+ double nu = 1.;
+ double sum = 0;
+ output_summation_iterator<double> it(&sum); // sum of 1/zeros^2
+ cyl_bessel_j_zero(nu, 1, 10000, it);
+
+ double s = 1/(4 * (nu + 1)); // 0.125 = 1/8 is exact analytical solution.
+ std::cout << std::setprecision(6) << "nu = " << nu << ", sum = " << sum
+ << ", exact = " << s << std::endl;
+ // nu = 1.00000, sum = 0.124990, exact = 0.125000
+//] [/bessel_zero_example_iterator_2]
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+//[bessel_zero_example_iterator_3]
+
+/*`Examples below show effect of 'bad' arguments that throw a `domain_error` exception.
+*/
+ try
+ { // Try a negative rank m.
+ std::cout << "boost::math::cyl_bessel_j_zero(-1.F, -1) " << std::endl;
+ float dodgy_root = boost::math::cyl_bessel_j_zero(-1.F, -1);
+ std::cout << "boost::math::cyl_bessel_j_zero(-1.F, -1) " << dodgy_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int):
+ // Order argument is -1, but must be >= 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Throw exception " << ex.what() << std::endl;
+ }
+
+/*`[note The type shown is the type [*after promotion],
+using __precision_policy and __promotion_policy, from `float` to `double` in this case.]
+
+In this example the promotion goes:
+
+# Arguments are `float` and `int`.
+# Treat `int` "as if" it were a `double`, so arguments are `float` and `double`.
+# Common type is `double` - so that's the precision we want (and the type that will be returned).
+# Evaluate internally as `long double` for full `double` precision.
+
+See full code for other examples that promote from `double` to `long double`.
+
+*/
+
+//] [/bessel_zero_example_iterator_3]
+ try
+ { // order v = inf
+ std::cout << "boost::math::cyl_bessel_j_zero(infF, 1) " << std::endl;
+ float infF = std::numeric_limits<float>::infinity();
+ float inf_root = boost::math::cyl_bessel_j_zero(infF, 1);
+ std::cout << "boost::math::cyl_bessel_j_zero(infF, 1) " << inf_root << std::endl;
+ // boost::math::cyl_bessel_j_zero(-1.F, -1)
+ //Thrown exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int):
+ // Requested the -1'th zero, but the rank must be positive !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+ try
+ { // order v = inf
+ double inf = std::numeric_limits<double>::infinity();
+ double inf_root = boost::math::cyl_bessel_j_zero(inf, 1);
+ std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << inf_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, unsigned):
+ // Order argument is 1.#INF, but must be finite >= 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // order v = NaN
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ double nan_root = boost::math::cyl_bessel_j_zero(nan, 1);
+ std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << nan_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, unsigned):
+ // Order argument is 1.#QNAN, but must be finite >= 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // Try a negative m.
+ double dodgy_root = boost::math::cyl_bessel_j_zero(0.0, -1);
+ // warning C4146: unary minus operator applied to unsigned type, result still unsigned.
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, -1) " << dodgy_root << std::endl;
+ // boost::math::cyl_bessel_j_zero(0.0, -1) 6.74652e+009
+ // This *should* fail because m is unreasonably large.
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // m = inf
+ double inf = std::numeric_limits<double>::infinity();
+ double inf_root = boost::math::cyl_bessel_j_zero(0.0, inf);
+ // warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data.
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, inf) " << inf_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int):
+ // Requested the 0'th zero, but must be > 0 !
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ try
+ { // m = NaN
+ std::cout << "boost::math::cyl_bessel_j_zero(0.0, nan) " << std::endl ;
+ double nan = std::numeric_limits<double>::quiet_NaN();
+ double nan_root = boost::math::cyl_bessel_j_zero(0.0, nan);
+ // warning C4244: 'argument' : conversion from 'double' to 'int', possible loss of data.
+ std::cout << nan_root << std::endl;
+ // Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int):
+ // Requested the 0'th zero, but must be > 0 !
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ } // int main()
+
+/*
+Mathematica: Table[N[BesselJZero[71/19, n], 50], {n, 1, 20, 1}]
+
+7.2731751938316489503185694262290765588963196701623
+10.724858308883141732536172745851416647110749599085
+14.018504599452388106120459558042660282427471931581
+17.25249845917041718216248716654977734919590383861
+20.456678874044517595180234083894285885460502077814
+23.64363089714234522494551422714731959985405172504
+26.819671140255087745421311470965019261522390519297
+29.988343117423674742679141796661432043878868194142
+33.151796897690520871250862469973445265444791966114
+36.3114160002162074157243540350393860813165201842
+39.468132467505236587945197808083337887765967032029
+42.622597801391236474855034831297954018844433480227
+45.775281464536847753390206207806726581495950012439
+48.926530489173566198367766817478553992471739894799
+52.076607045343002794279746041878924876873478063472
+55.225712944912571393594224327817265689059002890192
+58.374006101538886436775188150439025201735151418932
+61.521611873000965273726742659353136266390944103571
+64.66863105379093036834648221487366079456596628716
+67.815145619696290925556791375555951165111460585458
+
+Mathematica: Table[N[BesselKZero[2, n], 50], {n, 1, 5, 1}]
+n |
+1 | 3.3842417671495934727014260185379031127323883259329
+2 | 6.7938075132682675382911671098369487124493222183854
+3 | 10.023477979360037978505391792081418280789658279097
+
+
+*/
+
+ /*
+[bessel_zero_output]
+
+ boost::math::cyl_bessel_j_zero(0.0, 1) 2.40483
+ boost::math::cyl_bessel_j_zero(0.0, 1) 2.40482555769577
+ boost::math::cyl_bessel_j_zero(-1.0, 1) 1.#QNAN
+ boost::math::cyl_bessel_j_zero(inf, 1) 1.#QNAN
+ boost::math::cyl_bessel_j_zero(nan, 1) 1.#QNAN
+ 5.13562230184068
+ 8.41724414039986
+ 11.6198411721491
+ 14.7959517823513
+ 17.9598194949878
+
+ x = 3.7368421052631578947368421052631578947368421052632, r = 7.2731751938316489503185694262290765588963196701623
+ x = 3.7368421052631578947368421052631578947368421052632, r = 67.815145619696290925556791375555951165111460585458
+ 7.2731751938316489503185694262290765588963196701623
+ 10.724858308883141732536172745851416647110749599085
+ 14.018504599452388106120459558042660282427471931581
+ cyl_neumann_zero(2., 1) = 3.3842417671495935000000000000000000000000000000000
+ 3.3842418193817139000000000000000000000000000000000
+ 6.7938075065612793000000000000000000000000000000000
+ 10.023477554321289000000000000000000000000000000000
+ 3.6154383428745996706772556069431792744372398748422
+ nu = 1.00000, sum = 0.124990, exact = 0.125000
+ Throw exception Error in function boost::math::cyl_bessel_j_zero<double>(double, int): Order argument is -1, but must be >= 0 !
+ Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Order argument is 1.#INF, but must be finite >= 0 !
+ Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Order argument is 1.#QNAN, but must be finite >= 0 !
+ Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the -1'th zero, but must be > 0 !
+ Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the -2147483648'th zero, but must be > 0 !
+ Throw exception Error in function boost::math::cyl_bessel_j_zero<long double>(long double, int): Requested the -2147483648'th zero, but must be > 0 !
+
+
+] [/bessel_zero_output]
+*/
+
diff --git a/src/boost/libs/math/example/bessel_zeros_example_1.cpp b/src/boost/libs/math/example/bessel_zeros_example_1.cpp
new file mode 100644
index 000000000..59172cd02
--- /dev/null
+++ b/src/boost/libs/math/example/bessel_zeros_example_1.cpp
@@ -0,0 +1,213 @@
+
+// Copyright Christopher Kormanyos 2013.
+// Copyright Paul A. Bristow 2013.
+// Copyright John Maddock 2013.
+
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated.
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+
+// Weisstein, Eric W. "Bessel Function Zeros." From MathWorld--A Wolfram Web Resource.
+// http://mathworld.wolfram.com/BesselFunctionZeros.html
+// Test values can be calculated using [@wolframalpha.com WolframAplha]
+// See also http://dlmf.nist.gov/10.21
+
+//[bessel_zeros_example_1
+
+/*`This example demonstrates calculating zeros of the Bessel and Neumann functions.
+It also shows how Boost.Math and Boost.Multiprecision can be combined to provide
+a many decimal digit precision. For 50 decimal digit precision we need to include
+*/
+
+ #include <boost/multiprecision/cpp_dec_float.hpp>
+
+/*`and a `typedef` for `float_type` may be convenient
+(allowing a quick switch to re-compute at built-in `double` or other precision)
+*/
+ typedef boost::multiprecision::cpp_dec_float_50 float_type;
+
+//`To use the functions for finding zeros of the functions we need
+
+ #include <boost/math/special_functions/bessel.hpp>
+
+//`This file includes the forward declaration signatures for the zero-finding functions:
+
+// #include <boost/math/special_functions/math_fwd.hpp>
+
+/*`but more details are in the full documentation, for example at
+[@http://www.boost.org/doc/libs/1_53_0/libs/math/doc/sf_and_dist/html/math_toolkit/special/bessel/bessel_over.html Boost.Math Bessel functions].
+*/
+
+/*`This example shows obtaining both a single zero of the Bessel function,
+and then placing multiple zeros into a container like `std::vector` by providing an iterator.
+*/
+//] [/bessel_zeros_example_1]
+
+/*The signature of the single value function is:
+
+ template <class T>
+ inline typename detail::bessel_traits<T, T, policies::policy<> >::result_type
+ cyl_bessel_j_zero(
+ T v, // Floating-point value for Jv.
+ int m); // start index.
+
+The result type is controlled by the floating-point type of parameter `v`
+(but subject to the usual __precision_policy and __promotion_policy).
+
+The signature of multiple zeros function is:
+
+ template <class T, class OutputIterator>
+ inline OutputIterator cyl_bessel_j_zero(
+ T v, // Floating-point value for Jv.
+ int start_index, // 1-based start index.
+ unsigned number_of_zeros, // How many zeros to generate
+ OutputIterator out_it); // Destination for zeros.
+
+There is also a version which allows control of the __policy_section for error handling and precision.
+
+ template <class T, class OutputIterator, class Policy>
+ inline OutputIterator cyl_bessel_j_zero(
+ T v, // Floating-point value for Jv.
+ int start_index, // 1-based start index.
+ unsigned number_of_zeros, // How many zeros to generate
+ OutputIterator out_it, // Destination for zeros.
+ const Policy& pol); // Policy to use.
+*/
+
+int main()
+{
+ try
+ {
+//[bessel_zeros_example_2
+
+/*`[tip It is always wise to place code using Boost.Math inside try'n'catch blocks;
+this will ensure that helpful error messages are shown when exceptional conditions arise.]
+
+First, evaluate a single Bessel zero.
+
+The precision is controlled by the float-point type of template parameter `T` of `v`
+so this example has `double` precision, at least 15 but up to 17 decimal digits (for the common 64-bit double).
+*/
+// double root = boost::math::cyl_bessel_j_zero(0.0, 1);
+// // Displaying with default precision of 6 decimal digits:
+// std::cout << "boost::math::cyl_bessel_j_zero(0.0, 1) " << root << std::endl; // 2.40483
+// // And with all the guaranteed (15) digits:
+// std::cout.precision(std::numeric_limits<double>::digits10);
+// std::cout << "boost::math::cyl_bessel_j_zero(0.0, 1) " << root << std::endl; // 2.40482555769577
+/*`But note that because the parameter `v` controls the precision of the result,
+`v` [*must be a floating-point type].
+So if you provide an integer type, say 0, rather than 0.0, then it will fail to compile thus:
+``
+ root = boost::math::cyl_bessel_j_zero(0, 1);
+``
+with this error message
+``
+ error C2338: Order must be a floating-point type.
+``
+
+Optionally, we can use a policy to ignore errors, C-style, returning some value,
+perhaps infinity or NaN, or the best that can be done. (See __user_error_handling).
+
+To create a (possibly unwise!) policy `ignore_all_policy` that ignores all errors:
+*/
+
+ typedef boost::math::policies::policy<
+ boost::math::policies::domain_error<boost::math::policies::ignore_error>,
+ boost::math::policies::overflow_error<boost::math::policies::ignore_error>,
+ boost::math::policies::underflow_error<boost::math::policies::ignore_error>,
+ boost::math::policies::denorm_error<boost::math::policies::ignore_error>,
+ boost::math::policies::pole_error<boost::math::policies::ignore_error>,
+ boost::math::policies::evaluation_error<boost::math::policies::ignore_error>
+ > ignore_all_policy;
+ //`Examples of use of this `ignore_all_policy` are
+
+ double inf = std::numeric_limits<double>::infinity();
+ double nan = std::numeric_limits<double>::quiet_NaN();
+
+ double dodgy_root = boost::math::cyl_bessel_j_zero(-1.0, 1, ignore_all_policy());
+ std::cout << "boost::math::cyl_bessel_j_zero(-1.0, 1) " << dodgy_root << std::endl; // 1.#QNAN
+ double inf_root = boost::math::cyl_bessel_j_zero(inf, 1, ignore_all_policy());
+ std::cout << "boost::math::cyl_bessel_j_zero(inf, 1) " << inf_root << std::endl; // 1.#QNAN
+ double nan_root = boost::math::cyl_bessel_j_zero(nan, 1, ignore_all_policy());
+ std::cout << "boost::math::cyl_bessel_j_zero(nan, 1) " << nan_root << std::endl; // 1.#QNAN
+
+/*`Another version of `cyl_bessel_j_zero` allows calculation of multiple zeros with one call,
+placing the results in a container, often `std::vector`.
+For example, generate and display the first five `double` roots of J[sub v] for integral order 2,
+as column ['J[sub 2](x)] in table 1 of
+[@ http://mathworld.wolfram.com/BesselFunctionZeros.html Wolfram Bessel Function Zeros].
+*/
+ unsigned int n_roots = 5U;
+ std::vector<double> roots;
+ boost::math::cyl_bessel_j_zero(2.0, 1, n_roots, std::back_inserter(roots));
+ std::copy(roots.begin(),
+ roots.end(),
+ std::ostream_iterator<double>(std::cout, "\n"));
+
+/*`Or we can use Boost.Multiprecision to generate 50 decimal digit roots of ['J[sub v]]
+for non-integral order `v= 71/19 == 3.736842`, expressed as an exact-integer fraction
+to generate the most accurate value possible for all floating-point types.
+
+We set the precision of the output stream, and show trailing zeros to display a fixed 50 decimal digits.
+*/
+ std::cout.precision(std::numeric_limits<float_type>::digits10); // 50 decimal digits.
+ std::cout << std::showpoint << std::endl; // Show trailing zeros.
+
+ float_type x = float_type(71) / 19;
+ float_type r = boost::math::cyl_bessel_j_zero(x, 1); // 1st root.
+ std::cout << "x = " << x << ", r = " << r << std::endl;
+
+ r = boost::math::cyl_bessel_j_zero(x, 20U); // 20th root.
+ std::cout << "x = " << x << ", r = " << r << std::endl;
+
+ std::vector<float_type> zeros;
+ boost::math::cyl_bessel_j_zero(x, 1, 3, std::back_inserter(zeros));
+
+ std::cout << "cyl_bessel_j_zeros" << std::endl;
+ // Print the roots to the output stream.
+ std::copy(zeros.begin(), zeros.end(),
+ std::ostream_iterator<float_type>(std::cout, "\n"));
+//] [/bessel_zeros_example_2]
+ }
+ catch (std::exception const& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+ } // int main()
+
+ /*
+
+ Output:
+
+ Description: Autorun "J:\Cpp\big_number\Debug\bessel_zeros_example_1.exe"
+ boost::math::cyl_bessel_j_zero(-1.0, 1) 3.83171
+ boost::math::cyl_bessel_j_zero(inf, 1) 1.#QNAN
+ boost::math::cyl_bessel_j_zero(nan, 1) 1.#QNAN
+ 5.13562
+ 8.41724
+ 11.6198
+ 14.796
+ 17.9598
+
+ x = 3.7368421052631578947368421052631578947368421052632, r = 7.2731751938316489503185694262290765588963196701623
+ x = 3.7368421052631578947368421052631578947368421052632, r = 67.815145619696290925556791375555951165111460585458
+ cyl_bessel_j_zeros
+ 7.2731751938316489503185694262290765588963196701623
+ 10.724858308883141732536172745851416647110749599085
+ 14.018504599452388106120459558042660282427471931581
+
+*/
+
diff --git a/src/boost/libs/math/example/bessel_zeros_interator_example.cpp b/src/boost/libs/math/example/bessel_zeros_interator_example.cpp
new file mode 100644
index 000000000..a92a2704a
--- /dev/null
+++ b/src/boost/libs/math/example/bessel_zeros_interator_example.cpp
@@ -0,0 +1,88 @@
+// Copyright Christopher Kormanyos 2013.
+// Copyright Paul A. Bristow 2013.
+// Copyright John Maddock 2013.
+
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated.
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+
+//[bessel_zeros_iterator_example_1
+
+/*`[h5 Using Output Iterator to sum zeros of Bessel Functions]
+
+This example demonstrates summing zeros of the Bessel functions.
+To use the functions for finding zeros of the functions we need
+ */
+
+#include <boost/math/special_functions/bessel.hpp>
+
+/*`We use the `cyl_bessel_j_zero` output iterator parameter `out_it`
+to create a sum of ['1/zeros[super 2]] by defining a custom output iterator:
+*/
+
+template <class T>
+struct output_summation_iterator
+{
+ output_summation_iterator(T* p) : p_sum(p)
+ {}
+ output_summation_iterator& operator*()
+ { return *this; }
+ output_summation_iterator& operator++()
+ { return *this; }
+ output_summation_iterator& operator++(int)
+ { return *this; }
+ output_summation_iterator& operator = (T const& val)
+ {
+ *p_sum += 1./ (val * val); // Summing 1/zero^2.
+ return *this;
+ }
+private:
+ T* p_sum;
+};
+
+//] [/bessel_zeros_iterator_example_1]
+
+int main()
+{
+ try
+ {
+//[bessel_zeros_iterator_example_2
+
+/*`The sum is calculated for many values, converging on the analytical exact value of `1/8`.
+*/
+ using boost::math::cyl_bessel_j_zero;
+ double nu = 1.;
+ double sum = 0;
+ output_summation_iterator<double> it(&sum); // sum of 1/zeros^2
+ cyl_bessel_j_zero(nu, 1, 10000, it);
+
+ double s = 1/(4 * (nu + 1)); // 0.125 = 1/8 is exact analytical solution.
+ std::cout << std::setprecision(6) << "nu = " << nu << ", sum = " << sum
+ << ", exact = " << s << std::endl;
+ // nu = 1.00000, sum = 0.124990, exact = 0.125000
+//] [/bessel_zeros_iterator_example_2]
+ }
+ catch (std::exception const& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+ return 0;
+ } // int_main()
+
+/*
+ Output:
+
+ nu = 1, sum = 0.12499, exact = 0.125
+*/
diff --git a/src/boost/libs/math/example/big_seventh.cpp b/src/boost/libs/math/example/big_seventh.cpp
new file mode 100644
index 000000000..7f3a3b0d9
--- /dev/null
+++ b/src/boost/libs/math/example/big_seventh.cpp
@@ -0,0 +1,204 @@
+// 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)
+
+// Copyright Paul A. Bristow 2019.
+// Copyright Christopher Kormanyos 2012.
+// Copyright John Maddock 2012.
+
+// This file is written to be included from a Quickbook .qbk document.
+// It can be compiled by the C++ compiler, and run. Any output can
+// also be added here as comment or included or pasted in elsewhere.
+// Caution: this file contains Quickbook markup as well as code
+// and comments: don't change any of the special comment markups!
+
+#ifdef _MSC_VER
+#pragma warning(disable : 4512) // assignment operator could not be generated.
+#pragma warning(disable : 4996)
+#endif
+
+//[big_seventh_example_1
+
+/*`[h5 Using Boost.Multiprecision `cpp_float` types for numerical calculations with higher precision than built-in `long double`.]
+
+The Boost.Multiprecision library can be used for computations requiring precision
+exceeding that of standard built-in types such as `float`, `double`
+and `long double`. For extended-precision calculations, Boost.Multiprecision
+supplies several template data types called `cpp_bin_float_`.
+
+The number of decimal digits of precision is fixed at compile-time via template parameter.
+
+To use these floating-point types and
+[@https://www.boost.org/doc/libs/release/libs/math/doc/html/constants.html Boost.Math collection of high-precision constants],
+we need some includes:
+*/
+
+#include <boost/math/constants/constants.hpp>
+
+#include <boost/multiprecision/cpp_bin_float.hpp>
+// that includes some predefined typedefs that can be used thus:
+// using boost::multiprecision::cpp_bin_float_quad;
+// using boost::multiprecision::cpp_bin_float_50;
+// using boost::multiprecision::cpp_bin_float_100;
+
+#include <iostream>
+#include <limits>
+#include <type_traits>
+
+/*` So now we can demonstrate with some trivial calculations:
+*/
+
+//] //[big_seventh_example_1]
+
+void no_et()
+{
+ using namespace boost::multiprecision;
+
+ std::cout.setf(std::ios_base::boolalpha);
+
+ typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_on> cpp_bin_float_quad_et_on;
+ typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_quad_et_off;
+
+ typedef number<backends::cpp_bin_float<113, backends::digit_base_2, void, boost::int16_t, -16382, 16383>, et_off> cpp_bin_float_oct;
+
+
+ cpp_bin_float_quad x("42.");
+ std::cout << "cpp_bin_float_quad x = " << x << std::endl;
+
+ cpp_bin_float_quad_et_on q("42.");
+
+ std::cout << "std::is_same<cpp_bin_float_quad, cpp_bin_float_quad_et_off>::value is " << std::is_same<cpp_bin_float_quad, cpp_bin_float_quad_et_off>::value << std::endl;
+ std::cout << "std::is_same<cpp_bin_float_quad, cpp_bin_float_quad_et_on>::value is " << std::is_same<cpp_bin_float_quad, cpp_bin_float_quad_et_on>::value << std::endl;
+
+ std::cout << "cpp_bin_float_quad_et_on q = " << q << std::endl;
+ cpp_bin_float_50 y("42."); // typedef number<backends::cpp_bin_float<50> > cpp_bin_float_50;
+
+ std::cout << "cpp_bin_float_50 y = " << y << std::endl;
+
+ typedef number<backends::cpp_bin_float<50>, et_off > cpp_bin_float_50_no_et;
+ typedef number<backends::cpp_bin_float<50>, et_on > cpp_bin_float_50_et;
+
+ cpp_bin_float_50_no_et z("42."); // typedef number<backends::cpp_bin_float<50> > cpp_bin_float_50;
+
+ std::cout << "cpp_bin_float_50_no_et z = " << z << std::endl;
+
+ std::cout << " std::is_same<cpp_bin_float_50, cpp_bin_float_50_no_et>::value is " << std::is_same<cpp_bin_float_50, cpp_bin_float_50_no_et>::value << std::endl;
+ std::cout << " std::is_same<cpp_bin_float_50_et, cpp_bin_float_50_no_et>::value is " << std::is_same<cpp_bin_float_50_et, cpp_bin_float_50_no_et>::value << std::endl;
+
+} // void no_et()
+
+int main()
+{
+
+ no_et();
+
+ return 0;
+
+
+ //[big_seventh_example_2
+ /*`Using `typedef cpp_bin_float_50` hides the complexity of multiprecision,
+allows us to define variables with 50 decimal digit precision just like built-in `double`.
+*/
+ using boost::multiprecision::cpp_bin_float_50;
+
+ cpp_bin_float_50 seventh = cpp_bin_float_50(1) / 7; // 1 / 7
+
+ /*`By default, output would only show the standard 6 decimal digits,
+ so set precision to show all 50 significant digits, including any trailing zeros.
+*/
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::digits10);
+ std::cout << std::showpoint << std::endl; // Append any trailing zeros.
+ std::cout << seventh << std::endl;
+ /*`which outputs:
+
+ 0.14285714285714285714285714285714285714285714285714
+
+We can also use __math_constants like [pi],
+guaranteed to be initialized with the very last bit of precision (__ULP) for the floating-point type.
+*/
+ std::cout << "pi = " << boost::math::constants::pi<cpp_bin_float_50>() << std::endl;
+ cpp_bin_float_50 circumference = boost::math::constants::pi<cpp_bin_float_50>() * 2 * seventh;
+ std::cout << "c = " << circumference << std::endl;
+
+ /*`which outputs
+
+ pi = 3.1415926535897932384626433832795028841971693993751
+
+ c = 0.89759790102565521098932668093700082405633411410717
+*/
+ //] [/big_seventh_example_2]
+
+ //[big_seventh_example_3
+ /*`So using `cpp_bin_float_50` looks like a simple 'drop-in' for the __fundamental_type like 'double',
+but beware of loss of precision from construction or conversion from `double` or other lower precision types.
+This is a mistake that is very easy to make,
+and very difficult to detect because the loss of precision is only visible after the 17th decimal digit.
+
+We can show this by constructing from `double`, (avoiding the schoolboy-error `double d7 = 1 / 7;` giving zero!)
+*/
+
+ double d7 = 1. / 7; //
+ std::cout << "d7 = " << d7 << std::endl;
+
+ cpp_bin_float_50 seventh_0 = cpp_bin_float_50(1 / 7); // Avoid the schoolboy-error 1 / 7 == 0!)
+ std::cout << "seventh_0 = " << seventh_0 << std::endl;
+ // seventh_double0 = 0.0000000000000000000000000000000000000000000000000
+
+ cpp_bin_float_50 seventh_double = cpp_bin_float_50(1. / 7); // Construct from double!
+ std::cout << "seventh_double = " << seventh_double << std::endl; // Boost.Multiprecision post-school error!
+ // seventh_double = 0.14285714285714284921269268124888185411691665649414
+
+ /*`Did you spot the mistake? After the 17th decimal digit, result is random!
+
+14285714285714 should be recurring.
+*/
+
+ cpp_bin_float_50 seventh_big(1); // 1
+ seventh_big /= 7;
+ std::cout << "seventh_big = " << seventh_big << std::endl; //
+ // seventh_big = 0.14285714285714285714285714285714285714285714285714
+ /*`Note the recurring 14285714285714 pattern as expected.
+
+As one would expect, the variable can be `const` (but sadly [*not yet `constexpr`]).
+*/
+
+ const cpp_bin_float_50 seventh_const(cpp_bin_float_50(1) / 7);
+ std::cout << "seventh_const = " << seventh_const << std::endl;
+ // seventh_const = 0.14285714285714285714285714285714285714285714285714
+
+/*`The full output is:
+*/
+
+//] [/big_seventh_example_3
+
+//[big_seventh_example_constexpr
+
+// Sadly we cannot (yet) write:
+// constexpr cpp_bin_float_50 any_constexpr(0);
+
+// constexpr cpp_bin_float_50 seventh_constexpr (cpp_bin_float_50(1) / 7);
+// std::cout << "seventh_constexpr = " << seventh_constexpr << std::endl; //
+// nor use the macro BOOST_CONSTEXPR_OR_CONST unless it returns `const`
+// BOOST_CONSTEXPR_OR_CONST cpp_bin_float_50 seventh_constexpr(seventh_const);
+
+//] [/big_seventh_example_constexpr
+
+ return 0;
+} // int main()
+
+/*
+//[big_seventh_example_output
+
+0.14285714285714285714285714285714285714285714285714
+pi = 3.1415926535897932384626433832795028841971693993751
+c = 0.89759790102565521098932668093700082405633411410717
+d7 = 0.14285714285714284921269268124888185411691665649414
+seventh_0 = 0.0000000000000000000000000000000000000000000000000
+seventh_double = 0.14285714285714284921269268124888185411691665649414
+seventh_big = 0.14285714285714285714285714285714285714285714285714
+seventh_const = 0.14285714285714285714285714285714285714285714285714
+
+//] //[big_seventh_example_output]
+
+*/
diff --git a/src/boost/libs/math/example/binomial_coinflip_example.cpp b/src/boost/libs/math/example/binomial_coinflip_example.cpp
new file mode 100644
index 000000000..5f1826b94
--- /dev/null
+++ b/src/boost/libs/math/example/binomial_coinflip_example.cpp
@@ -0,0 +1,243 @@
+// Copyright Paul A. 2007, 2010
+// Copyright John Maddock 2006
+
+// 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)
+
+// Simple example of computing probabilities and quantiles for
+// a Bernoulli random variable representing the flipping of a coin.
+
+// http://mathworld.wolfram.com/CoinTossing.html
+// http://en.wikipedia.org/wiki/Bernoulli_trial
+// Weisstein, Eric W. "Dice." From MathWorld--A Wolfram Web Resource.
+// http://mathworld.wolfram.com/Dice.html
+// http://en.wikipedia.org/wiki/Bernoulli_distribution
+// http://mathworld.wolfram.com/BernoulliDistribution.html
+//
+// An idealized coin consists of a circular disk of zero thickness which,
+// when thrown in the air and allowed to fall, will rest with either side face up
+// ("heads" H or "tails" T) with equal probability. A coin is therefore a two-sided die.
+// Despite slight differences between the sides and nonzero thickness of actual coins,
+// the distribution of their tosses makes a good approximation to a p==1/2 Bernoulli distribution.
+
+//[binomial_coinflip_example1
+
+/*`An example of a [@http://en.wikipedia.org/wiki/Bernoulli_process Bernoulli process]
+is coin flipping.
+A variable in such a sequence may be called a Bernoulli variable.
+
+This example shows using the Binomial distribution to predict the probability
+of heads and tails when throwing a coin.
+
+The number of correct answers (say heads),
+X, is distributed as a binomial random variable
+with binomial distribution parameters number of trials (flips) n = 10 and probability (success_fraction) of getting a head p = 0.5 (a 'fair' coin).
+
+(Our coin is assumed fair, but we could easily change the success_fraction parameter p
+from 0.5 to some other value to simulate an unfair coin,
+say 0.6 for one with chewing gum on the tail,
+so it is more likely to fall tails down and heads up).
+
+First we need some includes and using statements to be able to use the binomial distribution, some std input and output, and get started:
+*/
+
+#include <boost/math/distributions/binomial.hpp>
+ using boost::math::binomial;
+
+#include <iostream>
+ using std::cout; using std::endl; using std::left;
+#include <iomanip>
+ using std::setw;
+
+int main()
+{
+ cout << "Using Binomial distribution to predict how many heads and tails." << endl;
+ try
+ {
+/*`
+See note [link coinflip_eg_catch with the catch block]
+about why a try and catch block is always a good idea.
+
+First, construct a binomial distribution with parameters success_fraction
+1/2, and how many flips.
+*/
+ const double success_fraction = 0.5; // = 50% = 1/2 for a 'fair' coin.
+ int flips = 10;
+ binomial flip(flips, success_fraction);
+
+ cout.precision(4);
+/*`
+ Then some examples of using Binomial moments (and echoing the parameters).
+*/
+ cout << "From " << flips << " one can expect to get on average "
+ << mean(flip) << " heads (or tails)." << endl;
+ cout << "Mode is " << mode(flip) << endl;
+ cout << "Standard deviation is " << standard_deviation(flip) << endl;
+ cout << "So about 2/3 will lie within 1 standard deviation and get between "
+ << ceil(mean(flip) - standard_deviation(flip)) << " and "
+ << floor(mean(flip) + standard_deviation(flip)) << " correct." << endl;
+ cout << "Skewness is " << skewness(flip) << endl;
+ // Skewness of binomial distributions is only zero (symmetrical)
+ // if success_fraction is exactly one half,
+ // for example, when flipping 'fair' coins.
+ cout << "Skewness if success_fraction is " << flip.success_fraction()
+ << " is " << skewness(flip) << endl << endl; // Expect zero for a 'fair' coin.
+/*`
+Now we show a variety of predictions on the probability of heads:
+*/
+ cout << "For " << flip.trials() << " coin flips: " << endl;
+ cout << "Probability of getting no heads is " << pdf(flip, 0) << endl;
+ cout << "Probability of getting at least one head is " << 1. - pdf(flip, 0) << endl;
+/*`
+When we want to calculate the probability for a range or values we can sum the PDF's:
+*/
+ cout << "Probability of getting 0 or 1 heads is "
+ << pdf(flip, 0) + pdf(flip, 1) << endl; // sum of exactly == probabilities
+/*`
+Or we can use the cdf.
+*/
+ cout << "Probability of getting 0 or 1 (<= 1) heads is " << cdf(flip, 1) << endl;
+ cout << "Probability of getting 9 or 10 heads is " << pdf(flip, 9) + pdf(flip, 10) << endl;
+/*`
+Note that using
+*/
+ cout << "Probability of getting 9 or 10 heads is " << 1. - cdf(flip, 8) << endl;
+/*`
+is less accurate than using the complement
+*/
+ cout << "Probability of getting 9 or 10 heads is " << cdf(complement(flip, 8)) << endl;
+/*`
+Since the subtraction may involve
+[@http://docs.sun.com/source/806-3568/ncg_goldberg.html cancellation error],
+where as `cdf(complement(flip, 8))`
+does not use such a subtraction internally, and so does not exhibit the problem.
+
+To get the probability for a range of heads, we can either add the pdfs for each number of heads
+*/
+ cout << "Probability of between 4 and 6 heads (4 or 5 or 6) is "
+ // P(X == 4) + P(X == 5) + P(X == 6)
+ << pdf(flip, 4) + pdf(flip, 5) + pdf(flip, 6) << endl;
+/*`
+But this is probably less efficient than using the cdf
+*/
+ cout << "Probability of between 4 and 6 heads (4 or 5 or 6) is "
+ // P(X <= 6) - P(X <= 3) == P(X < 4)
+ << cdf(flip, 6) - cdf(flip, 3) << endl;
+/*`
+Certainly for a bigger range like, 3 to 7
+*/
+ cout << "Probability of between 3 and 7 heads (3, 4, 5, 6 or 7) is "
+ // P(X <= 7) - P(X <= 2) == P(X < 3)
+ << cdf(flip, 7) - cdf(flip, 2) << endl;
+ cout << endl;
+
+/*`
+Finally, print two tables of probability for the /exactly/ and /at least/ a number of heads.
+*/
+ // Print a table of probability for the exactly a number of heads.
+ cout << "Probability of getting exactly (==) heads" << endl;
+ for (int successes = 0; successes <= flips; successes++)
+ { // Say success means getting a head (or equally success means getting a tail).
+ double probability = pdf(flip, successes);
+ cout << left << setw(2) << successes << " " << setw(10)
+ << probability << " or 1 in " << 1. / probability
+ << ", or " << probability * 100. << "%" << endl;
+ } // for i
+ cout << endl;
+
+ // Tabulate the probability of getting between zero heads and 0 up to 10 heads.
+ cout << "Probability of getting up to (<=) heads" << endl;
+ for (int successes = 0; successes <= flips; successes++)
+ { // Say success means getting a head
+ // (equally success could mean getting a tail).
+ double probability = cdf(flip, successes); // P(X <= heads)
+ cout << setw(2) << successes << " " << setw(10) << left
+ << probability << " or 1 in " << 1. / probability << ", or "
+ << probability * 100. << "%"<< endl;
+ } // for i
+/*`
+The last (0 to 10 heads) must, of course, be 100% probability.
+*/
+ double probability = 0.3;
+ double q = quantile(flip, probability);
+ std::cout << "Quantile (flip, " << probability << ") = " << q << std::endl; // Quantile (flip, 0.3) = 3
+ probability = 0.6;
+ q = quantile(flip, probability);
+ std::cout << "Quantile (flip, " << probability << ") = " << q << std::endl; // Quantile (flip, 0.6) = 5
+ }
+ catch(const std::exception& e)
+ {
+ //
+ /*`
+ [#coinflip_eg_catch]
+ It is always essential to include try & catch blocks because
+ default policies are to throw exceptions on arguments that
+ are out of domain or cause errors like numeric-overflow.
+
+ Lacking try & catch blocks, the program will abort, whereas the
+ message below from the thrown exception will give some helpful
+ clues as to the cause of the problem.
+ */
+ std::cout <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+//] [binomial_coinflip_example1]
+ return 0;
+} // int main()
+
+// Output:
+
+//[binomial_coinflip_example_output
+/*`
+
+[pre
+Using Binomial distribution to predict how many heads and tails.
+From 10 one can expect to get on average 5 heads (or tails).
+Mode is 5
+Standard deviation is 1.581
+So about 2/3 will lie within 1 standard deviation and get between 4 and 6 correct.
+Skewness is 0
+Skewness if success_fraction is 0.5 is 0
+
+For 10 coin flips:
+Probability of getting no heads is 0.0009766
+Probability of getting at least one head is 0.999
+Probability of getting 0 or 1 heads is 0.01074
+Probability of getting 0 or 1 (<= 1) heads is 0.01074
+Probability of getting 9 or 10 heads is 0.01074
+Probability of getting 9 or 10 heads is 0.01074
+Probability of getting 9 or 10 heads is 0.01074
+Probability of between 4 and 6 heads (4 or 5 or 6) is 0.6562
+Probability of between 4 and 6 heads (4 or 5 or 6) is 0.6563
+Probability of between 3 and 7 heads (3, 4, 5, 6 or 7) is 0.8906
+
+Probability of getting exactly (==) heads
+0 0.0009766 or 1 in 1024, or 0.09766%
+1 0.009766 or 1 in 102.4, or 0.9766%
+2 0.04395 or 1 in 22.76, or 4.395%
+3 0.1172 or 1 in 8.533, or 11.72%
+4 0.2051 or 1 in 4.876, or 20.51%
+5 0.2461 or 1 in 4.063, or 24.61%
+6 0.2051 or 1 in 4.876, or 20.51%
+7 0.1172 or 1 in 8.533, or 11.72%
+8 0.04395 or 1 in 22.76, or 4.395%
+9 0.009766 or 1 in 102.4, or 0.9766%
+10 0.0009766 or 1 in 1024, or 0.09766%
+
+Probability of getting up to (<=) heads
+0 0.0009766 or 1 in 1024, or 0.09766%
+1 0.01074 or 1 in 93.09, or 1.074%
+2 0.05469 or 1 in 18.29, or 5.469%
+3 0.1719 or 1 in 5.818, or 17.19%
+4 0.377 or 1 in 2.653, or 37.7%
+5 0.623 or 1 in 1.605, or 62.3%
+6 0.8281 or 1 in 1.208, or 82.81%
+7 0.9453 or 1 in 1.058, or 94.53%
+8 0.9893 or 1 in 1.011, or 98.93%
+9 0.999 or 1 in 1.001, or 99.9%
+10 1 or 1 in 1, or 100%
+]
+*/
+//][/binomial_coinflip_example_output]
diff --git a/src/boost/libs/math/example/binomial_confidence_limits.cpp b/src/boost/libs/math/example/binomial_confidence_limits.cpp
new file mode 100644
index 000000000..56ab48c36
--- /dev/null
+++ b/src/boost/libs/math/example/binomial_confidence_limits.cpp
@@ -0,0 +1,165 @@
+// Copyright John Maddock 2006
+// Copyright Paul A. Bristow 2010
+
+// 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)
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4512) // assignment operator could not be generated.
+# pragma warning(disable: 4510) // default constructor could not be generated.
+# pragma warning(disable: 4610) // can never be instantiated - user defined constructor required.
+#endif
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::fixed; using std::left; using std::right; using std::right; using std::setw;
+using std::setprecision;
+
+#include <boost/math/distributions/binomial.hpp>
+
+void confidence_limits_on_frequency(unsigned trials, unsigned successes)
+{
+ //
+ // trials = Total number of trials.
+ // successes = Total number of observed successes.
+ //
+ // Calculate confidence limits for an observed
+ // frequency of occurrence that follows a binomial distribution.
+ //
+ //using namespace std; // Avoid
+ // using namespace boost::math; // potential name ambiguity with std <random>
+ using boost::math::binomial_distribution;
+
+ // Print out general info:
+ cout <<
+ "___________________________________________\n"
+ "2-Sided Confidence Limits For Success Ratio\n"
+ "___________________________________________\n\n";
+ cout << setprecision(7);
+ cout << setw(40) << left << "Number of Observations" << "= " << trials << "\n";
+ cout << setw(40) << left << "Number of successes" << "= " << successes << "\n";
+ cout << setw(40) << left << "Sample frequency of occurrence" << "= " << double(successes) / trials << "\n";
+ //
+ // Define a table of significance levels:
+ //
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+ //
+ // Print table header:
+ //
+ cout << "\n\n"
+ "_______________________________________________________________________\n"
+ "Confidence Lower CP Upper CP Lower JP Upper JP\n"
+ " Value (%) Limit Limit Limit Limit\n"
+ "_______________________________________________________________________\n";
+ //
+ // Now print out the data for the table rows.
+ //
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // Calculate Clopper Pearson bounds:
+ double l = binomial_distribution<>::find_lower_bound_on_p(trials, successes, alpha[i]/2);
+ double u = binomial_distribution<>::find_upper_bound_on_p(trials, successes, alpha[i]/2);
+ // Print Clopper Pearson Limits:
+ cout << fixed << setprecision(5) << setw(15) << right << l;
+ cout << fixed << setprecision(5) << setw(15) << right << u;
+ // Calculate Jeffreys Prior Bounds:
+ l = binomial_distribution<>::find_lower_bound_on_p(trials, successes, alpha[i]/2, binomial_distribution<>::jeffreys_prior_interval);
+ u = binomial_distribution<>::find_upper_bound_on_p(trials, successes, alpha[i]/2, binomial_distribution<>::jeffreys_prior_interval);
+ // Print Jeffreys Prior Limits:
+ cout << fixed << setprecision(5) << setw(15) << right << l;
+ cout << fixed << setprecision(5) << setw(15) << right << u << std::endl;
+ }
+ cout << endl;
+} // void confidence_limits_on_frequency()
+
+int main()
+{
+ confidence_limits_on_frequency(20, 4);
+ confidence_limits_on_frequency(200, 40);
+ confidence_limits_on_frequency(2000, 400);
+
+ return 0;
+} // int main()
+
+/*
+
+------ Build started: Project: binomial_confidence_limits, Configuration: Debug Win32 ------
+Compiling...
+binomial_confidence_limits.cpp
+Linking...
+Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\binomial_confidence_limits.exe"
+___________________________________________
+2-Sided Confidence Limits For Success Ratio
+___________________________________________
+
+Number of Observations = 20
+Number of successes = 4
+Sample frequency of occurrence = 0.2
+
+
+_______________________________________________________________________
+Confidence Lower CP Upper CP Lower JP Upper JP
+ Value (%) Limit Limit Limit Limit
+_______________________________________________________________________
+ 50.000 0.12840 0.29588 0.14974 0.26916
+ 75.000 0.09775 0.34633 0.11653 0.31861
+ 90.000 0.07135 0.40103 0.08734 0.37274
+ 95.000 0.05733 0.43661 0.07152 0.40823
+ 99.000 0.03576 0.50661 0.04655 0.47859
+ 99.900 0.01905 0.58632 0.02634 0.55960
+ 99.990 0.01042 0.64997 0.01530 0.62495
+ 99.999 0.00577 0.70216 0.00901 0.67897
+
+___________________________________________
+2-Sided Confidence Limits For Success Ratio
+___________________________________________
+
+Number of Observations = 200
+Number of successes = 40
+Sample frequency of occurrence = 0.2000000
+
+
+_______________________________________________________________________
+Confidence Lower CP Upper CP Lower JP Upper JP
+ Value (%) Limit Limit Limit Limit
+_______________________________________________________________________
+ 50.000 0.17949 0.22259 0.18190 0.22001
+ 75.000 0.16701 0.23693 0.16934 0.23429
+ 90.000 0.15455 0.25225 0.15681 0.24956
+ 95.000 0.14689 0.26223 0.14910 0.25951
+ 99.000 0.13257 0.28218 0.13468 0.27940
+ 99.900 0.11703 0.30601 0.11902 0.30318
+ 99.990 0.10489 0.32652 0.10677 0.32366
+ 99.999 0.09492 0.34485 0.09670 0.34197
+
+___________________________________________
+2-Sided Confidence Limits For Success Ratio
+___________________________________________
+
+Number of Observations = 2000
+Number of successes = 400
+Sample frequency of occurrence = 0.2000000
+
+
+_______________________________________________________________________
+Confidence Lower CP Upper CP Lower JP Upper JP
+ Value (%) Limit Limit Limit Limit
+_______________________________________________________________________
+ 50.000 0.19382 0.20638 0.19406 0.20613
+ 75.000 0.18965 0.21072 0.18990 0.21047
+ 90.000 0.18537 0.21528 0.18561 0.21503
+ 95.000 0.18267 0.21821 0.18291 0.21796
+ 99.000 0.17745 0.22400 0.17769 0.22374
+ 99.900 0.17150 0.23079 0.17173 0.23053
+ 99.990 0.16658 0.23657 0.16681 0.23631
+ 99.999 0.16233 0.24169 0.16256 0.24143
+
+*/
+
+
+
diff --git a/src/boost/libs/math/example/binomial_example_nag.cpp b/src/boost/libs/math/example/binomial_example_nag.cpp
new file mode 100644
index 000000000..152558c76
--- /dev/null
+++ b/src/boost/libs/math/example/binomial_example_nag.cpp
@@ -0,0 +1,91 @@
+// Copyright Paul A. 2007, 2010
+// Copyright John Maddock 2007
+// 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)
+
+// Simple example of computing probabilities for a binomial random variable.
+// Replication of source nag_binomial_dist (g01bjc).
+
+// Shows how to replace NAG C library calls by Boost Math Toolkit C++ calls.
+// Note that the default policy does not replicate the way that NAG
+// library calls handle 'bad' arguments, but you can define policies that do,
+// as well as other policies that may suit your application even better.
+// See the examples of changing default policies for details.
+
+#include <boost/math/distributions/binomial.hpp>
+
+#include <iostream>
+ using std::cout; using std::endl; using std::ios; using std::showpoint;
+#include <iomanip>
+ using std::fixed; using std::setw;
+
+int main()
+{
+ cout << "Using the binomial distribution to replicate a NAG library call." << endl;
+ using boost::math::binomial_distribution;
+
+ // This replicates the computation of the examples of using nag-binomial_dist
+ // using g01bjc in section g01 Simple Calculations on Statistical Data.
+ // http://www.nag.co.uk/numeric/cl/manual/pdf/G01/g01bjc.pdf
+ // Program results section 8.3 page 3.g01bjc.3
+ //8.2. Program Data
+ //g01bjc Example Program Data
+ //4 0.50 2 : n, p, k
+ //19 0.44 13
+ //100 0.75 67
+ //2000 0.33 700
+ //8.3. Program Results
+ //g01bjc Example Program Results
+ //n p k plek pgtk peqk
+ //4 0.500 2 0.68750 0.31250 0.37500
+ //19 0.440 13 0.99138 0.00862 0.01939
+ //100 0.750 67 0.04460 0.95540 0.01700
+ //2000 0.330 700 0.97251 0.02749 0.00312
+
+ cout.setf(ios::showpoint); // Trailing zeros to show significant decimal digits.
+ cout.precision(5); // Might calculate this from trials in distribution?
+ cout << fixed;
+ // Binomial distribution.
+
+ // Note that cdf(dist, k) is equivalent to NAG library plek probability of <= k
+ // cdf(complement(dist, k)) is equivalent to NAG library pgtk probability of > k
+ // pdf(dist, k) is equivalent to NAG library peqk probability of == k
+
+ cout << " n p k plek pgtk peqk " << endl;
+ binomial_distribution<>my_dist(4, 0.5);
+ cout << setw(4) << (int)my_dist.trials() << " " << my_dist.success_fraction()
+ << " " << 2 << " " << cdf(my_dist, 2) << " "
+ << cdf(complement(my_dist, 2)) << " " << pdf(my_dist, 2) << endl;
+
+ binomial_distribution<>two(19, 0.440);
+ cout << setw(4) << (int)two.trials() << " " << two.success_fraction()
+ << " " << 13 << " " << cdf(two, 13) << " "
+ << cdf(complement(two, 13)) << " " << pdf(two, 13) << endl;
+
+ binomial_distribution<>three(100, 0.750);
+ cout << setw(4) << (int)three.trials() << " " << three.success_fraction()
+ << " " << 67 << " " << cdf(three, 67) << " " << cdf(complement(three, 67))
+ << " " << pdf(three, 67) << endl;
+ binomial_distribution<>four(2000, 0.330);
+ cout << setw(4) << (int)four.trials() << " " << four.success_fraction()
+ << " " << 700 << " "
+ << cdf(four, 700) << " " << cdf(complement(four, 700))
+ << " " << pdf(four, 700) << endl;
+
+ return 0;
+} // int main()
+
+/*
+
+Example of using the binomial distribution to replicate a NAG library call.
+ n p k plek pgtk peqk
+ 4 0.50000 2 0.68750 0.31250 0.37500
+ 19 0.44000 13 0.99138 0.00862 0.01939
+ 100 0.75000 67 0.04460 0.95540 0.01700
+2000 0.33000 700 0.97251 0.02749 0.00312
+
+
+ */
+
diff --git a/src/boost/libs/math/example/binomial_quiz_example.cpp b/src/boost/libs/math/example/binomial_quiz_example.cpp
new file mode 100644
index 000000000..acf06e2da
--- /dev/null
+++ b/src/boost/libs/math/example/binomial_quiz_example.cpp
@@ -0,0 +1,525 @@
+// Copyright Paul A. Bristow 2007, 2009, 2010
+// Copyright John Maddock 2006
+
+// 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)
+
+// binomial_examples_quiz.cpp
+
+// Simple example of computing probabilities and quantiles for a binomial random variable
+// representing the correct guesses on a multiple-choice test.
+
+// source http://www.stat.wvu.edu/SRS/Modules/Binomial/test.html
+
+//[binomial_quiz_example1
+/*`
+A multiple choice test has four possible answers to each of 16 questions.
+A student guesses the answer to each question,
+so the probability of getting a correct answer on any given question is
+one in four, a quarter, 1/4, 25% or fraction 0.25.
+The conditions of the binomial experiment are assumed to be met:
+n = 16 questions constitute the trials;
+each question results in one of two possible outcomes (correct or incorrect);
+the probability of being correct is 0.25 and is constant if no knowledge about the subject is assumed;
+the questions are answered independently if the student's answer to a question
+in no way influences his/her answer to another question.
+
+First, we need to be able to use the binomial distribution constructor
+(and some std input/output, of course).
+*/
+
+#include <boost/math/distributions/binomial.hpp>
+ using boost::math::binomial;
+
+#include <iostream>
+ using std::cout; using std::endl;
+ using std::ios; using std::flush; using std::left; using std::right; using std::fixed;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <exception>
+
+
+
+//][/binomial_quiz_example1]
+
+int main()
+{
+ try
+ {
+ cout << "Binomial distribution example - guessing in a quiz." << endl;
+//[binomial_quiz_example2
+/*`
+The number of correct answers, X, is distributed as a binomial random variable
+with binomial distribution parameters: questions n and success fraction probability p.
+So we construct a binomial distribution:
+*/
+ int questions = 16; // All the questions in the quiz.
+ int answers = 4; // Possible answers to each question.
+ double success_fraction = 1. / answers; // If a random guess, p = 1/4 = 0.25.
+ binomial quiz(questions, success_fraction);
+/*`
+and display the distribution parameters we used thus:
+*/
+ cout << "In a quiz with " << quiz.trials()
+ << " questions and with a probability of guessing right of "
+ << quiz.success_fraction() * 100 << " %"
+ << " or 1 in " << static_cast<int>(1. / quiz.success_fraction()) << endl;
+/*`
+Show a few probabilities of just guessing:
+*/
+ cout << "Probability of getting none right is " << pdf(quiz, 0) << endl; // 0.010023
+ cout << "Probability of getting exactly one right is " << pdf(quiz, 1) << endl;
+ cout << "Probability of getting exactly two right is " << pdf(quiz, 2) << endl;
+ int pass_score = 11;
+ cout << "Probability of getting exactly " << pass_score << " answers right by chance is "
+ << pdf(quiz, pass_score) << endl;
+ cout << "Probability of getting all " << questions << " answers right by chance is "
+ << pdf(quiz, questions) << endl;
+/*`
+[pre
+Probability of getting none right is 0.0100226
+Probability of getting exactly one right is 0.0534538
+Probability of getting exactly two right is 0.133635
+Probability of getting exactly 11 right is 0.000247132
+Probability of getting exactly all 16 answers right by chance is 2.32831e-010
+]
+These don't give any encouragement to guessers!
+
+We can tabulate the 'getting exactly right' ( == ) probabilities thus:
+*/
+ cout << "\n" "Guessed Probability" << right << endl;
+ for (int successes = 0; successes <= questions; successes++)
+ {
+ double probability = pdf(quiz, successes);
+ cout << setw(2) << successes << " " << probability << endl;
+ }
+ cout << endl;
+/*`
+[pre
+Guessed Probability
+ 0 0.0100226
+ 1 0.0534538
+ 2 0.133635
+ 3 0.207876
+ 4 0.225199
+ 5 0.180159
+ 6 0.110097
+ 7 0.0524273
+ 8 0.0196602
+ 9 0.00582526
+10 0.00135923
+11 0.000247132
+12 3.43239e-005
+13 3.5204e-006
+14 2.51457e-007
+15 1.11759e-008
+16 2.32831e-010
+]
+Then we can add the probabilities of some 'exactly right' like this:
+*/
+ cout << "Probability of getting none or one right is " << pdf(quiz, 0) + pdf(quiz, 1) << endl;
+
+/*`
+[pre
+Probability of getting none or one right is 0.0634764
+]
+But if more than a couple of scores are involved, it is more convenient (and may be more accurate)
+to use the Cumulative Distribution Function (cdf) instead:
+*/
+ cout << "Probability of getting none or one right is " << cdf(quiz, 1) << endl;
+/*`
+[pre
+Probability of getting none or one right is 0.0634764
+]
+Since the cdf is inclusive, we can get the probability of getting up to 10 right ( <= )
+*/
+ cout << "Probability of getting <= 10 right (to fail) is " << cdf(quiz, 10) << endl;
+/*`
+[pre
+Probability of getting <= 10 right (to fail) is 0.999715
+]
+To get the probability of getting 11 or more right (to pass),
+it is tempting to use ``1 - cdf(quiz, 10)`` to get the probability of > 10
+*/
+ cout << "Probability of getting > 10 right (to pass) is " << 1 - cdf(quiz, 10) << endl;
+/*`
+[pre
+Probability of getting > 10 right (to pass) is 0.000285239
+]
+But this should be resisted in favor of using the __complements function (see __why_complements).
+*/
+ cout << "Probability of getting > 10 right (to pass) is " << cdf(complement(quiz, 10)) << endl;
+/*`
+[pre
+Probability of getting > 10 right (to pass) is 0.000285239
+]
+And we can check that these two, <= 10 and > 10, add up to unity.
+*/
+BOOST_ASSERT((cdf(quiz, 10) + cdf(complement(quiz, 10))) == 1.);
+/*`
+If we want a < rather than a <= test, because the CDF is inclusive, we must subtract one from the score.
+*/
+ cout << "Probability of getting less than " << pass_score
+ << " (< " << pass_score << ") answers right by guessing is "
+ << cdf(quiz, pass_score -1) << endl;
+/*`
+[pre
+Probability of getting less than 11 (< 11) answers right by guessing is 0.999715
+]
+and similarly to get a >= rather than a > test
+we also need to subtract one from the score (and can again check the sum is unity).
+This is because if the cdf is /inclusive/,
+then its complement must be /exclusive/ otherwise there would be one possible
+outcome counted twice!
+*/
+ cout << "Probability of getting at least " << pass_score
+ << "(>= " << pass_score << ") answers right by guessing is "
+ << cdf(complement(quiz, pass_score-1))
+ << ", only 1 in " << 1/cdf(complement(quiz, pass_score-1)) << endl;
+
+ BOOST_ASSERT((cdf(quiz, pass_score -1) + cdf(complement(quiz, pass_score-1))) == 1);
+
+/*`
+[pre
+Probability of getting at least 11 (>= 11) answers right by guessing is 0.000285239, only 1 in 3505.83
+]
+Finally we can tabulate some probabilities:
+*/
+ cout << "\n" "At most (<=)""\n""Guessed OK Probability" << right << endl;
+ for (int score = 0; score <= questions; score++)
+ {
+ cout << setw(2) << score << " " << setprecision(10)
+ << cdf(quiz, score) << endl;
+ }
+ cout << endl;
+/*`
+[pre
+At most (<=)
+Guessed OK Probability
+ 0 0.01002259576
+ 1 0.0634764398
+ 2 0.1971110499
+ 3 0.4049871101
+ 4 0.6301861752
+ 5 0.8103454274
+ 6 0.9204427481
+ 7 0.9728700437
+ 8 0.9925302796
+ 9 0.9983555346
+10 0.9997147608
+11 0.9999618928
+12 0.9999962167
+13 0.9999997371
+14 0.9999999886
+15 0.9999999998
+16 1
+]
+*/
+ cout << "\n" "At least (>)""\n""Guessed OK Probability" << right << endl;
+ for (int score = 0; score <= questions; score++)
+ {
+ cout << setw(2) << score << " " << setprecision(10)
+ << cdf(complement(quiz, score)) << endl;
+ }
+/*`
+[pre
+At least (>)
+Guessed OK Probability
+ 0 0.9899774042
+ 1 0.9365235602
+ 2 0.8028889501
+ 3 0.5950128899
+ 4 0.3698138248
+ 5 0.1896545726
+ 6 0.07955725188
+ 7 0.02712995629
+ 8 0.00746972044
+ 9 0.001644465374
+10 0.0002852391917
+11 3.810715862e-005
+12 3.783265129e-006
+13 2.628657967e-007
+14 1.140870154e-008
+15 2.328306437e-010
+16 0
+]
+We now consider the probabilities of *ranges* of correct guesses.
+
+First, calculate the probability of getting a range of guesses right,
+by adding the exact probabilities of each from low ... high.
+*/
+ int low = 3; // Getting at least 3 right.
+ int high = 5; // Getting as most 5 right.
+ double sum = 0.;
+ for (int i = low; i <= high; i++)
+ {
+ sum += pdf(quiz, i);
+ }
+ cout.precision(4);
+ cout << "Probability of getting between "
+ << low << " and " << high << " answers right by guessing is "
+ << sum << endl; // 0.61323
+/*`
+[pre
+Probability of getting between 3 and 5 answers right by guessing is 0.6132
+]
+Or, usually better, we can use the difference of cdfs instead:
+*/
+ cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
+ << cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 0.61323
+/*`
+[pre
+Probability of getting between 3 and 5 answers right by guessing is 0.6132
+]
+And we can also try a few more combinations of high and low choices:
+*/
+ low = 1; high = 6;
+ cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
+ << cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 1 and 6 P= 0.91042
+ low = 1; high = 8;
+ cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
+ << cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 1 <= x 8 P = 0.9825
+ low = 4; high = 4;
+ cout << "Probability of getting between " << low << " and " << high << " answers right by guessing is "
+ << cdf(quiz, high) - cdf(quiz, low - 1) << endl; // 4 <= x 4 P = 0.22520
+
+/*`
+[pre
+Probability of getting between 1 and 6 answers right by guessing is 0.9104
+Probability of getting between 1 and 8 answers right by guessing is 0.9825
+Probability of getting between 4 and 4 answers right by guessing is 0.2252
+]
+[h4 Using Binomial distribution moments]
+Using moments of the distribution, we can say more about the spread of results from guessing.
+*/
+ cout << "By guessing, on average, one can expect to get " << mean(quiz) << " correct answers." << endl;
+ cout << "Standard deviation is " << standard_deviation(quiz) << endl;
+ cout << "So about 2/3 will lie within 1 standard deviation and get between "
+ << ceil(mean(quiz) - standard_deviation(quiz)) << " and "
+ << floor(mean(quiz) + standard_deviation(quiz)) << " correct." << endl;
+ cout << "Mode (the most frequent) is " << mode(quiz) << endl;
+ cout << "Skewness is " << skewness(quiz) << endl;
+
+/*`
+[pre
+By guessing, on average, one can expect to get 4 correct answers.
+Standard deviation is 1.732
+So about 2/3 will lie within 1 standard deviation and get between 3 and 5 correct.
+Mode (the most frequent) is 4
+Skewness is 0.2887
+]
+[h4 Quantiles]
+The quantiles (percentiles or percentage points) for a few probability levels:
+*/
+ cout << "Quartiles " << quantile(quiz, 0.25) << " to "
+ << quantile(complement(quiz, 0.25)) << endl; // Quartiles
+ cout << "1 standard deviation " << quantile(quiz, 0.33) << " to "
+ << quantile(quiz, 0.67) << endl; // 1 sd
+ cout << "Deciles " << quantile(quiz, 0.1) << " to "
+ << quantile(complement(quiz, 0.1))<< endl; // Deciles
+ cout << "5 to 95% " << quantile(quiz, 0.05) << " to "
+ << quantile(complement(quiz, 0.05))<< endl; // 5 to 95%
+ cout << "2.5 to 97.5% " << quantile(quiz, 0.025) << " to "
+ << quantile(complement(quiz, 0.025)) << endl; // 2.5 to 97.5%
+ cout << "2 to 98% " << quantile(quiz, 0.02) << " to "
+ << quantile(complement(quiz, 0.02)) << endl; // 2 to 98%
+
+ cout << "If guessing then percentiles 1 to 99% will get " << quantile(quiz, 0.01)
+ << " to " << quantile(complement(quiz, 0.01)) << " right." << endl;
+/*`
+Notice that these output integral values because the default policy is `integer_round_outwards`.
+[pre
+Quartiles 2 to 5
+1 standard deviation 2 to 5
+Deciles 1 to 6
+5 to 95% 0 to 7
+2.5 to 97.5% 0 to 8
+2 to 98% 0 to 8
+]
+*/
+
+//] [/binomial_quiz_example2]
+
+//[discrete_quantile_real
+/*`
+Quantiles values are controlled by the __understand_dis_quant quantile policy chosen.
+The default is `integer_round_outwards`,
+so the lower quantile is rounded down, and the upper quantile is rounded up.
+
+But we might believe that the real values tell us a little more - see __math_discrete.
+
+We could control the policy for *all* distributions by
+
+ #define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
+
+ at the head of the program would make this policy apply
+to this *one, and only*, translation unit.
+
+Or we can now create a (typedef for) policy that has discrete quantiles real
+(here avoiding any 'using namespaces ...' statements):
+*/
+ using boost::math::policies::policy;
+ using boost::math::policies::discrete_quantile;
+ using boost::math::policies::real;
+ using boost::math::policies::integer_round_outwards; // Default.
+ typedef boost::math::policies::policy<discrete_quantile<real> > real_quantile_policy;
+/*`
+Add a custom binomial distribution called ``real_quantile_binomial`` that uses ``real_quantile_policy``
+*/
+ using boost::math::binomial_distribution;
+ typedef binomial_distribution<double, real_quantile_policy> real_quantile_binomial;
+/*`
+Construct an object of this custom distribution:
+*/
+ real_quantile_binomial quiz_real(questions, success_fraction);
+/*`
+And use this to show some quantiles - that now have real rather than integer values.
+*/
+ cout << "Quartiles " << quantile(quiz, 0.25) << " to "
+ << quantile(complement(quiz_real, 0.25)) << endl; // Quartiles 2 to 4.6212
+ cout << "1 standard deviation " << quantile(quiz_real, 0.33) << " to "
+ << quantile(quiz_real, 0.67) << endl; // 1 sd 2.6654 4.194
+ cout << "Deciles " << quantile(quiz_real, 0.1) << " to "
+ << quantile(complement(quiz_real, 0.1))<< endl; // Deciles 1.3487 5.7583
+ cout << "5 to 95% " << quantile(quiz_real, 0.05) << " to "
+ << quantile(complement(quiz_real, 0.05))<< endl; // 5 to 95% 0.83739 6.4559
+ cout << "2.5 to 97.5% " << quantile(quiz_real, 0.025) << " to "
+ << quantile(complement(quiz_real, 0.025)) << endl; // 2.5 to 97.5% 0.42806 7.0688
+ cout << "2 to 98% " << quantile(quiz_real, 0.02) << " to "
+ << quantile(complement(quiz_real, 0.02)) << endl; // 2 to 98% 0.31311 7.7880
+
+ cout << "If guessing, then percentiles 1 to 99% will get " << quantile(quiz_real, 0.01)
+ << " to " << quantile(complement(quiz_real, 0.01)) << " right." << endl;
+/*`
+[pre
+Real Quantiles
+Quartiles 2 to 4.621
+1 standard deviation 2.665 to 4.194
+Deciles 1.349 to 5.758
+5 to 95% 0.8374 to 6.456
+2.5 to 97.5% 0.4281 to 7.069
+2 to 98% 0.3131 to 7.252
+If guessing then percentiles 1 to 99% will get 0 to 7.788 right.
+]
+*/
+
+//] [/discrete_quantile_real]
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+
+
+/*
+
+Output is:
+
+BAutorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\binomial_quiz_example.exe"
+Binomial distribution example - guessing in a quiz.
+In a quiz with 16 questions and with a probability of guessing right of 25 % or 1 in 4
+Probability of getting none right is 0.0100226
+Probability of getting exactly one right is 0.0534538
+Probability of getting exactly two right is 0.133635
+Probability of getting exactly 11 answers right by chance is 0.000247132
+Probability of getting all 16 answers right by chance is 2.32831e-010
+Guessed Probability
+ 0 0.0100226
+ 1 0.0534538
+ 2 0.133635
+ 3 0.207876
+ 4 0.225199
+ 5 0.180159
+ 6 0.110097
+ 7 0.0524273
+ 8 0.0196602
+ 9 0.00582526
+10 0.00135923
+11 0.000247132
+12 3.43239e-005
+13 3.5204e-006
+14 2.51457e-007
+15 1.11759e-008
+16 2.32831e-010
+Probability of getting none or one right is 0.0634764
+Probability of getting none or one right is 0.0634764
+Probability of getting <= 10 right (to fail) is 0.999715
+Probability of getting > 10 right (to pass) is 0.000285239
+Probability of getting > 10 right (to pass) is 0.000285239
+Probability of getting less than 11 (< 11) answers right by guessing is 0.999715
+Probability of getting at least 11(>= 11) answers right by guessing is 0.000285239, only 1 in 3505.83
+At most (<=)
+Guessed OK Probability
+ 0 0.01002259576
+ 1 0.0634764398
+ 2 0.1971110499
+ 3 0.4049871101
+ 4 0.6301861752
+ 5 0.8103454274
+ 6 0.9204427481
+ 7 0.9728700437
+ 8 0.9925302796
+ 9 0.9983555346
+10 0.9997147608
+11 0.9999618928
+12 0.9999962167
+13 0.9999997371
+14 0.9999999886
+15 0.9999999998
+16 1
+At least (>)
+Guessed OK Probability
+ 0 0.9899774042
+ 1 0.9365235602
+ 2 0.8028889501
+ 3 0.5950128899
+ 4 0.3698138248
+ 5 0.1896545726
+ 6 0.07955725188
+ 7 0.02712995629
+ 8 0.00746972044
+ 9 0.001644465374
+10 0.0002852391917
+11 3.810715862e-005
+12 3.783265129e-006
+13 2.628657967e-007
+14 1.140870154e-008
+15 2.328306437e-010
+16 0
+Probability of getting between 3 and 5 answers right by guessing is 0.6132
+Probability of getting between 3 and 5 answers right by guessing is 0.6132
+Probability of getting between 1 and 6 answers right by guessing is 0.9104
+Probability of getting between 1 and 8 answers right by guessing is 0.9825
+Probability of getting between 4 and 4 answers right by guessing is 0.2252
+By guessing, on average, one can expect to get 4 correct answers.
+Standard deviation is 1.732
+So about 2/3 will lie within 1 standard deviation and get between 3 and 5 correct.
+Mode (the most frequent) is 4
+Skewness is 0.2887
+Quartiles 2 to 5
+1 standard deviation 2 to 5
+Deciles 1 to 6
+5 to 95% 0 to 7
+2.5 to 97.5% 0 to 8
+2 to 98% 0 to 8
+If guessing then percentiles 1 to 99% will get 0 to 8 right.
+Quartiles 2 to 4.621
+1 standard deviation 2.665 to 4.194
+Deciles 1.349 to 5.758
+5 to 95% 0.8374 to 6.456
+2.5 to 97.5% 0.4281 to 7.069
+2 to 98% 0.3131 to 7.252
+If guessing, then percentiles 1 to 99% will get 0 to 7.788 right.
+
+*/
+
diff --git a/src/boost/libs/math/example/binomial_sample_sizes.cpp b/src/boost/libs/math/example/binomial_sample_sizes.cpp
new file mode 100644
index 000000000..db9f85978
--- /dev/null
+++ b/src/boost/libs/math/example/binomial_sample_sizes.cpp
@@ -0,0 +1,176 @@
+// Copyright John Maddock 2006
+// Copyright Paul A. Bristow 2010
+
+// 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)
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4512) // assignment operator could not be generated.
+# pragma warning(disable: 4510) // default constructor could not be generated.
+# pragma warning(disable: 4610) // can never be instantiated - user defined constructor required.
+#endif
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::fixed; using std::left; using std::right; using std::right; using std::setw;
+using std::setprecision;
+
+#include <boost/math/distributions/binomial.hpp>
+
+void find_max_sample_size(double p, unsigned successes)
+{
+ //
+ // p = success ratio.
+ // successes = Total number of observed successes.
+ //
+ // Calculate how many trials we can have to ensure the
+ // maximum number of successes does not exceed "successes".
+ // A typical use would be failure analysis, where you want
+ // zero or fewer "successes" with some probability.
+ //
+ // using namespace boost::math;
+ // Avoid potential binomial_distribution name ambiguity with std <random>
+ using boost::math::binomial_distribution;
+
+ // Print out general info:
+ cout <<
+ "________________________\n"
+ "Maximum Number of Trials\n"
+ "________________________\n\n";
+ cout << setprecision(7);
+ cout << setw(40) << left << "Success ratio" << "= " << p << "\n";
+ cout << setw(40) << left << "Maximum Number of \"successes\" permitted" << "= " << successes << "\n";
+ //
+ // Define a table of confidence intervals:
+ //
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+ //
+ // Print table header:
+ //
+ cout << "\n\n"
+ "____________________________\n"
+ "Confidence Max Number\n"
+ " Value (%) Of Trials \n"
+ "____________________________\n";
+ //
+ // Now print out the data for the table rows.
+ //
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // calculate trials:
+ double t = binomial_distribution<>::find_maximum_number_of_trials(successes, p, alpha[i]);
+ t = floor(t);
+ // Print Trials:
+ cout << fixed << setprecision(0) << setw(15) << right << t << endl;
+ }
+ cout << endl;
+}
+
+int main()
+{
+ find_max_sample_size(1.0/1000, 0);
+ find_max_sample_size(1.0/10000, 0);
+ find_max_sample_size(1.0/100000, 0);
+ find_max_sample_size(1.0/1000000, 0);
+
+ return 0;
+}
+
+
+/*
+
+Output:
+
+ binomial_sample_sizes.cpp
+ binomial_sample_sizes_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Debug\binomial_sample_sizes_example.exe
+ ________________________
+ Maximum Number of Trials
+ ________________________
+
+ Success ratio = 0.001
+ Maximum Number of "successes" permitted = 0
+
+
+ ____________________________
+ Confidence Max Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 692
+ 75.000 287
+ 90.000 105
+ 95.000 51
+ 99.000 10
+ 99.900 0
+ 99.990 0
+ 99.999 0
+
+ ________________________
+ Maximum Number of Trials
+ ________________________
+
+ Success ratio = 0.0001000
+ Maximum Number of "successes" permitted = 0
+
+
+ ____________________________
+ Confidence Max Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 6931
+ 75.000 2876
+ 90.000 1053
+ 95.000 512
+ 99.000 100
+ 99.900 10
+ 99.990 0
+ 99.999 0
+
+ ________________________
+ Maximum Number of Trials
+ ________________________
+
+ Success ratio = 0.0000100
+ Maximum Number of "successes" permitted = 0
+
+
+ ____________________________
+ Confidence Max Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 69314
+ 75.000 28768
+ 90.000 10535
+ 95.000 5129
+ 99.000 1005
+ 99.900 100
+ 99.990 10
+ 99.999 1
+
+ ________________________
+ Maximum Number of Trials
+ ________________________
+
+ Success ratio = 0.0000010
+ Maximum Number of "successes" permitted = 0
+
+
+ ____________________________
+ Confidence Max Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 693146
+ 75.000 287681
+ 90.000 105360
+ 95.000 51293
+ 99.000 10050
+ 99.900 1000
+ 99.990 100
+ 99.999 10
+
+
+*/
diff --git a/src/boost/libs/math/example/brent_minimise_example.cpp b/src/boost/libs/math/example/brent_minimise_example.cpp
new file mode 100644
index 000000000..09053bd03
--- /dev/null
+++ b/src/boost/libs/math/example/brent_minimise_example.cpp
@@ -0,0 +1,730 @@
+//! \file
+//! \brief Brent_minimise_example.cpp
+
+// Copyright Paul A. Bristow 2015, 2018.
+
+// 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)
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+// For some diagnostic information:
+//#define BOOST_MATH_INSTRUMENT
+// If quadmath float128 is available:
+//#define BOOST_HAVE_QUADMATH
+
+// Example of finding minimum of a function with Brent's method.
+//[brent_minimise_include_1
+#include <boost/math/tools/minima.hpp>
+//] [/brent_minimise_include_1]
+
+#include <boost/math/special_functions/next.hpp>
+#include <boost/multiprecision/cpp_dec_float.hpp>
+#include <boost/math/special_functions/pow.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/test/tools/floating_point_comparison.hpp> // For is_close_at)tolerance and is_small
+
+//[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 2018.
+#ifdef BOOST_HAVE_QUADMATH // Define only if GCC or Intel, and have quadmath.lib or .dll library available.
+# include <boost/multiprecision/float128.hpp>
+#endif
+
+#include <iostream>
+// using std::cout; using std::endl;
+#include <iomanip>
+// using std::setw; using std::setprecision;
+#include <limits>
+using std::numeric_limits;
+#include <tuple>
+#include <utility> // pair, make_pair
+#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
+
+// An example of a function for which we want to find a minimum.
+double f(double x)
+{
+ return (x + 3) * (x - 1) * (x - 1);
+}
+
+//[brent_minimise_double_functor
+struct funcdouble
+{
+ double operator()(double const& x)
+ {
+ return (x + 3) * (x - 1) * (x - 1); // (x + 3)(x - 1)^2
+ }
+};
+//] [/brent_minimise_double_functor]
+
+//[brent_minimise_T_functor
+struct func
+{
+ template <class T>
+ T operator()(T const& x)
+ {
+ return (x + 3) * (x - 1) * (x - 1); // (x + 3)(x - 1)^2
+ }
+};
+//] [/brent_minimise_T_functor]
+
+//! Test if two values are close within a given tolerance.
+template<typename FPT>
+inline bool
+is_close_to(FPT left, FPT right, FPT tolerance)
+{
+ return boost::math::fpc::close_at_tolerance<FPT>(tolerance) (left, right);
+}
+
+//[brent_minimise_close
+
+//! Compare if value got is close to expected,
+//! checking first if expected is very small
+//! (to avoid divide by tiny or zero during comparison)
+//! before comparing expect with value got.
+
+template <class T>
+bool is_close(T expect, T got, T tolerance)
+{
+ using boost::math::fpc::close_at_tolerance;
+ using boost::math::fpc::is_small;
+ using boost::math::fpc::FPC_STRONG;
+
+ if (is_small<T>(expect, tolerance))
+ {
+ return is_small<T>(got, tolerance);
+ }
+
+ return close_at_tolerance<T>(tolerance, FPC_STRONG) (expect, got);
+} // bool is_close(T expect, T got, T tolerance)
+
+//] [/brent_minimise_close]
+
+//[brent_minimise_T_show
+
+//! Example template function to find and show minima.
+//! \tparam T floating-point or fixed_point type.
+template <class T>
+void show_minima()
+{
+ using boost::math::tools::brent_find_minima;
+ using std::sqrt;
+ try
+ { // Always use try'n'catch blocks with Boost.Math to ensure you get any error messages.
+
+ int bits = std::numeric_limits<T>::digits/2; // Maximum is digits/2;
+ std::streamsize prec = static_cast<int>(2 + sqrt((double)bits)); // Number of significant decimal digits.
+ std::streamsize precision = std::cout.precision(prec); // Save and set.
+
+ 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's minimization is "
+ << sqrt(std::numeric_limits<T>::epsilon())
+ << "\n Displaying to std::numeric_limits<T>::digits10 " << prec << ", significant decimal digits."
+ << std::endl;
+
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ // Construct using string, not double, avoids loss of precision.
+ //T bracket_min = static_cast<T>("-4");
+ //T bracket_max = static_cast<T>("1.3333333333333333333333333333333333333333333333333");
+
+ // Construction from double may cause loss of precision for multiprecision types like cpp_bin_float,
+ // but brackets values are good enough for using Brent minimization.
+ T bracket_min = static_cast<T>(-4);
+ T bracket_max = static_cast<T>(1.3333333333333333333333333333333333333333333333333);
+
+ std::pair<T, T> r = brent_find_minima<func, T>(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << " x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second;
+ if (it < maxit)
+ {
+ std::cout << ",\n met " << bits << " bits precision" << ", after " << it << " iterations." << std::endl;
+ }
+ else
+ {
+ std::cout << ",\n did NOT meet " << bits << " bits precision" << " after " << it << " iterations!" << std::endl;
+ }
+ // Check that result is that expected (compared to theoretical uncertainty).
+ T uncertainty = sqrt(std::numeric_limits<T>::epsilon());
+ std::cout << std::boolalpha << "x == 1 (compared to uncertainty " << uncertainty << ") is "
+ << is_close(static_cast<T>(1), r.first, uncertainty) << std::endl;
+ std::cout << std::boolalpha << "f(x) == (0 compared to uncertainty " << uncertainty << ") is "
+ << is_close(static_cast<T>(0), r.second, uncertainty) << std::endl;
+ // Problems with this using multiprecision with expression template on?
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+} // void show_minima()
+
+//] [/brent_minimise_T_show]
+
+int main()
+{
+ using boost::math::tools::brent_find_minima;
+ using std::sqrt;
+ std::cout << "Brent's minimisation examples." << std::endl;
+ std::cout << std::boolalpha << std::endl;
+ std::cout << std::showpoint << std::endl; // Show trailing zeros.
+
+ // Tip - using
+ // std::cout.precision(std::numeric_limits<T>::digits10);
+ // during debugging is wise because it warns
+ // if construction of multiprecision involves conversion from double
+ // by finding random or zero digits after 17th decimal digit.
+
+ // Specific type double - unlimited iterations (unwise?).
+ {
+ std::cout << "\nType double - unlimited iterations (unwise?)" << std::endl;
+ //[brent_minimise_double_1
+ const int double_bits = std::numeric_limits<double>::digits;
+ std::pair<double, double> r = brent_find_minima(funcdouble(), -4., 4. / 3, double_bits);
+
+ std::streamsize precision_1 = std::cout.precision(std::numeric_limits<double>::digits10);
+ // Show all double precision decimal digits and trailing zeros.
+ std::cout << "x at minimum = " << r.first
+ << ", f(" << r.first << ") = " << r.second << std::endl;
+ //] [/brent_minimise_double_1]
+ std::cout << "x at minimum = " << (r.first - 1.) / r.first << std::endl;
+ // x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018
+ double uncertainty = sqrt(std::numeric_limits<double>::epsilon());
+ std::cout << "Uncertainty sqrt(epsilon) = " << uncertainty << std::endl;
+ // sqrt(epsilon) = 1.49011611938477e-008
+ // (epsilon is always > 0, so no need to take abs value).
+
+ std::cout.precision(precision_1); // Restore.
+ //[brent_minimise_double_1a
+
+ using boost::math::fpc::close_at_tolerance;
+ using boost::math::fpc::is_small;
+
+ std::cout << "x = " << r.first << ", f(x) = " << r.second << std::endl;
+ std::cout << std::boolalpha << "x == 1 (compared to uncertainty "
+ << uncertainty << ") is " << is_close(1., r.first, uncertainty) << std::endl; // true
+ std::cout << std::boolalpha << "f(x) == 0 (compared to uncertainty "
+ << uncertainty << ") is " << is_close(0., r.second, uncertainty) << std::endl; // true
+//] [/brent_minimise_double_1a]
+
+ }
+ std::cout << "\nType double with limited iterations." << std::endl;
+ {
+ const int bits = std::numeric_limits<double>::digits;
+ // Specific type double - limit maxit to 20 iterations.
+ std::cout << "Precision bits = " << bits << std::endl;
+ //[brent_minimise_double_2
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ std::pair<double, double> 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_2]
+ // x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018
+//[brent_minimise_double_3
+ std::streamsize prec = static_cast<int>(2 + sqrt((double)bits)); // Number of significant decimal digits.
+ std::streamsize precision_3 = std::cout.precision(prec); // Save and set new precision.
+ std::cout << "Showing " << bits << " bits "
+ "precision with " << prec
+ << " decimal digits from tolerance " << sqrt(std::numeric_limits<double>::epsilon())
+ << std::endl;
+
+ std::cout << "x at minimum = " << r.first
+ << ", f(" << r.first << ") = " << r.second
+ << " after " << it << " iterations. " << std::endl;
+ std::cout.precision(precision_3); // Restore.
+//] [/brent_minimise_double_3]
+ // Showing 53 bits precision with 9 decimal digits from tolerance 1.49011611938477e-008
+ // x at minimum = 1, f(1) = 5.04852568e-018
+ }
+
+ std::cout << "\nType double with limited iterations and half double bits." << std::endl;
+ {
+
+//[brent_minimise_double_4
+ const int bits_div_2 = std::numeric_limits<double>::digits / 2; // Half digits precision (effective maximum).
+ double epsilon_2 = boost::math::pow<-(std::numeric_limits<double>::digits/2 - 1), double>(2);
+ std::streamsize prec = static_cast<int>(2 + sqrt((double)bits_div_2)); // Number of significant decimal digits.
+
+ std::cout << "Showing " << bits_div_2 << " bits precision with " << prec
+ << " decimal digits from tolerance " << sqrt(epsilon_2)
+ << std::endl;
+ std::streamsize precision_4 = std::cout.precision(prec); // Save.
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it_4 = maxit;
+ std::pair<double, double> r = brent_find_minima(funcdouble(), -4., 4. / 3, bits_div_2, it_4);
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
+ std::cout << it_4 << " iterations. " << std::endl;
+ std::cout.precision(precision_4); // Restore.
+
+//] [/brent_minimise_double_4]
+ }
+ // x at minimum = 1, f(1) = 5.04852568e-018
+
+ {
+ std::cout << "\nType double with limited iterations and quarter double bits." << std::endl;
+ //[brent_minimise_double_5
+ const int bits_div_4 = std::numeric_limits<double>::digits / 4; // Quarter precision.
+ double epsilon_4 = boost::math::pow<-(std::numeric_limits<double>::digits / 4 - 1), double>(2);
+ std::streamsize prec = static_cast<int>(2 + sqrt((double)bits_div_4)); // Number of significant decimal digits.
+ std::cout << "Showing " << bits_div_4 << " bits precision with " << prec
+ << " decimal digits from tolerance " << sqrt(epsilon_4)
+ << std::endl;
+ std::streamsize precision_5 = std::cout.precision(prec); // Save & set.
+ const boost::uintmax_t maxit = 20;
+
+ boost::uintmax_t it_5 = maxit;
+ std::pair<double, double> r = brent_find_minima(funcdouble(), -4., 4. / 3, bits_div_4, it_5);
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second
+ << ", after " << it_5 << " iterations. " << std::endl;
+ std::cout.precision(precision_5); // Restore.
+
+ //] [/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.
+
+ {
+ std::cout << "\nType long double with limited iterations and all long double bits." << std::endl;
+//[brent_minimise_template_1
+ std::streamsize precision_t1 = std::cout.precision(std::numeric_limits<long double>::digits10); // Save & set.
+ long double bracket_min = -4.;
+ long double bracket_max = 4. / 3;
+ const int bits = std::numeric_limits<long double>::digits;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+
+ std::pair<long double, long double> r = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second
+ << ", after " << it << " iterations. " << std::endl;
+ std::cout.precision(precision_t1); // Restore.
+//] [/brent_minimise_template_1]
+ }
+
+ // Show use of built-in type Template versions.
+ // (Will not work if construct bracket min and max from string).
+
+//[brent_minimise_template_fd
+ show_minima<float>();
+ show_minima<double>();
+ show_minima<long double>();
+
+ //] [/brent_minimise_template_fd]
+
+//[brent_minimise_mp_include_1
+#ifdef BOOST_HAVE_QUADMATH // Defined 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
+#ifdef BOOST_HAVE_QUADMATH // Defined 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.
+#endif
+//] [/brent_minimise_template_quad
+
+ // User-defined floating-point template.
+
+//[brent_minimise_mp_typedefs
+ using boost::multiprecision::cpp_bin_float_50; // binary multiprecision typedef.
+ using boost::multiprecision::cpp_dec_float_50; // decimal multiprecision typedef.
+
+ // One might also need typedefs like these to switch expression templates off and on (default is on).
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<50>,
+ boost::multiprecision::et_on>
+ cpp_bin_float_50_et_on; // et_on is default so is same as cpp_bin_float_50.
+
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<50>,
+ boost::multiprecision::et_off>
+ cpp_bin_float_50_et_off;
+
+ typedef boost::multiprecision::number<boost::multiprecision::cpp_dec_float<50>,
+ boost::multiprecision::et_on> // et_on is default so is same as cpp_dec_float_50.
+ cpp_dec_float_50_et_on;
+
+ 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.
+//[brent_minimise_mp_1
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::digits10);
+ int bits = std::numeric_limits<cpp_bin_float_50>::digits / 2 - 2;
+ cpp_bin_float_50 bracket_min = static_cast<cpp_bin_float_50>("-4");
+ cpp_bin_float_50 bracket_max = static_cast<cpp_bin_float_50>("1.3333333333333333333333333333333333333333333333333");
+
+ std::cout << "Bracketing " << bracket_min << " to " << bracket_max << std::endl;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit; // Will be updated with actual iteration count.
+ std::pair<cpp_bin_float_50, cpp_bin_float_50> r
+ = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << "x at minimum = " << r.first << ",\n f(" << r.first << ") = " << r.second
+ // x at minimum = 1, f(1) = 5.04853e-018
+ << ", after " << it << " iterations. " << std::endl;
+
+ is_close_to(static_cast<cpp_bin_float_50>("1"), r.first, sqrt(std::numeric_limits<cpp_bin_float_50>::epsilon()));
+ is_close_to(static_cast<cpp_bin_float_50>("0"), r.second, sqrt(std::numeric_limits<cpp_bin_float_50>::epsilon()));
+
+//] [/brent_minimise_mp_1]
+
+/*
+//[brent_minimise_mp_output_1
+For type class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,1>,
+epsilon = 5.3455294202e-51,
+the maximum theoretical precision from Brent minimization is 7.311312755e-26
+Displaying to std::numeric_limits<T>::digits10 11 significant decimal digits.
+x at minimum = 1, f(1) = 5.6273022713e-58,
+met 84 bits precision, after 14 iterations.
+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
+//] [/brent_minimise_mp_output_1]
+*/
+//[brent_minimise_mp_2
+ 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]
+*/
+ }
+
+ { // binary ET on explicit
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50_et_on>::digits10);
+
+ int bits = std::numeric_limits<cpp_bin_float_50_et_on>::digits / 2 - 2;
+
+ cpp_bin_float_50_et_on bracket_min = static_cast<cpp_bin_float_50_et_on>("-4");
+ cpp_bin_float_50_et_on bracket_max = static_cast<cpp_bin_float_50_et_on>("1.3333333333333333333333333333333333333333333333333");
+
+ std::cout << bracket_min << " " << bracket_max << std::endl;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ std::pair<cpp_bin_float_50_et_on, cpp_bin_float_50_et_on> r = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
+ // x at minimum = 1, f(1) = 5.04853e-018
+ std::cout << it << " iterations. " << std::endl;
+
+ show_minima<cpp_bin_float_50_et_on>(); //
+
+ }
+ return 0;
+
+ // Some examples of switching expression templates on and off follow.
+
+ { // binary ET off
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50_et_off>::digits10);
+
+ int bits = std::numeric_limits<cpp_bin_float_50_et_off>::digits / 2 - 2;
+ cpp_bin_float_50_et_off bracket_min = static_cast<cpp_bin_float_50_et_off>("-4");
+ cpp_bin_float_50_et_off bracket_max = static_cast<cpp_bin_float_50_et_off>("1.3333333333333333333333333333333333333333333333333");
+
+ std::cout << bracket_min << " " << bracket_max << std::endl;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ std::pair<cpp_bin_float_50_et_off, cpp_bin_float_50_et_off> r = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
+ // x at minimum = 1, f(1) = 5.04853e-018
+ std::cout << it << " iterations. " << std::endl;
+
+ show_minima<cpp_bin_float_50_et_off>(); //
+ }
+
+ { // decimal ET on by default
+ std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10);
+
+ int bits = std::numeric_limits<cpp_dec_float_50>::digits / 2 - 2;
+
+ cpp_dec_float_50 bracket_min = static_cast<cpp_dec_float_50>("-4");
+ cpp_dec_float_50 bracket_max = static_cast<cpp_dec_float_50>("1.3333333333333333333333333333333333333333333333333");
+
+ std::cout << bracket_min << " " << bracket_max << std::endl;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ std::pair<cpp_dec_float_50, cpp_dec_float_50> r = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
+ // x at minimum = 1, f(1) = 5.04853e-018
+ std::cout << it << " iterations. " << std::endl;
+
+ show_minima<cpp_dec_float_50>();
+ }
+
+ { // 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;
+
+ cpp_dec_float_50_et_on bracket_min = static_cast<cpp_dec_float_50_et_on>("-4");
+ cpp_dec_float_50_et_on bracket_max = static_cast<cpp_dec_float_50_et_on>("1.3333333333333333333333333333333333333333333333333");
+ std::cout << bracket_min << " " << bracket_max << std::endl;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ std::pair<cpp_dec_float_50_et_on, cpp_dec_float_50_et_on> r = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
+ // x at minimum = 1, f(1) = 5.04853e-018
+ std::cout << it << " iterations. " << std::endl;
+
+ show_minima<cpp_dec_float_50_et_on>();
+
+ }
+
+ { // decimal ET off
+ std::cout.precision(std::numeric_limits<cpp_dec_float_50_et_off>::digits10);
+
+ int bits = std::numeric_limits<cpp_dec_float_50_et_off>::digits / 2 - 2;
+
+ cpp_dec_float_50_et_off bracket_min = static_cast<cpp_dec_float_50_et_off>("-4");
+ cpp_dec_float_50_et_off bracket_max = static_cast<cpp_dec_float_50_et_off>("1.3333333333333333333333333333333333333333333333333");
+
+ std::cout << bracket_min << " " << bracket_max << std::endl;
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ std::pair<cpp_dec_float_50_et_off, cpp_dec_float_50_et_off> r = brent_find_minima(func(), bracket_min, bracket_max, bits, it);
+
+ std::cout << "x at minimum = " << r.first << ", f(" << r.first << ") = " << r.second << std::endl;
+ // x at minimum = 1, f(1) = 5.04853e-018
+ std::cout << it << " iterations. " << std::endl;
+
+ show_minima<cpp_dec_float_50_et_off>();
+ }
+
+ return 0;
+} // int main()
+
+
+/*
+
+Typical output MSVC 15.7.3
+
+brent_minimise_example.cpp
+Generating code
+7 of 2746 functions ( 0.3%) were compiled, the rest were copied from previous compilation.
+0 functions were new in current compilation
+1 functions had inline decision re-evaluated but remain unchanged
+Finished generating code
+brent_minimise_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\brent_minimise_example.exe
+Autorun "J:\Cpp\MathToolkit\test\Math_test\Release\brent_minimise_example.exe"
+Brent's minimisation examples.
+
+
+
+Type double - unlimited iterations (unwise?)
+x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-18
+x at minimum = 1.12344622367552e-09
+Uncertainty sqrt(epsilon) = 1.49011611938477e-08
+x = 1.00000, f(x) = 5.04853e-18
+x == 1 (compared to uncertainty 1.49012e-08) is true
+f(x) == 0 (compared to uncertainty 1.49012e-08) is true
+
+Type double with limited iterations.
+Precision bits = 53
+x at minimum = 1.00000, f(1.00000) = 5.04853e-18 after 10 iterations.
+Showing 53 bits precision with 9 decimal digits from tolerance 1.49011612e-08
+x at minimum = 1.00000000, f(1.00000000) = 5.04852568e-18 after 10 iterations.
+
+Type double with limited iterations and half double bits.
+Showing 26 bits precision with 7 decimal digits from tolerance 0.000172633
+x at minimum = 1.000000, f(1.000000) = 5.048526e-18
+10 iterations.
+
+Type double with limited iterations and quarter double bits.
+Showing 13 bits precision with 5 decimal digits from tolerance 0.0156250
+x at minimum = 0.99998, f(0.99998) = 2.0070e-09, after 7 iterations.
+
+Type long double with limited iterations and all long double bits.
+x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-18, after 10 iterations.
+
+
+For type: float,
+epsilon = 1.1921e-07,
+the maximum theoretical precision from Brent's minimization is 0.00034527
+Displaying to std::numeric_limits<T>::digits10 5, significant decimal digits.
+x at minimum = 1.0002, f(1.0002) = 1.9017e-07,
+met 12 bits precision, after 7 iterations.
+x == 1 (compared to uncertainty 0.00034527) is true
+f(x) == (0 compared to uncertainty 0.00034527) is true
+
+
+For type: double,
+epsilon = 2.220446e-16,
+the maximum theoretical precision from Brent's minimization is 1.490116e-08
+Displaying to std::numeric_limits<T>::digits10 7, significant decimal digits.
+x at minimum = 1.000000, f(1.000000) = 5.048526e-18,
+met 26 bits precision, after 10 iterations.
+x == 1 (compared to uncertainty 1.490116e-08) is true
+f(x) == (0 compared to uncertainty 1.490116e-08) is true
+
+
+For type: long double,
+epsilon = 2.220446e-16,
+the maximum theoretical precision from Brent's minimization is 1.490116e-08
+Displaying to std::numeric_limits<T>::digits10 7, significant decimal digits.
+x at minimum = 1.000000, f(1.000000) = 5.048526e-18,
+met 26 bits precision, after 10 iterations.
+x == 1 (compared to uncertainty 1.490116e-08) is true
+f(x) == (0 compared to uncertainty 1.490116e-08) is true
+Bracketing -4.0000000000000000000000000000000000000000000000000 to 1.3333333333333333333333333333333333333333333333333
+x at minimum = 0.99999999999999999999999999998813903221565569205253,
+f(0.99999999999999999999999999998813903221565569205253) = 5.6273022712501408640665300316078046703496236636624e-58, after 14 iterations.
+
+
+For type: class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,1>,
+epsilon = 5.3455294202e-51,
+the maximum theoretical precision from Brent's minimization is 7.3113127550e-26
+Displaying to std::numeric_limits<T>::digits10 11, significant decimal digits.
+x at minimum = 1.0000000000, f(1.0000000000) = 5.6273022713e-58,
+met 84 bits precision, after 14 iterations.
+x == 1 (compared to uncertainty 7.3113127550e-26) is true
+f(x) == (0 compared to uncertainty 7.3113127550e-26) is true
+-4.0000000000000000000000000000000000000000000000000 1.3333333333333333333333333333333333333333333333333
+x at minimum = 0.99999999999999999999999999998813903221565569205253, f(0.99999999999999999999999999998813903221565569205253) = 5.6273022712501408640665300316078046703496236636624e-58
+14 iterations.
+
+
+For type: class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,1>,
+epsilon = 5.3455294202e-51,
+the maximum theoretical precision from Brent's minimization is 7.3113127550e-26
+Displaying to std::numeric_limits<T>::digits10 11, significant decimal digits.
+x at minimum = 1.0000000000, f(1.0000000000) = 5.6273022713e-58,
+met 84 bits precision, after 14 iterations.
+x == 1 (compared to uncertainty 7.3113127550e-26) is true
+f(x) == (0 compared to uncertainty 7.3113127550e-26) is true
+
+
+============================================================================================================
+
+ // GCC 7.2.0 with quadmath
+
+Brent's minimisation examples.
+
+Type double - unlimited iterations (unwise?)
+x at minimum = 1.00000000112345, f(1.00000000112345) = 5.04852568272458e-018
+x at minimum = 1.12344622367552e-009
+Uncertainty sqrt(epsilon) = 1.49011611938477e-008
+x = 1.00000, f(x) = 5.04853e-018
+x == 1 (compared to uncertainty 1.49012e-008) is true
+f(x) == 0 (compared to uncertainty 1.49012e-008) is true
+
+Type double with limited iterations.
+Precision bits = 53
+x at minimum = 1.00000, f(1.00000) = 5.04853e-018 after 10 iterations.
+Showing 53 bits precision with 9 decimal digits from tolerance 1.49011612e-008
+x at minimum = 1.00000000, f(1.00000000) = 5.04852568e-018 after 10 iterations.
+
+Type double with limited iterations and half double bits.
+Showing 26 bits precision with 7 decimal digits from tolerance 0.000172633
+x at minimum = 1.000000, f(1.000000) = 5.048526e-018
+10 iterations.
+
+Type double with limited iterations and quarter double bits.
+Showing 13 bits precision with 5 decimal digits from tolerance 0.0156250
+x at minimum = 0.99998, f(0.99998) = 2.0070e-009, after 7 iterations.
+
+Type long double with limited iterations and all long double bits.
+x at minimum = 1.00000000000137302, f(1.00000000000137302) = 7.54079013697311930e-024, after 10 iterations.
+
+
+For type: f,
+epsilon = 1.1921e-007,
+the maximum theoretical precision from Brent's minimization is 0.00034527
+Displaying to std::numeric_limits<T>::digits10 5, significant decimal digits.
+x at minimum = 1.0002, f(1.0002) = 1.9017e-007,
+met 12 bits precision, after 7 iterations.
+x == 1 (compared to uncertainty 0.00034527) is true
+f(x) == (0 compared to uncertainty 0.00034527) is true
+
+
+For type: d,
+epsilon = 2.220446e-016,
+the maximum theoretical precision from Brent's minimization is 1.490116e-008
+Displaying to std::numeric_limits<T>::digits10 7, significant decimal digits.
+x at minimum = 1.000000, f(1.000000) = 5.048526e-018,
+met 26 bits precision, after 10 iterations.
+x == 1 (compared to uncertainty 1.490116e-008) is true
+f(x) == (0 compared to uncertainty 1.490116e-008) is true
+
+
+For type: e,
+epsilon = 1.084202e-019,
+the maximum theoretical precision from Brent's minimization is 3.292723e-010
+Displaying to std::numeric_limits<T>::digits10 7, significant decimal digits.
+x at minimum = 1.000000, f(1.000000) = 7.540790e-024,
+met 32 bits precision, after 10 iterations.
+x == 1 (compared to uncertainty 3.292723e-010) is true
+f(x) == (0 compared to uncertainty 3.292723e-010) is true
+
+
+For type: N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE,
+epsilon = 1.92592994e-34,
+the maximum theoretical precision from Brent's minimization is 1.38777878e-17
+Displaying to std::numeric_limits<T>::digits10 9, significant decimal digits.
+x at minimum = 1.00000000, f(1.00000000) = 1.48695468e-43,
+met 56 bits precision, after 12 iterations.
+x == 1 (compared to uncertainty 1.38777878e-17) is true
+f(x) == (0 compared to uncertainty 1.38777878e-17) is true
+Bracketing -4.0000000000000000000000000000000000000000000000000 to 1.3333333333333333333333333333333333333333333333333
+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,
+epsilon = 5.3455294202e-51,
+the maximum theoretical precision from Brent's minimization is 7.3113127550e-26
+Displaying to std::numeric_limits<T>::digits10 11, significant decimal digits.
+x at minimum = 1.0000000000, f(1.0000000000) = 5.6273022713e-58,
+met 84 bits precision, after 14 iterations.
+x == 1 (compared to uncertainty 7.3113127550e-26) is true
+f(x) == (0 compared to uncertainty 7.3113127550e-26) is true
+-4.0000000000000000000000000000000000000000000000000 1.3333333333333333333333333333333333333333333333333
+x at minimum = 0.99999999999999999999999999998813903221565569205253, f(0.99999999999999999999999999998813903221565569205253) = 5.6273022712501408640665300316078046703496236636624e-58
+14 iterations.
+
+
+For type: N5boost14multiprecision6numberINS0_8backends13cpp_bin_floatILj50ELNS2_15digit_base_typeE10EviLi0ELi0EEELNS0_26expression_template_optionE1EEE,
+epsilon = 5.3455294202e-51,
+the maximum theoretical precision from Brent's minimization is 7.3113127550e-26
+Displaying to std::numeric_limits<T>::digits10 11, significant decimal digits.
+x at minimum = 1.0000000000, f(1.0000000000) = 5.6273022713e-58,
+met 84 bits precision, after 14 iterations.
+x == 1 (compared to uncertainty 7.3113127550e-26) is true
+f(x) == (0 compared to uncertainty 7.3113127550e-26) is true
+
+*/
diff --git a/src/boost/libs/math/example/c_error_policy_example.cpp b/src/boost/libs/math/example/c_error_policy_example.cpp
new file mode 100644
index 000000000..73ae024b0
--- /dev/null
+++ b/src/boost/libs/math/example/c_error_policy_example.cpp
@@ -0,0 +1,83 @@
+// C_error_policy_example.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+// Copyright John Maddock 2007.
+
+// 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)
+
+// Suppose we want a call to tgamma to behave in a C-compatible way
+// and set global ::errno rather than throw an exception.
+
+#include <cerrno> // for ::errno
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma;
+
+using boost::math::policies::policy;
+// Possible errors
+using boost::math::policies::overflow_error;
+using boost::math::policies::underflow_error;
+using boost::math::policies::domain_error;
+using boost::math::policies::pole_error;
+using boost::math::policies::denorm_error;
+using boost::math::policies::evaluation_error;
+
+using boost::math::policies::errno_on_error;
+using boost::math::policies::ignore_error;
+
+//using namespace boost::math::policies;
+//using namespace boost::math; // avoid potential ambiguity with std:: <random>
+
+// Define a policy:
+typedef policy<
+ domain_error<errno_on_error>, // 'bad' arguments.
+ pole_error<errno_on_error>, // argument is pole value.
+ overflow_error<errno_on_error>, // argument value causes overflow.
+ evaluation_error<errno_on_error> // evaluation does not converge and may be inaccurate, or worse,
+ // or there is no way known (yet) to implement this evaluation,
+ // for example, kurtosis of non-central beta distribution.
+ > C_error_policy;
+
+// std
+#include <iostream>
+ using std::cout;
+ using std::endl;
+
+int main()
+{
+ // We can achieve this at the function call site
+ // with the previously defined policy C_error_policy.
+ double t = tgamma(4., C_error_policy());
+ cout << "tgamma(4., C_error_policy() = " << t << endl; // 6
+
+ // Alternatively we could use the function make_policy,
+ // provided for convenience,
+ // and define everything at the call site:
+ t = tgamma(4., make_policy(
+ domain_error<errno_on_error>(),
+ pole_error<errno_on_error>(),
+ overflow_error<errno_on_error>(),
+ evaluation_error<errno_on_error>()
+ ));
+ cout << "tgamma(4., make_policy(...) = " << t << endl; // 6
+
+ return 0;
+} // int main()
+
+/*
+
+Output
+
+ c_error_policy_example.cpp
+ Generating code
+ Finished generating code
+ c_error_policy_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\c_error_policy_example.exe
+ tgamma(4., C_error_policy() = 6
+ tgamma(4., make_policy(...) = 6
+ tgamma(4., C_error_policy() = 6
+ tgamma(4., make_policy(...) = 6
+
+*/
diff --git a/src/boost/libs/math/example/cardinal_cubic_b_spline_example.cpp b/src/boost/libs/math/example/cardinal_cubic_b_spline_example.cpp
new file mode 100644
index 000000000..3a709f449
--- /dev/null
+++ b/src/boost/libs/math/example/cardinal_cubic_b_spline_example.cpp
@@ -0,0 +1,147 @@
+// Copyright Nicholas Thompson 2017.
+// Copyright Paul A. Bristow 2017.
+// Copyright John Maddock 2017.
+
+// 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).
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+#include <cmath>
+#include <random>
+#include <cstdint>
+#include <boost/random/uniform_real_distribution.hpp>
+#include <boost/math/tools/roots.hpp>
+
+//[cubic_b_spline_example
+
+/*`This example demonstrates how to use the cubic b spline interpolator for regularly spaced data.
+*/
+#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
+
+int main()
+{
+ // We begin with an array of samples:
+ std::vector<double> v(500);
+ // And decide on a stepsize:
+ double step = 0.01;
+
+ // Initialize the vector with a function we'd like to interpolate:
+ for (size_t i = 0; i < v.size(); ++i)
+ {
+ v[i] = sin(i*step);
+ }
+ // We could define an arbitrary start time, but for now we'll just use 0:
+ boost::math::interpolators::cardinal_cubic_b_spline<double> spline(v.data(), v.size(), 0 /* start time */, step);
+
+ // Now we can evaluate the spline wherever we please.
+ std::mt19937 gen;
+ boost::random::uniform_real_distribution<double> absissa(0, v.size()*step);
+ for (size_t i = 0; i < 10; ++i)
+ {
+ double x = absissa(gen);
+ std::cout << "sin(" << x << ") = " << sin(x) << ", spline interpolation gives " << spline(x) << std::endl;
+ std::cout << "cos(" << x << ") = " << cos(x) << ", spline derivative interpolation gives " << spline.prime(x) << std::endl;
+ }
+
+ // The next example is less trivial:
+ // We will try to figure out when the population of the United States crossed 100 million.
+ // Since the census is taken every 10 years, the data is equally spaced, so we can use the cubic b spline.
+ // Data taken from https://en.wikipedia.org/wiki/United_States_Census
+ // We'll start at the year 1860:
+ double t0 = 1860;
+ double time_step = 10;
+ std::vector<double> population{31443321, /* 1860 */
+ 39818449, /* 1870 */
+ 50189209, /* 1880 */
+ 62947714, /* 1890 */
+ 76212168, /* 1900 */
+ 92228496, /* 1910 */
+ 106021537, /* 1920 */
+ 122775046, /* 1930 */
+ 132164569, /* 1940 */
+ 150697361, /* 1950 */
+ 179323175};/* 1960 */
+
+ // An eyeball estimate indicates that the population crossed 100 million around 1915.
+ // Let's see what interpolation says:
+ boost::math::interpolators::cardinal_cubic_b_spline<double> p(population.data(), population.size(), t0, time_step);
+
+ // Now create a function which has a zero at p = 100,000,000:
+ auto f = [=](double t){ return p(t) - 100000000; };
+
+ // Boost includes a bisection algorithm, which is robust, though not as fast as some others
+ // we provide, but let's try that first. We need a termination condition for it, which
+ // takes the two endpoints of the range and returns either true (stop) or false (keep going),
+ // we could use a predefined one such as boost::math::tools::eps_tolerance<double>, but that
+ // won't stop until we have full double precision which is overkill, since we just need the
+ // endpoint to yield the same month. While we're at it, we'll keep track of the number of
+ // iterations required too, though this is strictly optional:
+
+ auto termination = [](double left, double right)
+ {
+ double left_month = std::round((left - std::floor(left)) * 12 + 1);
+ double right_month = std::round((right - std::floor(right)) * 12 + 1);
+ return (left_month == right_month) && (std::floor(left) == std::floor(right));
+ };
+ std::uintmax_t iterations = 1000;
+ auto result = boost::math::tools::bisect(f, 1910.0, 1920.0, termination, iterations);
+ auto time = result.first; // termination condition ensures that both endpoints yield the same result
+ auto month = std::round((time - std::floor(time))*12 + 1);
+ auto year = std::floor(time);
+ std::cout << "The population of the United States surpassed 100 million on the ";
+ std::cout << month << "th month of " << year << std::endl;
+ std::cout << "Found in " << iterations << " iterations" << std::endl;
+
+ // Since the cubic B spline offers the first derivative, we could equally have used Newton iterations,
+ // this takes "number of bits correct" as a termination condition - 20 should be plenty for what we need,
+ // and once again, we track how many iterations are taken:
+
+ auto f_n = [=](double t) { return std::make_pair(p(t) - 100000000, p.prime(t)); };
+ iterations = 1000;
+ time = boost::math::tools::newton_raphson_iterate(f_n, 1910.0, 1900.0, 2000.0, 20, iterations);
+ month = std::round((time - std::floor(time))*12 + 1);
+ year = std::floor(time);
+ std::cout << "The population of the United States surpassed 100 million on the ";
+ std::cout << month << "th month of " << year << std::endl;
+ std::cout << "Found in " << iterations << " iterations" << std::endl;
+
+}
+
+//] [/cubic_b_spline_example]
+
+//[cubic_b_spline_example_out
+/*` Program output is:
+[pre
+sin(4.07362) = -0.802829, spline interpolation gives - 0.802829
+cos(4.07362) = -0.596209, spline derivative interpolation gives - 0.596209
+sin(0.677385) = 0.626758, spline interpolation gives 0.626758
+cos(0.677385) = 0.779214, spline derivative interpolation gives 0.779214
+sin(4.52896) = -0.983224, spline interpolation gives - 0.983224
+cos(4.52896) = -0.182402, spline derivative interpolation gives - 0.182402
+sin(4.17504) = -0.85907, spline interpolation gives - 0.85907
+cos(4.17504) = -0.511858, spline derivative interpolation gives - 0.511858
+sin(0.634934) = 0.593124, spline interpolation gives 0.593124
+cos(0.634934) = 0.805111, spline derivative interpolation gives 0.805111
+sin(4.84434) = -0.991307, spline interpolation gives - 0.991307
+cos(4.84434) = 0.131567, spline derivative interpolation gives 0.131567
+sin(4.56688) = -0.989432, spline interpolation gives - 0.989432
+cos(4.56688) = -0.144997, spline derivative interpolation gives - 0.144997
+sin(1.10517) = 0.893541, spline interpolation gives 0.893541
+cos(1.10517) = 0.448982, spline derivative interpolation gives 0.448982
+sin(3.1618) = -0.0202022, spline interpolation gives - 0.0202022
+cos(3.1618) = -0.999796, spline derivative interpolation gives - 0.999796
+sin(1.54084) = 0.999551, spline interpolation gives 0.999551
+cos(1.54084) = 0.0299566, spline derivative interpolation gives 0.0299566
+The population of the United States surpassed 100 million on the 11th month of 1915
+Found in 12 iterations
+The population of the United States surpassed 100 million on the 11th month of 1915
+Found in 3 iterations
+]
+*/
+//]
diff --git a/src/boost/libs/math/example/catmull_rom_example.cpp b/src/boost/libs/math/example/catmull_rom_example.cpp
new file mode 100644
index 000000000..69a497070
--- /dev/null
+++ b/src/boost/libs/math/example/catmull_rom_example.cpp
@@ -0,0 +1,45 @@
+// Copyright Nick Thompson, 2017
+
+// 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).
+
+#include <iostream>
+#include <vector>
+#include <array>
+#include <cmath>
+#include <boost/math/interpolators/catmull_rom.hpp>
+#include <boost/math/constants/constants.hpp>
+
+using std::sin;
+using std::cos;
+using boost::math::catmull_rom;
+
+int main()
+{
+ std::cout << "This shows how to use Boost's Catmull-Rom spline to create an Archimedean spiral.\n";
+
+ // The Archimedean spiral is given by r = a*theta. We have set a = 1.
+ std::vector<std::array<double, 2>> spiral_points(500);
+ double theta_max = boost::math::constants::pi<double>();
+ for (size_t i = 0; i < spiral_points.size(); ++i)
+ {
+ double theta = ((double) i/ (double) spiral_points.size())*theta_max;
+ spiral_points[i] = {theta*cos(theta), theta*sin(theta)};
+ }
+
+ auto archimedean = catmull_rom<std::array<double,2>>(std::move(spiral_points));
+ double max_s = archimedean.max_parameter();
+ std::cout << "Max s = " << max_s << std::endl;
+ for (double s = 0; s < max_s; s += 0.01)
+ {
+ auto p = archimedean(s);
+ double x = p[0];
+ double y = p[1];
+ double r = sqrt(x*x + y*y);
+ double theta = atan2(y/r, x/r);
+ std::cout << "r = " << r << ", theta = " << theta << ", r - theta = " << r - theta << std::endl;
+ }
+
+ return 0;
+}
diff --git a/src/boost/libs/math/example/chi_square_std_dev_test.cpp b/src/boost/libs/math/example/chi_square_std_dev_test.cpp
new file mode 100644
index 000000000..9743240bd
--- /dev/null
+++ b/src/boost/libs/math/example/chi_square_std_dev_test.cpp
@@ -0,0 +1,555 @@
+// Copyright John Maddock 2006, 2007
+// Copyright Paul A. Bristow 2010
+
+// 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)
+
+#include <iostream>
+using std::cout; using std::endl;
+using std::left; using std::fixed; using std::right; using std::scientific;
+#include <iomanip>
+using std::setw;
+using std::setprecision;
+
+#include <boost/math/distributions/chi_squared.hpp>
+
+int error_result = 0;
+
+void confidence_limits_on_std_deviation(
+ double Sd, // Sample Standard Deviation
+ unsigned N) // Sample size
+{
+ // Calculate confidence intervals for the standard deviation.
+ // For example if we set the confidence limit to
+ // 0.95, we know that if we repeat the sampling
+ // 100 times, then we expect that the true standard deviation
+ // will be between out limits on 95 occasions.
+ // Note: this is not the same as saying a 95%
+ // confidence interval means that there is a 95%
+ // probability that the interval contains the true standard deviation.
+ // The interval computed from a given sample either
+ // contains the true standard deviation or it does not.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda358.htm
+
+ // using namespace boost::math; // potential name ambiguity with std <random>
+ using boost::math::chi_squared;
+ using boost::math::quantile;
+ using boost::math::complement;
+
+ // Print out general info:
+ cout <<
+ "________________________________________________\n"
+ "2-Sided Confidence Limits For Standard Deviation\n"
+ "________________________________________________\n\n";
+ cout << setprecision(7);
+ cout << setw(40) << left << "Number of Observations" << "= " << N << "\n";
+ cout << setw(40) << left << "Standard Deviation" << "= " << Sd << "\n";
+ //
+ // Define a table of significance/risk levels:
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+ //
+ // Start by declaring the distribution we'll need:
+ chi_squared dist(N - 1);
+ //
+ // Print table header:
+ //
+ cout << "\n\n"
+ "_____________________________________________\n"
+ "Confidence Lower Upper\n"
+ " Value (%) Limit Limit\n"
+ "_____________________________________________\n";
+ //
+ // Now print out the data for the table rows.
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // Calculate limits:
+ double lower_limit = sqrt((N - 1) * Sd * Sd / quantile(complement(dist, alpha[i] / 2)));
+ double upper_limit = sqrt((N - 1) * Sd * Sd / quantile(dist, alpha[i] / 2));
+ // Print Limits:
+ cout << fixed << setprecision(5) << setw(15) << right << lower_limit;
+ cout << fixed << setprecision(5) << setw(15) << right << upper_limit << endl;
+ }
+ cout << endl;
+} // void confidence_limits_on_std_deviation
+
+void confidence_limits_on_std_deviation_alpha(
+ double Sd, // Sample Standard Deviation
+ double alpha // confidence
+ )
+{ // Calculate confidence intervals for the standard deviation.
+ // for the alpha parameter, for a range number of observations,
+ // from a mere 2 up to a million.
+ // O. L. Davies, Statistical Methods in Research and Production, ISBN 0 05 002437 X,
+ // 4.33 Page 68, Table H, pp 452 459.
+
+ // using namespace std;
+ // using namespace boost::math;
+ using boost::math::chi_squared;
+ using boost::math::quantile;
+ using boost::math::complement;
+
+ // Define a table of numbers of observations:
+ unsigned int obs[] = {2, 3, 4, 5, 6, 7, 8, 9, 10, 15, 20, 30, 40 , 50, 60, 100, 120, 1000, 10000, 50000, 100000, 1000000};
+
+ cout << // Print out heading:
+ "________________________________________________\n"
+ "2-Sided Confidence Limits For Standard Deviation\n"
+ "________________________________________________\n\n";
+ cout << setprecision(7);
+ cout << setw(40) << left << "Confidence level (two-sided) " << "= " << alpha << "\n";
+ cout << setw(40) << left << "Standard Deviation" << "= " << Sd << "\n";
+
+ cout << "\n\n" // Print table header:
+ "_____________________________________________\n"
+ "Observations Lower Upper\n"
+ " Limit Limit\n"
+ "_____________________________________________\n";
+ for(unsigned i = 0; i < sizeof(obs)/sizeof(obs[0]); ++i)
+ {
+ unsigned int N = obs[i]; // Observations
+ // Start by declaring the distribution with the appropriate :
+ chi_squared dist(N - 1);
+
+ // Now print out the data for the table row.
+ cout << fixed << setprecision(3) << setw(10) << right << N;
+ // Calculate limits: (alpha /2 because it is a two-sided (upper and lower limit) test.
+ double lower_limit = sqrt((N - 1) * Sd * Sd / quantile(complement(dist, alpha / 2)));
+ double upper_limit = sqrt((N - 1) * Sd * Sd / quantile(dist, alpha / 2));
+ // Print Limits:
+ cout << fixed << setprecision(4) << setw(15) << right << lower_limit;
+ cout << fixed << setprecision(4) << setw(15) << right << upper_limit << endl;
+ }
+ cout << endl;
+}// void confidence_limits_on_std_deviation_alpha
+
+void chi_squared_test(
+ double Sd, // Sample std deviation
+ double D, // True std deviation
+ unsigned N, // Sample size
+ double alpha) // Significance level
+{
+ //
+ // A Chi Squared test applied to a single set of data.
+ // We are testing the null hypothesis that the true
+ // standard deviation of the sample is D, and that any variation is down
+ // to chance. We can also test the alternative hypothesis
+ // that any difference is not down to chance.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda358.htm
+ //
+ // using namespace boost::math;
+ using boost::math::chi_squared;
+ using boost::math::quantile;
+ using boost::math::complement;
+ using boost::math::cdf;
+
+ // Print header:
+ cout <<
+ "______________________________________________\n"
+ "Chi Squared test for sample standard deviation\n"
+ "______________________________________________\n\n";
+ cout << setprecision(5);
+ cout << setw(55) << left << "Number of Observations" << "= " << N << "\n";
+ cout << setw(55) << left << "Sample Standard Deviation" << "= " << Sd << "\n";
+ cout << setw(55) << left << "Expected True Standard Deviation" << "= " << D << "\n\n";
+ //
+ // Now we can calculate and output some stats:
+ //
+ // test-statistic:
+ double t_stat = (N - 1) * (Sd / D) * (Sd / D);
+ cout << setw(55) << left << "Test Statistic" << "= " << t_stat << "\n";
+ //
+ // Finally define our distribution, and get the probability:
+ //
+ chi_squared dist(N - 1);
+ double p = cdf(dist, t_stat);
+ cout << setw(55) << left << "CDF of test statistic: " << "= "
+ << setprecision(3) << scientific << p << "\n";
+ double ucv = quantile(complement(dist, alpha));
+ double ucv2 = quantile(complement(dist, alpha / 2));
+ double lcv = quantile(dist, alpha);
+ double lcv2 = quantile(dist, alpha / 2);
+ cout << setw(55) << left << "Upper Critical Value at alpha: " << "= "
+ << setprecision(3) << scientific << ucv << "\n";
+ cout << setw(55) << left << "Upper Critical Value at alpha/2: " << "= "
+ << setprecision(3) << scientific << ucv2 << "\n";
+ cout << setw(55) << left << "Lower Critical Value at alpha: " << "= "
+ << setprecision(3) << scientific << lcv << "\n";
+ cout << setw(55) << left << "Lower Critical Value at alpha/2: " << "= "
+ << setprecision(3) << scientific << lcv2 << "\n\n";
+ //
+ // Finally print out results of alternative hypothesis:
+ //
+ cout << setw(55) << left <<
+ "Results for Alternative Hypothesis and alpha" << "= "
+ << setprecision(4) << fixed << alpha << "\n\n";
+ cout << "Alternative Hypothesis Conclusion\n";
+ cout << "Standard Deviation != " << setprecision(3) << fixed << D << " ";
+ if((ucv2 < t_stat) || (lcv2 > t_stat))
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Standard Deviation < " << setprecision(3) << fixed << D << " ";
+ if(lcv > t_stat)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Standard Deviation > " << setprecision(3) << fixed << D << " ";
+ if(ucv < t_stat)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << endl << endl;
+} // void chi_squared_test
+
+void chi_squared_sample_sized(
+ double diff, // difference from variance to detect
+ double variance) // true variance
+{
+ using namespace std;
+ // using boost::math;
+ using boost::math::chi_squared;
+ using boost::math::quantile;
+ using boost::math::complement;
+ using boost::math::cdf;
+
+ try
+ {
+ cout << // Print out general info:
+ "_____________________________________________________________\n"
+ "Estimated sample sizes required for various confidence levels\n"
+ "_____________________________________________________________\n\n";
+ cout << setprecision(5);
+ cout << setw(40) << left << "True Variance" << "= " << variance << "\n";
+ cout << setw(40) << left << "Difference to detect" << "= " << diff << "\n";
+ //
+ // Define a table of significance levels:
+ //
+ double alpha[] = { 0.5, 0.33333333333333333333333, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+ //
+ // Print table header:
+ //
+ cout << "\n\n"
+ "_______________________________________________________________\n"
+ "Confidence Estimated Estimated\n"
+ " Value (%) Sample Size Sample Size\n"
+ " (lower one- (upper one-\n"
+ " sided test) sided test)\n"
+ "_______________________________________________________________\n";
+ //
+ // Now print out the data for the table rows.
+ //
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // Calculate df for a lower single-sided test:
+ double df = chi_squared::find_degrees_of_freedom(
+ -diff, alpha[i], alpha[i], variance);
+ // Convert to integral sample size (df is a floating point value in this implementation):
+ double size = ceil(df) + 1;
+ // Print size:
+ cout << fixed << setprecision(0) << setw(16) << right << size;
+ // Calculate df for an upper single-sided test:
+ df = chi_squared::find_degrees_of_freedom(
+ diff, alpha[i], alpha[i], variance);
+ // Convert to integral sample size:
+ size = ceil(df) + 1;
+ // Print size:
+ cout << fixed << setprecision(0) << setw(16) << right << size << endl;
+ }
+ cout << endl;
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ ++error_result;
+ }
+} // chi_squared_sample_sized
+
+int main()
+{
+ // Run tests for Gear data
+ // see http://www.itl.nist.gov/div898/handbook/eda/section3/eda3581.htm
+ // Tests measurements of gear diameter.
+ //
+ confidence_limits_on_std_deviation(0.6278908E-02, 100);
+ chi_squared_test(0.6278908E-02, 0.1, 100, 0.05);
+ chi_squared_sample_sized(0.1 - 0.6278908E-02, 0.1);
+ //
+ // Run tests for silicon wafer fabrication data.
+ // see http://www.itl.nist.gov/div898/handbook/prc/section2/prc23.htm
+ // A supplier of 100 ohm.cm silicon wafers claims that his fabrication
+ // process can produce wafers with sufficient consistency so that the
+ // standard deviation of resistivity for the lot does not exceed
+ // 10 ohm.cm. A sample of N = 10 wafers taken from the lot has a
+ // standard deviation of 13.97 ohm.cm
+ //
+ confidence_limits_on_std_deviation(13.97, 10);
+ chi_squared_test(13.97, 10.0, 10, 0.05);
+ chi_squared_sample_sized(13.97 * 13.97 - 100, 100);
+ chi_squared_sample_sized(55, 100);
+ chi_squared_sample_sized(1, 100);
+
+ // List confidence interval multipliers for standard deviation
+ // for a range of numbers of observations from 2 to a million,
+ // and for a few alpha values, 0.1, 0.05, 0.01 for confidences 90, 95, 99 %
+ confidence_limits_on_std_deviation_alpha(1., 0.1);
+ confidence_limits_on_std_deviation_alpha(1., 0.05);
+ confidence_limits_on_std_deviation_alpha(1., 0.01);
+
+ return error_result;
+}
+
+/*
+
+________________________________________________
+2-Sided Confidence Limits For Standard Deviation
+________________________________________________
+Number of Observations = 100
+Standard Deviation = 0.006278908
+_____________________________________________
+Confidence Lower Upper
+ Value (%) Limit Limit
+_____________________________________________
+ 50.000 0.00601 0.00662
+ 75.000 0.00582 0.00685
+ 90.000 0.00563 0.00712
+ 95.000 0.00551 0.00729
+ 99.000 0.00530 0.00766
+ 99.900 0.00507 0.00812
+ 99.990 0.00489 0.00855
+ 99.999 0.00474 0.00895
+______________________________________________
+Chi Squared test for sample standard deviation
+______________________________________________
+Number of Observations = 100
+Sample Standard Deviation = 0.00628
+Expected True Standard Deviation = 0.10000
+Test Statistic = 0.39030
+CDF of test statistic: = 1.438e-099
+Upper Critical Value at alpha: = 1.232e+002
+Upper Critical Value at alpha/2: = 1.284e+002
+Lower Critical Value at alpha: = 7.705e+001
+Lower Critical Value at alpha/2: = 7.336e+001
+Results for Alternative Hypothesis and alpha = 0.0500
+Alternative Hypothesis Conclusion
+Standard Deviation != 0.100 NOT REJECTED
+Standard Deviation < 0.100 NOT REJECTED
+Standard Deviation > 0.100 REJECTED
+_____________________________________________________________
+Estimated sample sizes required for various confidence levels
+_____________________________________________________________
+True Variance = 0.10000
+Difference to detect = 0.09372
+_______________________________________________________________
+Confidence Estimated Estimated
+ Value (%) Sample Size Sample Size
+ (lower one- (upper one-
+ sided test) sided test)
+_______________________________________________________________
+ 50.000 2 2
+ 66.667 2 5
+ 75.000 2 10
+ 90.000 4 32
+ 95.000 5 52
+ 99.000 8 102
+ 99.900 13 178
+ 99.990 18 257
+ 99.999 23 337
+________________________________________________
+2-Sided Confidence Limits For Standard Deviation
+________________________________________________
+Number of Observations = 10
+Standard Deviation = 13.9700000
+_____________________________________________
+Confidence Lower Upper
+ Value (%) Limit Limit
+_____________________________________________
+ 50.000 12.41880 17.25579
+ 75.000 11.23084 19.74131
+ 90.000 10.18898 22.98341
+ 95.000 9.60906 25.50377
+ 99.000 8.62898 31.81825
+ 99.900 7.69466 42.51593
+ 99.990 7.04085 55.93352
+ 99.999 6.54517 73.00132
+______________________________________________
+Chi Squared test for sample standard deviation
+______________________________________________
+Number of Observations = 10
+Sample Standard Deviation = 13.97000
+Expected True Standard Deviation = 10.00000
+Test Statistic = 17.56448
+CDF of test statistic: = 9.594e-001
+Upper Critical Value at alpha: = 1.692e+001
+Upper Critical Value at alpha/2: = 1.902e+001
+Lower Critical Value at alpha: = 3.325e+000
+Lower Critical Value at alpha/2: = 2.700e+000
+Results for Alternative Hypothesis and alpha = 0.0500
+Alternative Hypothesis Conclusion
+Standard Deviation != 10.000 REJECTED
+Standard Deviation < 10.000 REJECTED
+Standard Deviation > 10.000 NOT REJECTED
+_____________________________________________________________
+Estimated sample sizes required for various confidence levels
+_____________________________________________________________
+True Variance = 100.00000
+Difference to detect = 95.16090
+_______________________________________________________________
+Confidence Estimated Estimated
+ Value (%) Sample Size Sample Size
+ (lower one- (upper one-
+ sided test) sided test)
+_______________________________________________________________
+ 50.000 2 2
+ 66.667 2 5
+ 75.000 2 10
+ 90.000 4 32
+ 95.000 5 51
+ 99.000 7 99
+ 99.900 11 174
+ 99.990 15 251
+ 99.999 20 330
+_____________________________________________________________
+Estimated sample sizes required for various confidence levels
+_____________________________________________________________
+True Variance = 100.00000
+Difference to detect = 55.00000
+_______________________________________________________________
+Confidence Estimated Estimated
+ Value (%) Sample Size Sample Size
+ (lower one- (upper one-
+ sided test) sided test)
+_______________________________________________________________
+ 50.000 2 2
+ 66.667 4 10
+ 75.000 8 21
+ 90.000 23 71
+ 95.000 36 115
+ 99.000 71 228
+ 99.900 123 401
+ 99.990 177 580
+ 99.999 232 762
+_____________________________________________________________
+Estimated sample sizes required for various confidence levels
+_____________________________________________________________
+True Variance = 100.00000
+Difference to detect = 1.00000
+_______________________________________________________________
+Confidence Estimated Estimated
+ Value (%) Sample Size Sample Size
+ (lower one- (upper one-
+ sided test) sided test)
+_______________________________________________________________
+ 50.000 2 2
+ 66.667 14696 14993
+ 75.000 36033 36761
+ 90.000 130079 132707
+ 95.000 214283 218612
+ 99.000 428628 437287
+ 99.900 756333 771612
+ 99.990 1095435 1117564
+ 99.999 1440608 1469711
+________________________________________________
+2-Sided Confidence Limits For Standard Deviation
+________________________________________________
+Confidence level (two-sided) = 0.1000000
+Standard Deviation = 1.0000000
+_____________________________________________
+Observations Lower Upper
+ Limit Limit
+_____________________________________________
+ 2 0.5102 15.9472
+ 3 0.5778 4.4154
+ 4 0.6196 2.9200
+ 5 0.6493 2.3724
+ 6 0.6720 2.0893
+ 7 0.6903 1.9154
+ 8 0.7054 1.7972
+ 9 0.7183 1.7110
+ 10 0.7293 1.6452
+ 15 0.7688 1.4597
+ 20 0.7939 1.3704
+ 30 0.8255 1.2797
+ 40 0.8454 1.2320
+ 50 0.8594 1.2017
+ 60 0.8701 1.1805
+ 100 0.8963 1.1336
+ 120 0.9045 1.1203
+ 1000 0.9646 1.0383
+ 10000 0.9885 1.0118
+ 50000 0.9948 1.0052
+ 100000 0.9963 1.0037
+ 1000000 0.9988 1.0012
+________________________________________________
+2-Sided Confidence Limits For Standard Deviation
+________________________________________________
+Confidence level (two-sided) = 0.0500000
+Standard Deviation = 1.0000000
+_____________________________________________
+Observations Lower Upper
+ Limit Limit
+_____________________________________________
+ 2 0.4461 31.9102
+ 3 0.5207 6.2847
+ 4 0.5665 3.7285
+ 5 0.5991 2.8736
+ 6 0.6242 2.4526
+ 7 0.6444 2.2021
+ 8 0.6612 2.0353
+ 9 0.6755 1.9158
+ 10 0.6878 1.8256
+ 15 0.7321 1.5771
+ 20 0.7605 1.4606
+ 30 0.7964 1.3443
+ 40 0.8192 1.2840
+ 50 0.8353 1.2461
+ 60 0.8476 1.2197
+ 100 0.8780 1.1617
+ 120 0.8875 1.1454
+ 1000 0.9580 1.0459
+ 10000 0.9863 1.0141
+ 50000 0.9938 1.0062
+ 100000 0.9956 1.0044
+ 1000000 0.9986 1.0014
+________________________________________________
+2-Sided Confidence Limits For Standard Deviation
+________________________________________________
+Confidence level (two-sided) = 0.0100000
+Standard Deviation = 1.0000000
+_____________________________________________
+Observations Lower Upper
+ Limit Limit
+_____________________________________________
+ 2 0.3562 159.5759
+ 3 0.4344 14.1244
+ 4 0.4834 6.4675
+ 5 0.5188 4.3960
+ 6 0.5464 3.4848
+ 7 0.5688 2.9798
+ 8 0.5875 2.6601
+ 9 0.6036 2.4394
+ 10 0.6177 2.2776
+ 15 0.6686 1.8536
+ 20 0.7018 1.6662
+ 30 0.7444 1.4867
+ 40 0.7718 1.3966
+ 50 0.7914 1.3410
+ 60 0.8065 1.3026
+ 100 0.8440 1.2200
+ 120 0.8558 1.1973
+ 1000 0.9453 1.0609
+ 10000 0.9821 1.0185
+ 50000 0.9919 1.0082
+ 100000 0.9943 1.0058
+ 1000000 0.9982 1.0018
+*/
+
diff --git a/src/boost/libs/math/example/constants_eg1.cpp b/src/boost/libs/math/example/constants_eg1.cpp
new file mode 100644
index 000000000..53516145e
--- /dev/null
+++ b/src/boost/libs/math/example/constants_eg1.cpp
@@ -0,0 +1,192 @@
+// Copyright Paul Bristow 2013.
+// Copyright John Maddock 2010.
+
+// 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)
+
+/*! \brief Examples of using the enhanced math constants.
+ \details This allows for access to constants via functions like @c pi(),
+ and also via namespaces, @c using @c namespace boost::math::double_constants;
+ called simply @c pi.
+*/
+
+#include <boost/math/constants/constants.hpp>
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include <limits>
+using std::numeric_limits;
+
+/*! \brief Examples of a template function using constants.
+ \details This example shows using of constants from function calls like @c pi(),
+ rather than the 'cute' plain @c pi use in non-template applications.
+
+ \tparam Real radius parameter that can be a built-in like float, double,
+ or a user-defined type like multiprecision.
+ \returns Area = pi * radius ^ 2
+*/
+
+//[math_constants_eg1
+template<class Real>
+Real area(Real r)
+{
+ using namespace boost::math::constants;
+
+ return pi<Real>() * r * r;
+}
+//] [/math_constants_eg1]
+
+int main()
+{
+
+ { // Boost.Math constants using function calls like pi().
+ // using namespace boost::math::constants;
+
+ using boost::math::constants::pi;
+ using boost::math::constants::one_div_two_pi;
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ std::size_t max_digits10 = 2 + std::numeric_limits<double>::digits * 3010/10000;
+#else
+ std::size_t max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+
+ std::cout.precision(max_digits10);
+ cout << "double pi = boost::math::double_constants::pi = " << pi<double>() << endl;
+ // double pi = boost::math::double_constants::pi = 3.1415926535897931
+ double r = 1.234567890123456789;
+ double d = pi<double>() * r * r;
+
+ cout << "d = " << d << ", r = " << r << endl;
+
+ float rf = 0.987654321987654321f;
+
+ float pif = boost::math::constants::pi<float>();
+ cout << "pidf = boost::math::constants::pi() = " << pif << endl;
+ // pidf = boost::math::float_constants::pi = 3.1415927410125732
+
+ //float df = pi * rf * rf; // conversion from 'const double' to 'float', possible loss of data.
+ float df = pif * rf * rf;
+
+ cout << "df = " << df << ", rf = " << rf << endl;
+
+ cout << "one_div_two_pi " << one_div_two_pi<double>() << endl;
+
+ using boost::math::constants::one_div_two_pi;
+
+ cout << "one_div_root_two_pi " << one_div_two_pi<double>() << endl;
+ }
+
+ { // Boost math new constants using namespace selected values, like pi.
+
+ //using namespace boost::math::float_constants;
+ using namespace boost::math::double_constants;
+
+ double my2pi = two_pi; // Uses boost::math::double_constants::two_pi;
+
+ cout << "double my2pi = " << my2pi << endl;
+
+ using boost::math::float_constants::e;
+ float my_e = e;
+ cout << "float my_e " << my_e << endl;
+
+ double my_pi = boost::math::double_constants::pi;
+ cout << "double my_pi = boost::math::double_constants::pi = " << my_pi << endl;
+
+ // If you try to use two namespaces, this may, of course, create ambiguity:
+ // it is not too difficult to do this inadvertently.
+ using namespace boost::math::float_constants;
+ //cout << pi << endl; // error C2872: 'pi' : ambiguous symbol.
+
+ }
+ {
+
+//[math_constants_ambiguity
+ // If you use more than one namespace, this will, of course, create ambiguity:
+ using namespace boost::math::double_constants;
+ using namespace boost::math::constants;
+
+ //double my_pi = pi(); // error C2872: 'pi' : ambiguous symbol
+ //double my_pi2 = pi; // Context does not allow for disambiguation of overloaded function
+
+ // It is also possible to create ambiguity inadvertently,
+ // perhaps in other peoples code,
+ // by making the scope of a namespace declaration wider than necessary,
+ // therefore is it prudent to avoid this risk by localising the scope of such definitions.
+//] [/math_constants_ambiguity]
+
+ }
+
+ { // You can, of course, use both methods of access if both are fully qualified, for examples:
+
+ //cout.precision(std::numeric_limits<double>::max_digits10);// Ideally.
+ cout.precision(2 + std::numeric_limits<double>::digits * 3010/10000); // If no max_digits10.
+
+ double my_pi1 = boost::math::constants::pi<double>();
+ double my_pid = boost::math::double_constants::pi;
+ cout << "boost::math::constants::pi<double>() = " << my_pi1 << endl
+ << "boost::math::double_constants::pi = " << my_pid << endl;
+
+ // cout.precision(std::numeric_limits<float>::max_digits10); // Ideally.
+ cout.precision(2 + std::numeric_limits<double>::digits * 3010/10000); // If no max_digits10.
+ float my_pif = boost::math::float_constants::pi;
+ cout << "boost::math::float_constants::pi = " << my_pif << endl;
+
+ }
+
+ { // Use with templates
+
+ // \warning it is important to be very careful with the type provided as parameter.
+ // For example, naively providing an @b integer instead of a floating-point type can be disastrous.
+ // cout << "Area = " << area(2) << endl; // warning : 'return' : conversion from 'double' to 'int', possible loss of data
+ // Failure to heed this warning can lead to very wrong answers!
+ // Area = 12 !! = 3 * 2 * 2
+//[math_constants_template_integer_type
+ //cout << "Area = " << area(2) << endl; // Area = 12!
+ cout << "Area = " << area(2.) << endl; // Area = 12.566371
+
+ // You can also avoid this by being explicit about the type of @c area.
+ cout << "Area = " << area<double>(2) << endl;
+
+//] [/math_constants_template_integer_type]
+
+
+ }
+/*
+{
+ using boost::math::constants::pi;
+ //double my_pi3 = pi<double>(); // OK
+ //double my_pi4 = pi<>(); cannot find template type.
+ //double my_pi4 = pi(); // Can't find a function.
+
+ }
+*/
+
+} // int main()
+
+/*[constants_eq1_output
+
+Output:
+
+ double pi = boost::math::double_constants::pi = 3.1415926535897931
+ d = 4.7882831840285398, r = 1.2345678901234567
+ pidf = boost::math::constants::pi() = 3.1415927410125732
+ df = 3.0645015239715576, rf = 0.98765432834625244
+ one_div_two_pi 0.15915494309189535
+ one_div_root_two_pi 0.15915494309189535
+ double my2pi = 6.2831853071795862
+ float my_e 2.7182817459106445
+ double my_pi = boost::math::double_constants::pi = 3.1415926535897931
+ boost::math::constants::pi<double>() = 3.1415926535897931
+ boost::math::double_constants::pi = 3.1415926535897931
+ boost::math::float_constants::pi = 3.1415927410125732
+ Area = 12.566370614359172
+ Area = 12.566370614359172
+
+
+] [/constants_eq1_output]
+*/
diff --git a/src/boost/libs/math/example/continued_fractions.cpp b/src/boost/libs/math/example/continued_fractions.cpp
new file mode 100644
index 000000000..23f479fc9
--- /dev/null
+++ b/src/boost/libs/math/example/continued_fractions.cpp
@@ -0,0 +1,150 @@
+// (C) Copyright John Maddock 2018.
+// 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)
+
+#include <boost/math/tools/fraction.hpp>
+#include <iostream>
+#include <complex>
+#include <boost/multiprecision/cpp_complex.hpp>
+
+//[golden_ratio_1
+template <class T>
+struct golden_ratio_fraction
+{
+ typedef T result_type;
+
+ result_type operator()()
+ {
+ return 1;
+ }
+};
+//]
+
+//[cf_tan_fraction
+template <class T>
+struct tan_fraction
+{
+private:
+ T a, b;
+public:
+ tan_fraction(T v)
+ : a(-v * v), b(-1)
+ {}
+
+ typedef std::pair<T, T> result_type;
+
+ std::pair<T, T> operator()()
+ {
+ b += 2;
+ return std::make_pair(a, b);
+ }
+};
+//]
+//[cf_tan
+template <class T>
+T tan(T a)
+{
+ tan_fraction<T> fract(a);
+ return a / continued_fraction_b(fract, std::numeric_limits<T>::epsilon());
+}
+//]
+//[cf_expint_fraction
+template <class T>
+struct expint_fraction
+{
+ typedef std::pair<T, T> result_type;
+ expint_fraction(unsigned n_, T z_) : b(z_ + T(n_)), i(-1), n(n_) {}
+ std::pair<T, T> operator()()
+ {
+ std::pair<T, T> result = std::make_pair(-static_cast<T>((i + 1) * (n + i)), b);
+ b += 2;
+ ++i;
+ return result;
+ }
+private:
+ T b;
+ int i;
+ unsigned n;
+};
+//]
+//[cf_expint
+template <class T>
+inline std::complex<T> expint_as_fraction(unsigned n, std::complex<T> const& z)
+{
+ boost::uintmax_t max_iter = 1000;
+ expint_fraction<std::complex<T> > f(n, z);
+ std::complex<T> result = boost::math::tools::continued_fraction_b(
+ f,
+ std::complex<T>(std::numeric_limits<T>::epsilon()),
+ max_iter);
+ result = exp(-z) / result;
+ return result;
+}
+//]
+//[cf_upper_gamma_fraction
+template <class T>
+struct upper_incomplete_gamma_fract
+{
+private:
+ typedef typename T::value_type scalar_type;
+ T z, a;
+ int k;
+public:
+ typedef std::pair<T, T> result_type;
+
+ upper_incomplete_gamma_fract(T a1, T z1)
+ : z(z1 - a1 + scalar_type(1)), a(a1), k(0)
+ {
+ }
+
+ result_type operator()()
+ {
+ ++k;
+ z += scalar_type(2);
+ return result_type(scalar_type(k) * (a - scalar_type(k)), z);
+ }
+};
+//]
+//[cf_gamma_Q
+template <class T>
+inline std::complex<T> gamma_Q_as_fraction(const std::complex<T>& a, const std::complex<T>& z)
+{
+ upper_incomplete_gamma_fract<std::complex<T> > f(a, z);
+ std::complex<T> eps(std::numeric_limits<T>::epsilon());
+ return pow(z, a) / (exp(z) *(z - a + T(1) + boost::math::tools::continued_fraction_a(f, eps)));
+}
+//]
+inline boost::multiprecision::cpp_complex_50 gamma_Q_as_fraction(const boost::multiprecision::cpp_complex_50& a, const boost::multiprecision::cpp_complex_50& z)
+{
+ upper_incomplete_gamma_fract<boost::multiprecision::cpp_complex_50> f(a, z);
+ boost::multiprecision::cpp_complex_50 eps(std::numeric_limits<boost::multiprecision::cpp_complex_50::value_type>::epsilon());
+ return pow(z, a) / (exp(z) * (z - a + 1 + boost::math::tools::continued_fraction_a(f, eps)));
+}
+
+
+int main()
+{
+ using namespace boost::math::tools;
+
+ //[cf_gr
+ golden_ratio_fraction<double> func;
+ double gr = continued_fraction_a(
+ func,
+ std::numeric_limits<double>::epsilon());
+ std::cout << "The golden ratio is: " << gr << std::endl;
+ //]
+
+ std::cout << tan(0.5) << std::endl;
+
+ std::complex<double> arg(3, 2);
+ std::cout << expint_as_fraction(5, arg) << std::endl;
+
+ std::complex<double> a(3, 3), z(3, 2);
+ std::cout << gamma_Q_as_fraction(a, z) << std::endl;
+
+ boost::multiprecision::cpp_complex_50 am(3, 3), zm(3, 2);
+ std::cout << gamma_Q_as_fraction(am, zm) << std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/math/example/cstdfloat_example.cpp b/src/boost/libs/math/example/cstdfloat_example.cpp
new file mode 100644
index 000000000..761e811b1
--- /dev/null
+++ b/src/boost/libs/math/example/cstdfloat_example.cpp
@@ -0,0 +1,488 @@
+// Copyright John Maddock 2014
+// Copyright Christopher Kormanyos 2014.
+// Copyright Paul A. Bristow 2016.
+
+// 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)
+
+// Contains Quickbook snippets as C++ comments - do not remove.
+
+/*
+`This example shows use of a specified-width floating-point typedef
+to evaluate a moderately complex math function using
+[@http://en.wikipedia.org/wiki/Double-precision_floating-point_format IEEE754 64-bit double-precision].
+about 15 decimal digits `std::numeric_limits<boost::float64_t>::digits10`,
+(but never exceeding 17 decimal digits `std::numeric_limits<boost::float64_t>::max_digits10`).
+
+The Jahnke-Emden lambda function is described at
+
+Weisstein, Eric W. "Lambda Function." From MathWorld--A Wolfram Web Resource.
+http://mathworld.wolfram.com/LambdaFunction.html
+
+E. Jahnke and F. Emden, "Tables of Functions with Formulae and Curves,"
+Dover, New York, 4th ed., (1945), pages 180-188.
+
+*/
+
+//[cstdfloat_example_1
+#include <boost/cstdfloat.hpp> // For float_64_t, float128_t. Must be first include!
+#include <cmath> // for pow function.
+#include <boost/math/special_functions.hpp> // For gamma function.
+//] [/cstdfloat_example_1]
+#include <boost/type_traits/is_same.hpp>
+
+#include <iostream>
+
+/*!
+Function max_digits10
+Returns maximum number of possibly significant decimal digits for a floating-point type FPT,
+even for older compilers/standard libraries that
+lack support for std::numeric_limits<FPT>::max_digits10,
+when the Kahan formula 2 + binary_digits * 0.3010 is used instead.
+Also provides the correct result for Visual Studio 2010
+(where the value 8 provided for float is wrong).
+*/
+namespace boost
+{
+template <typename FPT>
+const int max_digits10()
+{
+// Since max_digits10 is not defined (or wrong) on older systems, define a local max_digits10.
+ // Usage: int m = max_digits10<boost::float64_t>();
+ const int m =
+#if (defined BOOST_NO_CXX11_NUMERIC_LIMITS) || (_MSC_VER == 1600) // is wrongly 8 not 9 for VS2010.
+ 2 + std::numeric_limits<FPT>::digits * 3010/10000;
+#else
+ std::numeric_limits<FPT>::max_digits10;
+#endif
+ return m;
+}
+} // namespace boost
+
+//`Define the Jahnke-Emden_lambda function.
+//[cstdfloat_example_2
+boost::float64_t jahnke_emden_lambda(boost::float64_t v, boost::float64_t x)
+{
+ const boost::float64_t gamma_v_plus_one = boost::math::tgamma(v + 1);
+ const boost::float64_t x_half_pow_v = std::pow(x /2, v);
+
+ return gamma_v_plus_one * boost::math::cyl_bessel_j(x, v) / x_half_pow_v;
+}
+//] [/cstdfloat_example_2]
+
+int main()
+{
+ std::cout.setf(std::ios::showpoint); // show all significant trailing zeros.
+
+ long double p = 1.L;
+ //std::cout.precision(std::numeric_limits<long double>::digits10);
+
+ std::cout << "pi = " << p << std::endl;
+
+//[cstdfloat_example_3
+//`Ensure that all possibly significant digits (17) including trailing zeros are shown.
+
+ std::cout.precision(std::numeric_limits<boost::float64_t>::max_digits10);
+ std::cout.setf(std::ios::showpoint); // Show trailing zeros.
+
+ try
+ { // Always use try'n'catch blocks to ensure any error messages are displayed.
+
+ // Evaluate and display an evaluation of the Jahnke-Emden lambda function:
+ boost::float64_t v = 1.;
+ boost::float64_t x = 1.;
+ std::cout << jahnke_emden_lambda(v, x) << std::endl; // 0.88010117148986700
+//] [/cstdfloat_example_3]
+
+ // We can show some evaluations with various precisions:
+ { // float64_t
+ for (int i = 0; i < 10; i++)
+ {
+ std::cout << std::setprecision(2) << boost::float64_t(i) << ' '
+ << std::setprecision(std::numeric_limits<boost::float64_t>::max_digits10)
+ << jahnke_emden_lambda(boost::float64_t(i), v) << std::endl; //
+ }
+ }
+ { // floatmax_t = the maximum available on this platform.
+ for (int i = 0; i < 10; i++)
+ {
+ std::cout << std::setprecision(2) << boost::floatmax_t(i) << ' '
+ << std::setprecision(std::numeric_limits<boost::floatmax_t>::max_digits10)
+ << jahnke_emden_lambda(boost::floatmax_t(i), v) << std::endl; //
+ }
+ }
+ // Show the precision of long double (this might be 64, 80 or 128 bits).
+ std::cout << "Floating-point type long double is available with:" << std::endl;
+ std::cout << " std::numeric_limits<long double>::digits10 == "
+ << std::numeric_limits<long double>::digits10 << std::endl; // 18
+ std::cout << " std::numeric_limits<long double>::max_digits10 == "
+ << std::numeric_limits<long double>::max_digits10 << std::endl; // 21
+ long double p = boost::math::constants::pi<double>();
+ std::cout.precision(std::numeric_limits<long double>::digits10);
+ std::cout << "pi = " << p << std::endl;
+
+//[cstdfloat_constant_2
+//`These allow floating-point [*constants of at least the specified width] to be declared:
+
+ // Declare Archimedes' constant using float32_t with approximately 7 decimal digits of precision.
+ static const boost::float32_t pi = BOOST_FLOAT32_C(3.1415926536);
+
+ // Declare the Euler-gamma constant with approximately 15 decimal digits of precision.
+ static const boost::float64_t euler =
+ BOOST_FLOAT64_C(0.57721566490153286060651209008240243104216);
+
+ // Declare the Golden Ratio constant with the maximum decimal digits of precision that the platform supports.
+ static const boost::floatmax_t golden_ratio =
+ BOOST_FLOATMAX_C(1.61803398874989484820458683436563811772);
+//] [/cstdfloat_constant_2]
+
+// http://www.boost.org/doc/libs/1_55_0/libs/multiprecision/doc/html/boost_multiprecision/tut/floats/float128.html
+//[cstdfloat_constant_1
+// Display the constant pi to the maximum available precision.
+ boost::floatmax_t pi_max = boost::math::constants::pi<boost::floatmax_t>();
+ std::cout.precision(std::numeric_limits<boost::floatmax_t>::digits10);
+ std::cout << "Most precise pi = " << pi_max << std::endl;
+// If floatmax_t is float_128_t, then
+// Most precise pi = 3.141592653589793238462643383279503
+//] [/cstdfloat_constant_1]
+
+// Test all the floating-point precisions in turn, and if they are available
+// then display how many decimal digits of precision.
+#ifdef BOOST_FLOAT16_C
+ std::cout << "Floating-point type boost::float16_t is available." << std::endl;
+#else
+ std::cout << "Floating-point type boost::float16_t is NOT available." << std::endl;
+#endif
+
+#ifdef BOOST_FLOAT32_C
+ std::cout << "Floating-point type boost::float32_t is available." << std::endl;
+ std::cout << " std::numeric_limits<boost::float32_t>::digits10 == "
+ << std::numeric_limits<boost::float32_t>::digits10 << std::endl;
+ std::cout << " std::numeric_limits<boost::float32_t>::max_digits10 == "
+ << std::numeric_limits<boost::float32_t>::max_digits10 << std::endl;
+#else
+ std::cout << "Floating-point type boost::float32_t is NOT available." << std::endl;
+#endif
+
+#ifdef BOOST_FLOAT64_C
+ std::cout << "Floating-point type boost::float64_t is available." << std::endl;
+ std::cout << " std::numeric_limits<boost::float64_t>::digits10 == "
+ << std::numeric_limits<boost::float64_t>::digits10 << std::endl;
+ std::cout << " std::numeric_limits<boost::float64_t>::max_digits10 == "
+ << std::numeric_limits<boost::float64_t>::max_digits10 << std::endl;
+#else
+ std::cout << "Floating-point type boost::float64_t is NOT available." << std::endl;
+#endif
+
+#ifdef BOOST_FLOAT80_C
+ std::cout << "Floating-point type boost::float80_t is available." << std::endl;
+ std::cout << " std::numeric_limits<boost::float80_t>::digits10 == "
+ << std::numeric_limits<boost::float80_t>::digits10 << std::endl;
+ std::cout << " std::numeric_limits<boost::float80_t>::max_digits10 == "
+ << std::numeric_limits<boost::float80_t>::max_digits10 << std::endl;
+#else
+ std::cout << "Floating-point type boost::float80_t is NOT available." << std::endl;
+#endif
+
+#ifdef BOOST_FLOAT128_C
+ std::cout << "Floating-point type boost::float128_t is available." << std::endl;
+ std::cout << " std::numeric_limits<boost::float128_t>::digits10 == "
+ << std::numeric_limits<boost::float128_t>::digits10 << std::endl;
+ std::cout << " std::numeric_limits<boost::float128_t>::max_digits10 == "
+ << std::numeric_limits<boost::float128_t>::max_digits10 << std::endl;
+#else
+ std::cout << "Floating-point type boost::float128_t is NOT available." << std::endl;
+#endif
+
+// Show some constants at a precision depending on the available type(s).
+#ifdef BOOST_FLOAT16_C
+ std::cout.precision(boost::max_digits10<boost::float16_t>()); // Show all significant decimal digits,
+ std::cout.setf(std::ios::showpoint); // including all significant trailing zeros.
+
+ std::cout << "BOOST_FLOAT16_C(123.456789012345678901234567890) = "
+ << BOOST_FLOAT16_C(123.456789012345678901234567890) << std::endl;
+ // BOOST_FLOAT16_C(123.456789012345678901234567890) = 123.45678901234568
+#endif
+
+//[floatmax_widths_1
+#ifdef BOOST_FLOAT32_C
+ std::cout.precision(boost::max_digits10<boost::float32_t>()); // Show all significant decimal digits,
+ std::cout.setf(std::ios::showpoint); // including all significant trailing zeros.
+ std::cout << "BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) = "
+ << BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) << std::endl;
+ // BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) = 123.456787
+#endif
+//] [/floatmax_widths_1]
+
+#ifdef BOOST_FLOAT64_C
+ std::cout.precision(boost::max_digits10<boost::float64_t>()); // Show all significant decimal digits,
+ std::cout.setf(std::ios::showpoint); // including all significant trailing zeros.
+ std::cout << "BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) = "
+ << BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) << std::endl;
+ // BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) = 123.45678901234568
+#endif
+
+#ifdef BOOST_FLOAT80_C
+ std::cout.precision(boost::max_digits10<boost::float80_t>()); // Show all significant decimal digits,
+ std::cout.setf(std::ios::showpoint); // including all significant trailing zeros.
+ std::cout << "BOOST_FLOAT80_C(123.4567890123456789012345678901234567890) = "
+ << BOOST_FLOAT80_C(123.4567890123456789012345678901234567890) << std::endl;
+ // BOOST_FLOAT80_C(123.4567890123456789012345678901234567890) = 123.456789012345678903
+#endif
+
+#ifdef BOOST_FLOAT128_C
+ std::cout.precision(boost::max_digits10<boost::float128_t>()); // Show all significant decimal digits,
+ std::cout.setf(std::ios::showpoint); // including all significant trailing zeros.
+ std::cout << "BOOST_FLOAT128_C(123.4567890123456789012345678901234567890) = "
+ << BOOST_FLOAT128_C(123.4567890123456789012345678901234567890) << std::endl;
+ // BOOST_FLOAT128_C(123.4567890123456789012345678901234567890) = 123.456789012345678901234567890123453
+#endif
+
+/*
+//[floatmax_widths_2
+BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) = 123.456787
+BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) = 123.45678901234568
+BOOST_FLOAT80_C(123.4567890123456789012345678901234567890) = 123.456789012345678903
+BOOST_FLOAT128_C(123.4567890123456789012345678901234567890) = 123.456789012345678901234567890123453
+//] [/floatmax_widths_2]
+*/
+
+// Display the precisions available for floatmax_t
+
+#ifdef BOOST_FLOATMAX_C
+ BOOST_ASSERT(std::numeric_limits<boost::floatmax_t>::is_specialized == true);
+ BOOST_ASSERT(std::numeric_limits<boost::floatmax_t>::is_iec559 == true);
+ BOOST_ASSERT(BOOST_FLOATMAX_C(0.) == 0);
+
+ std::cout << "floatmax_t " << std::numeric_limits<boost::floatmax_t>::digits << " bits\n" // 113
+ << std::numeric_limits<boost::floatmax_t>::digits10 << " decimal digits\n" // 34
+ << std::numeric_limits<boost::floatmax_t>::max_digits10 << " max_digits\n" // 36
+ << std::numeric_limits<boost::floatmax_t>::radix << " radix\n"
+ << std::endl;
+
+ int significand_bits = std::numeric_limits<boost::floatmax_t>::digits;
+ int exponent_max = std::numeric_limits<boost::floatmax_t>::max_exponent;
+ int exponent_min = std::numeric_limits<boost::floatmax_t>::min_exponent;
+ int exponent_bits = 1 + static_cast<int>(std::log2(std::numeric_limits<boost::floatmax_t>::max_exponent));
+ int sign_bits = std::numeric_limits<boost::floatmax_t>::is_signed;
+
+ std::cout << "significand_bits (including one implicit bit)" << significand_bits
+ << ", exponent_bits " << exponent_bits
+ << ", sign_bits " << sign_bits << std::endl;
+
+ // One can compute the total number of bits in the floatmax_t,
+ // but probably not at compile time.
+
+ std::cout << "bits = " << significand_bits + exponent_bits + sign_bits -1 << std::endl;
+ // -1 to take account of the implicit bit that is not part of the physical layout.
+
+ // One can compare typedefs (but, of course, only those that are defined for the platform in use.)
+ std::cout.setf(std::ios::boolalpha);
+ std::cout << "double, double: " << std::is_same<double, double>::value << std::endl;
+ bool b = boost::is_same<boost::floatmax_t, boost::float64_t>::value;
+ std::cout << "boost::is_same<boost::floatmax_t, boost::float64_t>::value; " << b << std::endl;
+ std::cout << "floatmax_t, float64_t: "
+ << std::is_same<boost::floatmax_t, boost::float64_t>::value << std::endl;
+
+/*`So the simplest way of obtaining the total number of bits in the floatmax_t
+is to infer it from the std::numeric_limits<>::digits value.
+This is possible because the type, must be a IEEE754 layout. */
+//[floatmax_1
+ const int fpbits =
+ (std::numeric_limits<boost::floatmax_t>::digits == 113) ? 128 :
+ (std::numeric_limits<boost::floatmax_t>::digits == 64) ? 80 :
+ (std::numeric_limits<boost::floatmax_t>::digits == 53) ? 64 :
+ (std::numeric_limits<boost::floatmax_t>::digits == 24) ? 32 :
+ (std::numeric_limits<boost::floatmax_t>::digits == 11) ? 16 :
+ 0; // Unknown - not IEEE754 format.
+ std::cout << fpbits << " bits." << std::endl;
+//] [/floatmax_1]
+#endif
+
+ }
+ catch (std::exception ex)
+ { // Display details about why any exceptions are thrown.
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+
+} // int main()
+
+/*
+[cstdfloat_output
+
+GCC 4.8.1 with quadmath
+
+ pi = 1.00000
+ 0.88010117148986700
+ 0.0 0.0000000000000000
+ 1.0 0.88010117148986700
+ 2.0 4.6137984620549872
+ 3.0 16.274830009244951
+ 4.0 -25.360637961042869
+ 5.0 -1257.9038883512264
+ 6.0 -12749.592182518225
+ 7.0 -3020.9830849309437
+ 8.0 2421897.6013183584
+ 9.0 45577595.449204877
+ 0.0 0.00000000000000000000000000000000000
+ 1.0 0.880101171489866995756301548681221902
+ 2.0 4.61379846205498722611082484945654869
+ 3.0 16.2748300092449511566883302293717861
+ 4.0 -25.3606379610428689375112298876047134
+ 5.0 -1257.90388835122644195507746189832687
+ 6.0 -12749.5921825182249449426308274269104
+ 7.0 -3020.98308493094373261556029319763184
+ 8.0 2421897.60131835844367742538452148438
+ 9.0 45577595.4492048770189285278320312500
+ Floating-point type long double is available with:
+ std::numeric_limits<long double>::digits10 == 18
+ std::numeric_limits<long double>::max_digits10 == 21
+ pi = 3.14159265358979312
+ Most precise pi = 3.141592653589793238462643383279503
+ Floating-point type boost::float16_t is NOT available.
+ Floating-point type boost::float32_t is available.
+ std::numeric_limits<boost::float32_t>::digits10 == 6
+ std::numeric_limits<boost::float32_t>::max_digits10 == 9
+ Floating-point type boost::float64_t is available.
+ std::numeric_limits<boost::float64_t>::digits10 == 15
+ std::numeric_limits<boost::float64_t>::max_digits10 == 17
+ Floating-point type boost::float80_t is available.
+ std::numeric_limits<boost::float80_t>::digits10 == 18
+ std::numeric_limits<boost::float80_t>::max_digits10 == 21
+ Floating-point type boost::float128_t is available.
+ std::numeric_limits<boost::float128_t>::digits10 == 34
+ std::numeric_limits<boost::float128_t>::max_digits10 == 36
+ BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) = 123.456787
+ BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) = 123.45678901234568
+ BOOST_FLOAT80_C(123.4567890123456789012345678901234567890) = 123.456789012345678903
+ BOOST_FLOAT128_C(123.4567890123456789012345678901234567890) = 123.456789012345678901234567890123453
+ floatmax_t 113 bits
+ 34 decimal digits
+ 36 max_digits
+ 2 radix
+
+ significand_bits (including one implicit bit)113, exponent_bits 15, sign_bits 1
+ bits = 128
+ double, double: true
+ boost::is_same<boost::floatmax_t, boost::float64_t>::value; false
+ floatmax_t, float64_t: false
+ 128 bits.
+
+ RUN SUCCESSFUL (total time: 53ms)
+
+GCC 6.1.1
+
+pi = 1.00000
+0.88010117148986700
+0.0 0.0000000000000000
+1.0 0.88010117148986700
+2.0 4.6137984620549872
+3.0 16.274830009244951
+4.0 -25.360637961042869
+5.0 -1257.9038883512264
+6.0 -12749.592182518225
+7.0 -3020.9830849309437
+8.0 2421897.6013183584
+9.0 45577595.449204877
+0.0 0.00000000000000000000000000000000000
+1.0 0.880101171489866995756301548681221902
+2.0 4.61379846205498722611082484945654869
+3.0 16.2748300092449511566883302293717861
+4.0 -25.3606379610428689375112298876047134
+5.0 -1257.90388835122644195507746189832687
+6.0 -12749.5921825182249449426308274269104
+7.0 -3020.98308493094373261556029319763184
+8.0 2421897.60131835844367742538452148438
+9.0 45577595.4492048770189285278320312500
+Floating-point type long double is available with:
+ std::numeric_limits<long double>::digits10 == 18
+ std::numeric_limits<long double>::max_digits10 == 21
+pi = 3.14159265358979312
+Most precise pi = 3.14159265358979323846264338327950
+Floating-point type boost::float16_t is NOT available.
+Floating-point type boost::float32_t is available.
+ std::numeric_limits<boost::float32_t>::digits10 == 6
+ std::numeric_limits<boost::float32_t>::max_digits10 == 9
+Floating-point type boost::float64_t is available.
+ std::numeric_limits<boost::float64_t>::digits10 == 15
+ std::numeric_limits<boost::float64_t>::max_digits10 == 17
+Floating-point type boost::float80_t is available.
+ std::numeric_limits<boost::float80_t>::digits10 == 18
+ std::numeric_limits<boost::float80_t>::max_digits10 == 21
+Floating-point type boost::float128_t is available.
+ std::numeric_limits<boost::float128_t>::digits10 == 33
+ std::numeric_limits<boost::float128_t>::max_digits10 == 36
+BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) = 123.456787
+BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) = 123.45678901234568
+BOOST_FLOAT80_C(123.4567890123456789012345678901234567890) = 123.456789012345678903
+BOOST_FLOAT128_C(123.4567890123456789012345678901234567890) = 123.456789012345678901234567890123453
+floatmax_t 113 bits
+33 decimal digits
+36 max_digits
+2 radix
+
+significand_bits (including one implicit bit)113, exponent_bits 15, sign_bits 1
+bits = 128
+double, double: true
+boost::is_same<boost::floatmax_t, boost::float64_t>::value; false
+floatmax_t, float64_t: false
+128 bits.
+
+
+ MSVC 2013 64-bit
+
+ 1> pi = 1.00000
+ 1> 0.88010117148986700
+ 1> 0.00 0.00000000000000000
+ 1> 1.0 0.88010117148986700
+ 1> 2.0 4.6137984620549854
+ 1> 3.0 16.274830009244948
+ 1> 4.0 -25.360637961042869
+ 1> 5.0 -1257.9038883512258
+ 1> 6.0 -12749.592182518225
+ 1> 7.0 -3020.9830849309396
+ 1> 8.0 2421897.6013183575
+ 1> 9.0 45577595.449204892
+ 1> 0.00 0.00000000000000000
+ 1> 1.0 0.88010117148986700
+ 1> 2.0 4.6137984620549854
+ 1> 3.0 16.274830009244948
+ 1> 4.0 -25.360637961042869
+ 1> 5.0 -1257.9038883512258
+ 1> 6.0 -12749.592182518225
+ 1> 7.0 -3020.9830849309396
+ 1> 8.0 2421897.6013183575
+ 1> 9.0 45577595.449204892
+ 1> Floating-point type long double is available with:
+ 1> std::numeric_limits<long double>::digits10 == 15
+ 1> std::numeric_limits<long double>::max_digits10 == 17
+ 1> pi = 3.14159265358979
+ 1> Most precise pi = 3.14159265358979
+ 1> Floating-point type boost::float16_t is NOT available.
+ 1> Floating-point type boost::float32_t is available.
+ 1> std::numeric_limits<boost::float32_t>::digits10 == 6
+ 1> std::numeric_limits<boost::float32_t>::max_digits10 == 9
+ 1> Floating-point type boost::float64_t is available.
+ 1> std::numeric_limits<boost::float64_t>::digits10 == 15
+ 1> std::numeric_limits<boost::float64_t>::max_digits10 == 17
+ 1> Floating-point type boost::float80_t is NOT available.
+ 1> Floating-point type boost::float128_t is NOT available.
+ 1> BOOST_FLOAT32_C(123.4567890123456789012345678901234567890) = 123.456787
+ 1> BOOST_FLOAT64_C(123.4567890123456789012345678901234567890) = 123.45678901234568
+ 1> floatmax_t 53 bits
+ 1> 15 decimal digits
+ 1> 17 max_digits
+ 1> 2 radix
+ 1>
+ 1> significand_bits (including one implicit bit)53, exponent_bits 11, sign_bits 1
+ 1> bits = 64
+ 1> double, double: true
+ 1> boost::is_same<boost::floatmax_t, boost::float64_t>::value; true
+ 1> floatmax_t, float64_t: true
+ 1> 64 bits.
+] [/cstdfloat_output]
+
+
+*/
+
diff --git a/src/boost/libs/math/example/daubechies_wavelets/bench.cpp b/src/boost/libs/math/example/daubechies_wavelets/bench.cpp
new file mode 100644
index 000000000..db2846130
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/bench.cpp
@@ -0,0 +1,489 @@
+/*
+ * Copyright Nick Thompson, 2020
+ * 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)
+ */
+
+#include <cmath>
+#include <random>
+#include <benchmark/benchmark.h>
+#include <boost/random/uniform_real_distribution.hpp>
+#include <boost/math/special_functions/daubechies_scaling.hpp>
+#include <boost/math/interpolators/cubic_hermite.hpp>
+#include <boost/math/interpolators/detail/quintic_hermite_detail.hpp>
+#include <boost/math/interpolators/detail/septic_hermite_detail.hpp>
+
+double exponential(benchmark::IterationCount j)
+{
+ return std::pow(2, j);
+}
+
+
+template<typename Real, int p>
+void DyadicGrid(benchmark::State & state)
+{
+ int j = state.range(0);
+ size_t s = 0;
+ for (auto _ : state)
+ {
+ auto v = boost::math::daubechies_scaling_dyadic_grid<Real, 4, 0>(j);
+ benchmark::DoNotOptimize(v[0]);
+ s = v.size();
+ }
+
+ state.counters["RAM"] = s*sizeof(Real);
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(DyadicGrid, double, 4)->DenseRange(3, 22, 1)->Unit(benchmark::kMillisecond)->Complexity(exponential);
+//BENCHMARK_TEMPLATE(DyadicGrid, double, 8)->DenseRange(3, 22, 1)->Unit(benchmark::kMillisecond)->Complexity(exponential);
+//BENCHMARK_TEMPLATE(DyadicGrid, double, 11)->DenseRange(3,22,1)->Unit(benchmark::kMillisecond)->Complexity(exponential);
+
+uint64_t s[2] = { 0x41, 0x29837592 };
+
+static inline uint64_t rotl(const uint64_t x, int k) {
+ return (x << k) | (x >> (64 - k));
+}
+
+uint64_t next(void) {
+ const uint64_t s0 = s[0];
+ uint64_t s1 = s[1];
+ const uint64_t result = s0 + s1;
+
+ s1 ^= s0;
+ s[0] = rotl(s0, 55) ^ s1 ^ (s1 << 14); // a, b
+ s[1] = rotl(s1, 36); // c
+
+ return result;
+}
+
+double uniform() {
+ return next()*(1.0/18446744073709551616.0);
+}
+
+template<typename Real, int p>
+void ScalingEvaluation(benchmark::State & state)
+{
+ auto phi = boost::math::daubechies_scaling<Real, p>();
+ Real xmax = phi.support().second;
+ Real x = 0;
+ Real step = uniform()/2048;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(phi(x));
+ x += step;
+ if (x > xmax) {
+ x = 0;
+ step = uniform()/2048;
+ }
+ }
+}
+
+
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 2);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 3);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 4);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 5);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 6);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 7);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 8);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 9);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 10);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 11);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 12);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 13);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 14);
+BENCHMARK_TEMPLATE(ScalingEvaluation, double, 15);
+
+
+template<typename Real, int p>
+void ScalingConstructor(benchmark::State & state)
+{
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(boost::math::daubechies_scaling<Real, p>());
+ }
+}
+
+BENCHMARK_TEMPLATE(ScalingConstructor, float, 2)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, double, 2)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, long double, 2)->Unit(benchmark::kMillisecond);
+
+BENCHMARK_TEMPLATE(ScalingConstructor, float, 3)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, double, 3)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, long double, 3)->Unit(benchmark::kMillisecond);
+
+BENCHMARK_TEMPLATE(ScalingConstructor, float, 4)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, double, 4)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, long double, 4)->Unit(benchmark::kMillisecond);
+
+BENCHMARK_TEMPLATE(ScalingConstructor, float, 5)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, double, 5)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, long double, 5)->Unit(benchmark::kMillisecond);
+
+BENCHMARK_TEMPLATE(ScalingConstructor, float, 11)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, double, 11)->Unit(benchmark::kMillisecond);
+BENCHMARK_TEMPLATE(ScalingConstructor, long double, 11)->Unit(benchmark::kMillisecond);
+
+template<typename Real>
+void CubicHermite(benchmark::State & state)
+{
+ using boost::math::interpolators::cubic_hermite;
+ auto n = state.range(0);
+ std::vector<Real> x(n);
+ std::vector<Real> y(n);
+ std::vector<Real> dydx(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ x[0] = dis(rd);
+ y[0] = dis(rd);
+ dydx[0] = dis(rd);
+ for (size_t i = 1; i < y.size(); ++i)
+ {
+ x[i] = x[i-1] + dis(rd);
+ y[i] = dis(rd);
+ dydx[i] = dis(rd);
+ }
+ Real x0 = x.front();
+ Real xf = x.back();
+
+ auto qh = cubic_hermite(std::move(x), std::move(y), std::move(dydx));
+ Real t = x0;
+ Real step = uniform()*(xf-x0)/2048;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(qh(t));
+ t += step;
+ if (t >= xf)
+ {
+ t = x0;
+ step = uniform()*(xf-x0)/2048;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(CubicHermite, double)->RangeMultiplier(2)->Range(1<<8, 1<<20)->Complexity(benchmark::oLogN);
+
+template<typename Real>
+void CardinalCubicHermite(benchmark::State & state)
+{
+ using boost::math::interpolators::detail::cardinal_cubic_hermite_detail;
+ auto n = state.range(0);
+ std::vector<Real> y(n);
+ std::vector<Real> dydx(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ for (size_t i = 0; i < y.size(); ++i)
+ {
+ y[i] = uniform();
+ dydx[i] = uniform();
+ }
+
+ Real dx = Real(1)/Real(8);
+ Real x0 = 0;
+ Real xf = x0 + (y.size()-1)*dx;
+
+ auto qh = cardinal_cubic_hermite_detail(std::move(y), std::move(dydx), x0, dx);
+ Real x = x0;
+ Real step = uniform()*(xf-x0)/2048;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(qh.unchecked_evaluation(x));
+ x += step;
+ if (x >= xf)
+ {
+ x = x0;
+ step = uniform()*(xf-x0)/2048;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+template<typename Real>
+void CardinalCubicHermiteAOS(benchmark::State & state)
+{
+ auto n = state.range(0);
+ std::vector<std::array<Real, 2>> dat(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ for (size_t i = 0; i < dat.size(); ++i)
+ {
+ dat[i][0] = uniform();
+ dat[i][1] = uniform();
+ }
+
+ using boost::math::interpolators::detail::cardinal_cubic_hermite_detail_aos;
+ Real dx = Real(1)/Real(8);
+ Real x0 = 0;
+ Real xf = x0 + (dat.size()-1)*dx;
+ auto qh = cardinal_cubic_hermite_detail_aos(std::move(dat), x0, dx);
+ Real x = 0;
+ Real step = uniform()*(xf-x0)/2048;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(qh.unchecked_evaluation(x));
+ x += step;
+ if (x >= xf)
+ {
+ x = x0;
+ step = uniform()*(xf-x0)/2048;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(CardinalCubicHermiteAOS, double)->RangeMultiplier(2)->Range(1<<8, 1<<21)->Complexity(benchmark::o1);
+BENCHMARK_TEMPLATE(CardinalCubicHermite, double)->RangeMultiplier(2)->Range(1<<8, 1<<21)->Complexity(benchmark::o1);
+
+template<class Real>
+void SineEvaluation(benchmark::State& state)
+{
+ std::default_random_engine gen;
+ std::uniform_real_distribution<Real> x_dis(0, 3.14159);
+
+ Real x = x_dis(gen);
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(std::sin(x));
+ x += std::numeric_limits<Real>::epsilon();
+ }
+}
+
+BENCHMARK_TEMPLATE(SineEvaluation, float);
+BENCHMARK_TEMPLATE(SineEvaluation, double);
+BENCHMARK_TEMPLATE(SineEvaluation, long double);
+
+template<class Real>
+void ExpEvaluation(benchmark::State& state)
+{
+ std::default_random_engine gen;
+ std::uniform_real_distribution<Real> x_dis(0, 3.14159);
+
+ Real x = x_dis(gen);
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(std::exp(x));
+ x += std::numeric_limits<Real>::epsilon();
+ }
+}
+
+BENCHMARK_TEMPLATE(ExpEvaluation, float);
+BENCHMARK_TEMPLATE(ExpEvaluation, double);
+BENCHMARK_TEMPLATE(ExpEvaluation, long double);
+
+template<class Real>
+void PowEvaluation(benchmark::State& state)
+{
+ std::default_random_engine gen;
+ std::uniform_real_distribution<Real> x_dis(0, 3.14159);
+
+ Real x = x_dis(gen);
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(std::pow(x, x+1));
+ x += std::numeric_limits<Real>::epsilon();
+ }
+}
+
+BENCHMARK_TEMPLATE(PowEvaluation, float);
+BENCHMARK_TEMPLATE(PowEvaluation, double);
+BENCHMARK_TEMPLATE(PowEvaluation, long double);
+
+
+template<typename Real>
+void CardinalQuinticHermite(benchmark::State & state)
+{
+ using boost::math::interpolators::detail::cardinal_quintic_hermite_detail;
+ auto n = state.range(0);
+ std::vector<Real> y(n);
+ std::vector<Real> dydx(n);
+ std::vector<Real> d2ydx2(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ for (size_t i = 0; i < y.size(); ++i)
+ {
+ y[i] = uniform();
+ dydx[i] = uniform();
+ d2ydx2[i] = uniform();
+ }
+
+ Real dx = Real(1)/Real(8);
+ Real x0 = 0;
+ Real xf = x0 + (y.size()-1)*dx;
+
+ auto qh = cardinal_quintic_hermite_detail(std::move(y), std::move(dydx), std::move(d2ydx2), x0, dx);
+ Real x = 0;
+ Real step = uniform()*(xf-x0)/2048;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(qh.unchecked_evaluation(x));
+ x += step;
+ if (x >= xf)
+ {
+ x = x0;
+ step = uniform()*(xf-x0)/2048;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+template<typename Real>
+void CardinalQuinticHermiteAOS(benchmark::State & state)
+{
+ auto n = state.range(0);
+ std::vector<std::array<Real, 3>> dat(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ for (size_t i = 0; i < dat.size(); ++i)
+ {
+ dat[i][0] = uniform();
+ dat[i][1] = uniform();
+ dat[i][2] = uniform();
+ }
+
+ using boost::math::interpolators::detail::cardinal_quintic_hermite_detail_aos;
+ Real dx = Real(1)/Real(8);
+ Real x0 = 0;
+ Real xf = x0 + (dat.size()-1)*dx;
+ auto qh = cardinal_quintic_hermite_detail_aos(std::move(dat), x0, dx);
+ Real x = x0;
+ Real step = uniform()*(xf-x0)/2048;
+ for (auto _ : state) {
+ benchmark::DoNotOptimize(qh.unchecked_evaluation(x));
+ x += step;
+ if (x >= xf)
+ {
+ x = x0;
+ step = uniform()*(xf-x0)/2048;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(CardinalQuinticHermiteAOS, double)->RangeMultiplier(2)->Range(1<<8, 1<<22)->Complexity(benchmark::o1);
+BENCHMARK_TEMPLATE(CardinalQuinticHermite, double)->RangeMultiplier(2)->Range(1<<8, 1<<22)->Complexity(benchmark::o1);
+
+template<typename Real>
+void SepticHermite(benchmark::State & state)
+{
+ using boost::math::interpolators::detail::septic_hermite_detail;
+ auto n = state.range(0);
+ std::vector<Real> x(n);
+ std::vector<Real> y(n);
+ std::vector<Real> dydx(n);
+ std::vector<Real> d2ydx2(n);
+ std::vector<Real> d3ydx3(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ Real x0 = dis(rd);
+ x[0] = x0;
+ for (size_t i = 1; i < n; ++i)
+ {
+ x[i] = x[i-1] + dis(rd);
+ }
+ for (size_t i = 0; i < y.size(); ++i)
+ {
+ y[i] = dis(rd);
+ dydx[i] = dis(rd);
+ d2ydx2[i] = dis(rd);
+ d3ydx3[i] = dis(rd);
+ }
+
+ Real xf = x.back();
+
+ auto sh = septic_hermite_detail(std::move(x), std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3));
+ Real t = x0;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(sh(t));
+ t += xf/128;
+ if (t >= xf)
+ {
+ t = x0;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(SepticHermite, double)->RangeMultiplier(2)->Range(1<<8, 1<<20)->Complexity();
+
+
+template<typename Real>
+void CardinalSepticHermite(benchmark::State & state)
+{
+ using boost::math::interpolators::detail::cardinal_septic_hermite_detail;
+ auto n = state.range(0);
+ std::vector<Real> y(n);
+ std::vector<Real> dydx(n);
+ std::vector<Real> d2ydx2(n);
+ std::vector<Real> d3ydx3(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ for (size_t i = 0; i < y.size(); ++i)
+ {
+ y[i] = dis(rd);
+ dydx[i] = dis(rd);
+ d2ydx2[i] = dis(rd);
+ d3ydx3[i] = dis(rd);
+ }
+
+ Real dx = Real(1)/Real(8);
+ Real x0 = 0;
+ Real xf = x0 + (y.size()-1)*dx;
+
+ auto sh = cardinal_septic_hermite_detail(std::move(y), std::move(dydx), std::move(d2ydx2), std::move(d3ydx3), x0, dx);
+ Real x = 0;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(sh.unchecked_evaluation(x));
+ x += xf/128;
+ if (x >= xf)
+ {
+ x = x0;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(CardinalSepticHermite, double)->RangeMultiplier(2)->Range(1<<8, 1<<20)->Complexity();
+
+template<typename Real>
+void CardinalSepticHermiteAOS(benchmark::State & state)
+{
+ using boost::math::interpolators::detail::cardinal_septic_hermite_detail_aos;
+ auto n = state.range(0);
+ std::vector<std::array<Real, 4>> data(n);
+ std::random_device rd;
+ boost::random::uniform_real_distribution<Real> dis(Real(0), Real(1));
+ for (size_t i = 0; i < data.size(); ++i)
+ {
+ for (size_t j = 0; j < 4; ++j)
+ {
+ data[i][j] = dis(rd);
+ }
+ }
+
+ Real dx = Real(1)/Real(8);
+ Real x0 = 0;
+ Real xf = x0 + (data.size()-1)*dx;
+
+ auto sh = cardinal_septic_hermite_detail_aos(std::move(data), x0, dx);
+ Real x = 0;
+ for (auto _ : state)
+ {
+ benchmark::DoNotOptimize(sh.unchecked_evaluation(x));
+ x += xf/128;
+ if (x >= xf)
+ {
+ x = x0;
+ }
+ }
+ state.SetComplexityN(state.range(0));
+}
+
+BENCHMARK_TEMPLATE(CardinalSepticHermiteAOS, double)->RangeMultiplier(2)->Range(1<<8, 1<<20)->Complexity();
+
+
+BENCHMARK_MAIN();
diff --git a/src/boost/libs/math/example/daubechies_wavelets/bootstrap_chebyshev.cpp b/src/boost/libs/math/example/daubechies_wavelets/bootstrap_chebyshev.cpp
new file mode 100644
index 000000000..b158fabcd
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/bootstrap_chebyshev.cpp
@@ -0,0 +1,18 @@
+#include <iostream>
+#include <boost/math/special_functions/daubechies_scaling.hpp>
+#include <boost/math/special_functions/chebyshev_transform.hpp>
+
+template<typename Real, int p>
+void bootstrap()
+{
+ std::cout << "Computing phi. . .\n";
+ auto phi = boost::math::daubechies_scaling<Real, p>();
+ std::cout << "Computing Chebyshev transform of phi.\n";
+ auto cheb = boost::math::chebyshev_transform(phi, phi.support().first, phi.support().second);
+ std::cout << "Number of coefficients = " << cheb.coefficients().size() << "\n";
+}
+
+int main()
+{
+ bootstrap<long double, 9>();
+} \ No newline at end of file
diff --git a/src/boost/libs/math/example/daubechies_wavelets/daubechies_coefficients.cpp b/src/boost/libs/math/example/daubechies_wavelets/daubechies_coefficients.cpp
new file mode 100644
index 000000000..1366e921c
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/daubechies_coefficients.cpp
@@ -0,0 +1,267 @@
+/*
+ * Copyright Nick Thompson, 2018
+ * 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)
+ */
+#include <iostream>
+#include <fstream>
+#include <vector>
+#include <string>
+#include <complex>
+#include <bitset>
+#include <boost/assert.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/tools/polynomial.hpp>
+#include <boost/math/tools/roots.hpp>
+#include <boost/math/special_functions/binomial.hpp>
+#include <boost/multiprecision/cpp_complex.hpp>
+#ifdef BOOST_HAS_FLOAT128
+#include <boost/multiprecision/float128.hpp>
+
+typedef boost::multiprecision::float128 float128_t;
+#else
+typedef boost::multiprecision::cpp_bin_float_quad float128_t;
+#endif
+//#include <boost/multiprecision/complex128.hpp>
+#include <boost/math/quadrature/gauss_kronrod.hpp>
+
+using std::string;
+using boost::math::tools::polynomial;
+using boost::math::binomial_coefficient;
+using boost::math::tools::schroder_iterate;
+using boost::math::tools::halley_iterate;
+using boost::math::tools::newton_raphson_iterate;
+using boost::math::tools::complex_newton;
+using boost::math::constants::half;
+using boost::math::constants::root_two;
+using boost::math::constants::pi;
+using boost::math::quadrature::gauss_kronrod;
+using boost::multiprecision::cpp_bin_float_100;
+using boost::multiprecision::cpp_complex_100;
+
+template<class Complex>
+std::vector<std::pair<Complex, Complex>> find_roots(size_t p)
+{
+ // Initialize the polynomial; see Mallat, A Wavelet Tour of Signal Processing, equation 7.96
+ BOOST_ASSERT(p>0);
+ typedef typename Complex::value_type Real;
+ std::vector<Complex> coeffs(p);
+ for (size_t k = 0; k < coeffs.size(); ++k)
+ {
+ coeffs[k] = Complex(binomial_coefficient<Real>(p-1+k, k), 0);
+ }
+
+ polynomial<Complex> P(std::move(coeffs));
+ polynomial<Complex> Pcopy = P;
+ polynomial<Complex> Pcopy_prime = P.prime();
+ auto orig = [&](Complex z) { return std::make_pair<Complex, Complex>(Pcopy(z), Pcopy_prime(z)); };
+
+ polynomial<Complex> P_prime = P.prime();
+
+ // Polynomial is of degree p-1.
+
+ std::vector<Complex> roots(p-1, {std::numeric_limits<Real>::quiet_NaN(),std::numeric_limits<Real>::quiet_NaN()});
+ size_t i = 0;
+ while(P.size() > 1)
+ {
+ Complex guess = {0.0, 1.0};
+ std::cout << std::setprecision(std::numeric_limits<Real>::digits10+3);
+
+ auto f = [&](Complex x)->std::pair<Complex, Complex>
+ {
+ return std::make_pair<Complex, Complex>(P(x), P_prime(x));
+ };
+
+ Complex r = complex_newton(f, guess);
+ using std::isnan;
+ if(isnan(r.real()))
+ {
+ int i = 50;
+ do {
+ // Try a different guess
+ guess *= Complex(1.0,-1.0);
+ r = complex_newton(f, guess);
+ std::cout << "New guess: " << guess << ", result? " << r << std::endl;
+
+ } while (isnan(r.real()) && i-- > 0);
+
+ if (isnan(r.real()))
+ {
+ std::cout << "Polynomial that killed the process: " << P << std::endl;
+ throw std::logic_error("Newton iteration did not converge");
+ }
+ }
+ // Refine r with the original function.
+ // We only use the polynomial division to ensure we don't get the same root over and over.
+ // However, the division induces error which can grow quickly-or slowly! See Numerical Recipes, section 9.5.1.
+ r = complex_newton(orig, r);
+ if (isnan(r.real()))
+ {
+ throw std::logic_error("Found a root for the deflated polynomial which is not a root for the original. Indicative of catastrophic numerical error.");
+ }
+ // Test the root:
+ using std::sqrt;
+ Real tol = sqrt(sqrt(std::numeric_limits<Real>::epsilon()));
+ if (norm(Pcopy(r)) > tol)
+ {
+ std::cout << "This is a bad root: P" << r << " = " << Pcopy(r) << std::endl;
+ std::cout << "Reduced polynomial leading to bad root: " << P << std::endl;
+ throw std::logic_error("Donezo.");
+ }
+
+ BOOST_ASSERT(i < roots.size());
+ roots[i] = r;
+ ++i;
+ polynomial<Complex> q{-r, {1,0}};
+ // This optimization breaks at p = 11. I have no clue why.
+ // Unfortunate, because I expect it to be considerably more stable than
+ // repeatedly dividing by the complex root.
+ /*polynomial<Complex> q;
+ if (r.imag() > sqrt(std::numeric_limits<Real>::epsilon()))
+ {
+ // Then the complex conjugate is also a root:
+ using std::conj;
+ using std::norm;
+ BOOST_ASSERT(i < roots.size());
+ roots[i] = conj(r);
+ ++i;
+ q = polynomial<Complex>({{norm(r), 0}, {-2*r.real(),0}, {1,0}});
+ }
+ else
+ {
+ // The imaginary part is numerical noise:
+ r.imag() = 0;
+ q = polynomial<Complex>({-r, {1,0}});
+ }*/
+
+
+ auto PR = quotient_remainder(P, q);
+ // I should validate that the remainder is small, but . . .
+ //std::cout << "Remainder = " << PR.second<< std::endl;
+
+ P = PR.first;
+ P_prime = P.prime();
+ }
+
+ std::vector<std::pair<Complex, Complex>> Qroots(p-1);
+ for (size_t i = 0; i < Qroots.size(); ++i)
+ {
+ Complex y = roots[i];
+ Complex z1 = static_cast<Complex>(1) - static_cast<Complex>(2)*y + static_cast<Complex>(2)*sqrt(y*(y-static_cast<Complex>(1)));
+ Complex z2 = static_cast<Complex>(1) - static_cast<Complex>(2)*y - static_cast<Complex>(2)*sqrt(y*(y-static_cast<Complex>(1)));
+ Qroots[i] = {z1, z2};
+ }
+
+ return Qroots;
+}
+
+template<class Complex>
+std::vector<typename Complex::value_type> daubechies_coefficients(std::vector<std::pair<Complex, Complex>> const & Qroots)
+{
+ typedef typename Complex::value_type Real;
+ size_t p = Qroots.size() + 1;
+ // Choose the minimum abs root; see Mallat, discussion just after equation 7.98
+ std::vector<Complex> chosen_roots(p-1);
+ for (size_t i = 0; i < p - 1; ++i)
+ {
+ if(norm(Qroots[i].first) <= 1)
+ {
+ chosen_roots[i] = Qroots[i].first;
+ }
+ else
+ {
+ BOOST_ASSERT(norm(Qroots[i].second) <= 1);
+ chosen_roots[i] = Qroots[i].second;
+ }
+ }
+
+ polynomial<Complex> R{1};
+ for (size_t i = 0; i < p-1; ++i)
+ {
+ Complex ak = chosen_roots[i];
+ R *= polynomial<Complex>({-ak/(static_cast<Complex>(1)-ak), static_cast<Complex>(1)/(static_cast<Complex>(1)-ak)});
+ }
+ polynomial<Complex> a{{half<Real>(), 0}, {half<Real>(),0}};
+ polynomial<Complex> poly = root_two<Real>()*pow(a, p)*R;
+ std::vector<Complex> result = poly.data();
+ // If we reverse, we get the Numerical Recipes and Daubechies convention.
+ // If we don't reverse, we get the Pywavelets and Mallat convention.
+ // I believe this is because of the sign convention on the DFT, which differs between Daubechies and Mallat.
+ // You implement a dot product in Daubechies/NR convention, and a convolution in PyWavelets/Mallat convention.
+ std::reverse(result.begin(), result.end());
+ std::vector<Real> h(result.size());
+ for (size_t i = 0; i < result.size(); ++i)
+ {
+ Complex r = result[i];
+ BOOST_ASSERT(r.imag() < sqrt(std::numeric_limits<Real>::epsilon()));
+ h[i] = r.real();
+ }
+
+ // Quick sanity check: We could check all vanishing moments, but that sum is horribly ill-conditioned too!
+ Real sum = 0;
+ Real scale = 0;
+ for (size_t i = 0; i < h.size(); ++i)
+ {
+ sum += h[i];
+ scale += h[i]*h[i];
+ }
+ BOOST_ASSERT(abs(scale -1) < sqrt(std::numeric_limits<Real>::epsilon()));
+ BOOST_ASSERT(abs(sum - root_two<Real>()) < sqrt(std::numeric_limits<Real>::epsilon()));
+ return h;
+}
+
+int main()
+{
+ typedef boost::multiprecision::cpp_complex<500> Complex;
+ size_t p_max = 20;
+ std::ofstream fs{"daubechies_filters.hpp"};
+ fs << "/*\n"
+ << " * Copyright Nick Thompson, 2019\n"
+ << " * Use, modification and distribution are subject to the\n"
+ << " * Boost Software License, Version 1.0. (See accompanying file\n"
+ << " * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n"
+ << " */\n"
+ << "#ifndef BOOST_MATH_FILTERS_DAUBECHIES_HPP\n"
+ << "#define BOOST_MATH_FILTERS_DAUBECHIES_HPP\n"
+ << "#include <array>\n"
+ << "#include <limits>\n"
+ << "#include <boost/math/tools/big_constant.hpp>\n\n"
+ << "namespace boost::math::filters {\n\n"
+ << "template <typename Real, unsigned p>\n"
+ << "constexpr std::array<Real, 2*p> daubechies_scaling_filter()\n"
+ << "{\n"
+ << " static_assert(p < " << p_max << ", \"Filter coefficients only implemented up to " << p_max - 1 << ".\");\n";
+
+ for(size_t p = 1; p < p_max; ++p)
+ {
+ fs << std::setprecision(std::numeric_limits<boost::multiprecision::cpp_bin_float_oct>::max_digits10);
+ auto roots = find_roots<Complex>(p);
+ auto h = daubechies_coefficients(roots);
+ fs << " if constexpr (p == " << p << ") {\n";
+ fs << " return {";
+ for (size_t i = 0; i < h.size() - 1; ++i) {
+ fs << "BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits<Real>::digits, " << h[i] << "), ";
+ }
+ fs << "BOOST_MATH_BIG_CONSTANT(Real, std::numeric_limits<Real>::digits, " << h[h.size()-1] << ") };\n";
+ fs << " }\n";
+ }
+
+ fs << "}\n\n";
+
+ fs << "template<class Real, size_t p>\n";
+ fs << "std::array<Real, 2*p> daubechies_wavelet_filter() {\n";
+ fs << " std::array<Real, 2*p> g;\n";
+ fs << " auto h = daubechies_scaling_filter<Real, p>();\n";
+ fs << " for (size_t i = 0; i < g.size(); i += 2)\n";
+ fs << " {\n";
+ fs << " g[i] = h[g.size() - i - 1];\n";
+ fs << " g[i+1] = -h[g.size() - i - 2];\n";
+ fs << " }\n";
+ fs << " return g;\n";
+ fs << "}\n\n";
+ fs << "} // namespaces\n";
+ fs << "#endif\n";
+ fs.close();
+}
diff --git a/src/boost/libs/math/example/daubechies_wavelets/daubechies_plots.cpp b/src/boost/libs/math/example/daubechies_wavelets/daubechies_plots.cpp
new file mode 100644
index 000000000..70172c98e
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/daubechies_plots.cpp
@@ -0,0 +1,165 @@
+/*
+ * Copyright Nick Thompson, 2020
+ * 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)
+ */
+#include <iostream>
+#include <boost/core/demangle.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+
+#include <boost/multiprecision/float128.hpp>
+#include <boost/math/special_functions/daubechies_scaling.hpp>
+#include <quicksvg/graph_fn.hpp>
+#include <quicksvg/ulp_plot.hpp>
+
+
+using boost::multiprecision::float128;
+constexpr const int GRAPH_WIDTH = 700;
+
+template<typename Real, int p>
+void plot_phi(int grid_refinements = -1)
+{
+ auto phi = boost::math::daubechies_scaling<Real, p>();
+ if (grid_refinements >= 0)
+ {
+ phi = boost::math::daubechies_scaling<Real, p>(grid_refinements);
+ }
+ Real a = 0;
+ Real b = phi.support().second;
+ std::string title = "Daubechies " + std::to_string(p) + " scaling function";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_scaling.svg";
+ int samples = 1024;
+ quicksvg::graph_fn daub(a, b, title, filename, samples, GRAPH_WIDTH);
+ daub.set_gridlines(8, 2*p-1);
+ daub.set_stroke_width(1);
+ daub.add_fn(phi);
+ daub.write_all();
+}
+
+template<typename Real, int p>
+void plot_dphi(int grid_refinements = -1)
+{
+ auto phi = boost::math::daubechies_scaling<Real, p>();
+ if (grid_refinements >= 0)
+ {
+ phi = boost::math::daubechies_scaling<Real, p>(grid_refinements);
+ }
+ Real a = 0;
+ Real b = phi.support().second;
+ std::string title = "Daubechies " + std::to_string(p) + " scaling function derivative";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_scaling_prime.svg";
+ int samples = 1024;
+ quicksvg::graph_fn daub(a, b, title, filename, samples, GRAPH_WIDTH);
+ daub.set_stroke_width(1);
+ daub.set_gridlines(8, 2*p-1);
+ auto dphi = [phi](Real x)->Real { return phi.prime(x); };
+ daub.add_fn(dphi);
+ daub.write_all();
+}
+
+template<typename Real, int p>
+void plot_convergence()
+{
+ auto phi0 = boost::math::daubechies_scaling<Real, p>(0);
+ Real a = 0;
+ Real b = phi0.support().second;
+ std::string title = "Daubechies " + std::to_string(p) + " scaling at 0 (green), 1 (orange), 2 (red), and 24 (blue) grid refinements";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_scaling_convergence.svg";
+
+ quicksvg::graph_fn daub(a, b, title, filename, 1024, GRAPH_WIDTH);
+ daub.set_stroke_width(1);
+ daub.set_gridlines(8, 2*p-1);
+
+ daub.add_fn(phi0, "green");
+ auto phi1 = boost::math::daubechies_scaling<Real, p>(1);
+ daub.add_fn(phi1, "orange");
+ auto phi2 = boost::math::daubechies_scaling<Real, p>(2);
+ daub.add_fn(phi2, "red");
+
+ auto phi21 = boost::math::daubechies_scaling<Real, p>(21);
+ daub.add_fn(phi21);
+
+ daub.write_all();
+}
+
+template<typename Real, int p>
+void plot_condition_number()
+{
+ using std::abs;
+ using std::log;
+ static_assert(p >= 3, "p = 2 is not differentiable, so condition numbers cannot be effectively evaluated.");
+ auto phi = boost::math::daubechies_scaling<Real, p>();
+ Real a = std::sqrt(std::numeric_limits<Real>::epsilon());
+ Real b = phi.support().second - 1000*std::sqrt(std::numeric_limits<Real>::epsilon());
+ std::string title = "log10 of condition number of function evaluation for Daubechies " + std::to_string(p) + " scaling function.";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_scaling_condition_number.svg";
+
+
+ quicksvg::graph_fn daub(a, b, title, filename, 2048, GRAPH_WIDTH);
+ daub.set_stroke_width(1);
+ daub.set_gridlines(8, 2*p-1);
+
+ auto cond = [&phi](Real x)
+ {
+ Real y = phi(x);
+ Real dydx = phi.prime(x);
+ Real z = abs(x*dydx/y);
+ using std::isnan;
+ if (z==0)
+ {
+ return Real(-1);
+ }
+ if (isnan(z))
+ {
+ // Graphing libraries don't like nan's:
+ return Real(1);
+ }
+ return log10(z);
+ };
+ daub.add_fn(cond);
+ daub.write_all();
+}
+
+template<typename CoarseReal, typename PreciseReal, int p, class PhiPrecise>
+void do_ulp(int coarse_refinements, PhiPrecise phi_precise)
+{
+ auto phi_coarse = boost::math::daubechies_scaling<CoarseReal, p>(coarse_refinements);
+
+ std::string title = std::to_string(p) + " vanishing moment ULP plot at " + std::to_string(coarse_refinements) + " refinements and " + boost::core::demangle(typeid(CoarseReal).name()) + " precision";
+ title = "";
+
+ std::string filename = "daubechies_" + std::to_string(p) + "_" + boost::core::demangle(typeid(CoarseReal).name()) + "_" + std::to_string(coarse_refinements) + "_refinements.svg";
+ int samples = 20000;
+ int clip = 20;
+ int horizontal_lines = 8;
+ int vertical_lines = 2*p - 1;
+ quicksvg::ulp_plot<decltype(phi_coarse), CoarseReal, decltype(phi_precise), PreciseReal>(phi_coarse, phi_precise, CoarseReal(0), phi_coarse.support().second, title, filename, samples, GRAPH_WIDTH, clip, horizontal_lines, vertical_lines);
+}
+
+
+int main()
+{
+ boost::hana::for_each(std::make_index_sequence<18>(), [&](auto i){ plot_phi<double, i+2>(); });
+ boost::hana::for_each(std::make_index_sequence<17>(), [&](auto i){ plot_dphi<double, i+3>(); });
+ boost::hana::for_each(std::make_index_sequence<17>(), [&](auto i){ plot_condition_number<double, i+3>(); });
+ boost::hana::for_each(std::make_index_sequence<18>(), [&](auto i){ plot_convergence<double, i+2>(); });
+
+ using PreciseReal = float128;
+ using CoarseReal = double;
+ int precise_refinements = 22;
+ constexpr const int p = 8;
+ std::cout << "Computing precise scaling function in " << boost::core::demangle(typeid(PreciseReal).name()) << " precision.\n";
+ auto phi_precise = boost::math::daubechies_scaling<PreciseReal, p>(precise_refinements);
+ std::cout << "Beginning comparison with functions computed in " << boost::core::demangle(typeid(CoarseReal).name()) << " precision.\n";
+ for (int i = 7; i <= precise_refinements-1; ++i)
+ {
+ std::cout << "\tCoarse refinement " << i << "\n";
+ do_ulp<CoarseReal, PreciseReal, p>(i, phi_precise);
+ }
+}
diff --git a/src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_integer_grid.cpp b/src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_integer_grid.cpp
new file mode 100644
index 000000000..c06bad5f1
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_integer_grid.cpp
@@ -0,0 +1,213 @@
+/*
+ * Copyright Nick Thompson, John Maddock 2020
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#define BOOST_MATH_GENERATE_DAUBECHIES_GRID
+
+#include <iostream>
+#include <vector>
+#include <numeric>
+#include <list>
+#include <cmath>
+#include <cassert>
+#include <fstream>
+#include <Eigen/Eigenvalues>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/core/demangle.hpp>
+#ifdef BOOST_HAS_FLOAT128
+#include <boost/multiprecision/float128.hpp>
+#endif
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/filters/daubechies.hpp>
+#include <boost/math/special_functions/factorials.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+
+typedef boost::multiprecision::number<boost::multiprecision::cpp_bin_float<237, boost::multiprecision::backends::digit_base_2, std::allocator<char>, boost::int32_t, -262142, 262143>, boost::multiprecision::et_off> octuple_type;
+
+#ifdef BOOST_HAS_FLOAT128
+typedef boost::multiprecision::float128 float128_t;
+#else
+typedef boost::multiprecision::cpp_bin_float_quad float128_t;
+#endif
+
+template<class Real, int p>
+std::list<std::vector<Real>> integer_grid()
+{
+ std::cout << std::setprecision(std::numeric_limits<Real>::digits10 + 3);
+ using std::abs;
+ using std::sqrt;
+ using std::pow;
+ std::list<std::vector<Real>> grids;
+
+ auto c = boost::math::filters::daubechies_scaling_filter<Real, p>();
+ for (auto & x : c)
+ {
+ x *= boost::math::constants::root_two<Real>();
+ }
+ std::cout << "\n\nTaps in filter = " << c.size() << "\n";
+
+
+ Eigen::Matrix<Real, 2*p - 2, 2*p-2> A;
+ for (int j = 0; j < 2*p-2; ++j) {
+ for (int k = 0; k < 2*p-2; ++k) {
+ if ( (2*j-k + 1) < 0 || (2*j - k + 1) >= 2*p)
+ {
+ A(j,k) = 0;
+ }
+ else {
+ A(j,k) = c[2*j - k + 1];
+ }
+ }
+ }
+
+ Eigen::EigenSolver<decltype(A)> es(A);
+
+ auto complex_eigs = es.eigenvalues();
+
+ std::vector<Real> eigs(complex_eigs.size(), std::numeric_limits<Real>::quiet_NaN());
+
+ std::cout << "Eigenvalues = {";
+ for (long i = 0; i < complex_eigs.size(); ++i) {
+ assert(abs(complex_eigs[i].imag()) < std::numeric_limits<Real>::epsilon());
+ eigs[i] = complex_eigs[i].real();
+ std::cout << eigs[i] << ", ";
+ }
+ std::cout << "}\n";
+
+ // Eigen does not sort the eigenpairs by any criteria on the eigenvalues.
+ // In any case, even if it did, some of the eigenpairs do not correspond to derivatives anyway.
+ for (size_t j = 0; j < eigs.size(); ++j) {
+ auto f = [&](Real x) {
+ return abs(x - Real(1)/Real(1 << j) ) < sqrt(std::numeric_limits<Real>::epsilon());
+ };
+ auto it = std::find_if(eigs.begin(), eigs.end(), f);
+ if (it == eigs.end()) {
+ std::cout << "couldn't find eigenvalue " << Real(1)/Real(1 << j) << "\n";
+ continue;
+ }
+ size_t idx = std::distance(eigs.begin(), it);
+ std::cout << "Eigenvector for derivative " << j << " is at index " << idx << "\n";
+ auto eigenvector_matrix = es.eigenvectors();
+ auto complex_eigenvec = eigenvector_matrix.col(idx);
+
+ std::vector<Real> eigenvec(complex_eigenvec.size() + 2, std::numeric_limits<Real>::quiet_NaN());
+ eigenvec[0] = 0;
+ eigenvec[eigenvec.size()-1] = 0;
+ for (size_t i = 0; i < eigenvec.size() - 2; ++i) {
+ assert(abs(complex_eigenvec[i].imag()) < std::numeric_limits<Real>::epsilon());
+ eigenvec[i+1] = complex_eigenvec[i].real();
+ }
+
+ Real sum = 0;
+ for(size_t k = 1; k < eigenvec.size(); ++k) {
+ sum += pow(k, j)*eigenvec[k];
+ }
+
+ Real alpha = pow(-1, j)*boost::math::factorial<Real>(j)/sum;
+
+ for (size_t i = 1; i < eigenvec.size(); ++i) {
+ eigenvec[i] *= alpha;
+ }
+
+
+ std::cout << "Eigenvector = {";
+ for (size_t i = 0; i < eigenvec.size() -1; ++i) {
+ std::cout << eigenvec[i] << ", ";
+ }
+ std::cout << eigenvec[eigenvec.size()-1] << "}\n";
+
+ sum = 0;
+ for(size_t k = 1; k < eigenvec.size(); ++k) {
+ sum += pow(k, j)*eigenvec[k];
+ }
+
+ std::cout << "Moment sum = " << sum << ", expected = " << pow(-1, j)*boost::math::factorial<Real>(j) << "\n";
+
+ assert(abs(sum - pow(-1, j)*boost::math::factorial<Real>(j))/abs(pow(-1, j)*boost::math::factorial<Real>(j)) < sqrt(std::numeric_limits<Real>::epsilon()));
+
+ grids.push_back(eigenvec);
+ }
+
+
+ return grids;
+}
+
+template<class Real, int p>
+void write_grid(std::ofstream & fs)
+{
+ auto grids = integer_grid<Real, p>();
+ size_t j = 0;
+ fs << std::setprecision(std::numeric_limits< boost::multiprecision::cpp_bin_float_quad>::max_digits10);
+ for (auto it = grids.begin(); it != grids.end(); ++it)
+ {
+ auto const& grid = *it;
+ fs << "template <typename Real> struct daubechies_scaling_integer_grid_imp <Real, " << p << ", ";
+ fs << j << "> { static inline constexpr std::array<Real, " << grid.size() << "> value = { ";
+ for (size_t i = 0; i < grid.size() -1; ++i){
+ fs << "C_(" << static_cast<float128_t>(grid[i]) << "), ";
+ }
+ fs << "C_(" << static_cast<float128_t>(grid[grid.size()-1]) << ") }; };\n";
+ ++j;
+ }
+}
+
+int main()
+{
+ constexpr const size_t p_max = 18;
+ std::ofstream fs{"daubechies_scaling_integer_grid.hpp"};
+ fs << "/*\n"
+ << " * Copyright Nick Thompson, John Maddock 2020\n"
+ << " * Use, modification and distribution are subject to the\n"
+ << " * Boost Software License, Version 1.0. (See accompanying file\n"
+ << " * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)\n"
+ << " */\n"
+ << "// THIS FILE GENERATED BY EXAMPLE/DAUBECHIES_SCALING_INTEGER_GRID.CPP, DO NOT EDIT.\n"
+ << "#ifndef BOOST_MATH_DAUBECHIES_SCALING_INTEGER_GRID_HPP\n"
+ << "#define BOOST_MATH_DAUBECHIES_SCALING_INTEGER_GRID_HPP\n"
+ << "#include <array>\n"
+ << "#include <float.h>\n"
+ << "#include <boost/config.hpp>\n"
+ << "/*\n"
+ << "In order to keep the character count as small as possible and speed up\n"
+ << "compiler parsing times, we define a macro C_ which appends an appropriate\n"
+ << "suffix to each literal, and then casts it to type Real.\n"
+ << "The suffix is as follows:\n\n"
+ << "* Q, when we have __float128 support.\n"
+ << "* L, when we have either 80 or 128 bit long doubles.\n"
+ << "* Nothing otherwise.\n"
+ << "*/\n\n"
+ << "#ifdef BOOST_HAS_FLOAT128\n"
+ << "# define C_(x) static_cast<Real>(x##Q)\n"
+ << "#elif (LDBL_MANT_DIG > DBL_MANT_DIG)\n"
+ << "# define C_(x) static_cast<Real>(x##L)\n"
+ << "#else\n"
+ << "# define C_(x) static_cast<Real>(x)\n"
+ << "#endif\n\n"
+ << "namespace boost::math::detail {\n\n"
+ << "template <typename Real, int p, int order> struct daubechies_scaling_integer_grid_imp;\n\n";
+
+ fs << std::hexfloat << std::setprecision(std::numeric_limits<boost::multiprecision::cpp_bin_float_quad>::max_digits10);
+
+ boost::hana::for_each(std::make_index_sequence<p_max>(), [&](auto idx){
+ write_grid<octuple_type, idx+2>(fs);
+ });
+
+ fs << "\n\ntemplate <typename Real, unsigned p, unsigned order>\n"
+ << "constexpr inline std::array<Real, 2*p> daubechies_scaling_integer_grid()\n"
+ << "{\n"
+ << " static_assert(sizeof(Real) <= 16, \"Integer grids only computed up to 128 bits of precision.\");\n"
+ << " static_assert(p <= " << p_max + 1 << ", \"Integer grids only implemented up to " << p_max + 1 << ".\");\n"
+ << " static_assert(p > 1, \"Integer grids only implemented for p >= 2.\");\n"
+ << " return daubechies_scaling_integer_grid_imp<Real, p, order>::value;\n"
+ << "}\n\n";
+
+ fs << "} // namespaces\n";
+ fs << "#endif\n";
+ fs.close();
+
+ return 0;
+}
diff --git a/src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_memory_occupation.cpp b/src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_memory_occupation.cpp
new file mode 100644
index 000000000..43ae80779
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/daubechies_scaling_memory_occupation.cpp
@@ -0,0 +1,59 @@
+#include <iostream>
+#include <boost/math/special_functions/daubechies_scaling.hpp>
+#include <boost/core/demangle.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+
+int main()
+{
+ boost::hana::for_each(std::make_index_sequence<18>(),
+ [](auto i) {
+ std::cout << std::right;
+ auto daub = boost::math::daubechies_scaling<float, i+2>();
+ std::cout << "The Daubechies " << std::setw(2) << i + 2 << " scaling function occupies "
+ << std::setw(12) << daub.bytes()/1000.0 << " kilobytes in relative accuracy mode in "
+ << boost::core::demangle(typeid(float).name()) << " precision\n";
+ });
+
+ std::cout << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+
+ boost::hana::for_each(std::make_index_sequence<18>(),
+ [](auto i) {
+ std::cout << std::right;
+ auto daub = boost::math::daubechies_scaling<float, i+2>(-2);
+ std::cout << "The Daubechies " << std::setw(2) << i + 2 << " scaling function occupies "
+ << std::setw(12) << daub.bytes()/1000.0 << " kilobytes in absolute accuracy mode in "
+ << boost::core::demangle(typeid(float).name()) << " precision\n";
+ });
+
+ std::cout << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+
+
+ boost::hana::for_each(std::make_index_sequence<18>(),
+ [](auto i) {
+ std::cout << std::right;
+ auto daub = boost::math::daubechies_scaling<double, i+2>();
+ std::cout << "The Daubechies " << std::setw(2) << i + 2 << " scaling function occupies "
+ << std::setw(12) << daub.bytes()/1000.0 << " kilobytes in relative accuracy mode in "
+ << boost::core::demangle(typeid(double).name()) << " precision\n";
+ });
+
+ std::cout << std::endl;
+ std::cout << std::endl;
+ std::cout << std::endl;
+
+ boost::hana::for_each(std::make_index_sequence<18>(),
+ [](auto i) {
+ std::cout << std::right;
+ auto daub = boost::math::daubechies_scaling<double, i+2>(-2);
+ std::cout << "The Daubechies " << std::setw(2) << i + 2 << " scaling function occupies "
+ << std::setw(12) << daub.bytes()/1000.0 << " kilobytes in absolute accuracy mode in "
+ << boost::core::demangle(typeid(double).name()) << " precision\n";
+ });
+
+
+}
diff --git a/src/boost/libs/math/example/daubechies_wavelets/daubechies_wavelet_plots.cpp b/src/boost/libs/math/example/daubechies_wavelets/daubechies_wavelet_plots.cpp
new file mode 100644
index 000000000..4d898ea4e
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/daubechies_wavelet_plots.cpp
@@ -0,0 +1,160 @@
+/*
+ * Copyright Nick Thompson, 2020
+ * 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)
+ */
+#include <iostream>
+#include <boost/core/demangle.hpp>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+
+#include <boost/multiprecision/float128.hpp>
+#include <boost/math/special_functions/daubechies_wavelet.hpp>
+#include <quicksvg/graph_fn.hpp>
+#include <quicksvg/ulp_plot.hpp>
+
+
+using boost::multiprecision::float128;
+constexpr const int GRAPH_WIDTH = 700;
+
+template<typename Real, int p>
+void plot_psi(int grid_refinements = -1)
+{
+ auto psi = boost::math::daubechies_wavelet<Real, p>();
+ if (grid_refinements >= 0)
+ {
+ psi = boost::math::daubechies_wavelet<Real, p>(grid_refinements);
+ }
+ auto [a, b] = psi.support();
+ std::string title = "Daubechies " + std::to_string(p) + " wavelet";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_wavelet.svg";
+ int samples = 1024;
+ quicksvg::graph_fn daub(a, b, title, filename, samples, GRAPH_WIDTH);
+ daub.set_gridlines(8, 2*p-1);
+ daub.set_stroke_width(1);
+ daub.add_fn(psi);
+ daub.write_all();
+}
+
+template<typename Real, int p>
+void plot_dpsi(int grid_refinements = -1)
+{
+ auto psi = boost::math::daubechies_wavelet<Real, p>();
+ if (grid_refinements >= 0)
+ {
+ psi = boost::math::daubechies_wavelet<Real, p>(grid_refinements);
+ }
+ auto [a, b] = psi.support();
+ std::string title = "Daubechies " + std::to_string(p) + " wavelet derivative";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_wavelet_prime.svg";
+ int samples = 1024;
+ quicksvg::graph_fn daub(a, b, title, filename, samples, GRAPH_WIDTH);
+ daub.set_stroke_width(1);
+ daub.set_gridlines(8, 2*p-1);
+ auto dpsi = [psi](Real x)->Real { return psi.prime(x); };
+ daub.add_fn(dpsi);
+ daub.write_all();
+}
+
+template<typename Real, int p>
+void plot_convergence()
+{
+ auto psi1 = boost::math::daubechies_wavelet<Real, p>(1);
+ auto [a, b] = psi1.support();
+ std::string title = "Daubechies " + std::to_string(p) + " wavelet at 1 (orange), 2 (red), and 21 (blue) grid refinements";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_wavelet_convergence.svg";
+
+ quicksvg::graph_fn daub(a, b, title, filename, 1024, GRAPH_WIDTH);
+ daub.set_stroke_width(1);
+ daub.set_gridlines(8, 2*p-1);
+
+ daub.add_fn(psi1, "orange");
+ auto psi2 = boost::math::daubechies_wavelet<Real, p>(2);
+ daub.add_fn(psi2, "red");
+
+ auto psi21 = boost::math::daubechies_wavelet<Real, p>(21);
+ daub.add_fn(psi21);
+
+ daub.write_all();
+}
+
+template<typename Real, int p>
+void plot_condition_number()
+{
+ using std::abs;
+ using std::log;
+ static_assert(p >= 3, "p = 2 is not differentiable, so condition numbers cannot be effectively evaluated.");
+ auto phi = boost::math::daubechies_wavelet<Real, p>();
+ Real a = phi.support().first + 1000*std::sqrt(std::numeric_limits<Real>::epsilon());
+ Real b = phi.support().second - 1000*std::sqrt(std::numeric_limits<Real>::epsilon());
+ std::string title = "log10 of condition number of function evaluation for Daubechies " + std::to_string(p) + " wavelet function.";
+ title = "";
+ std::string filename = "daubechies_" + std::to_string(p) + "_wavelet_condition_number.svg";
+
+
+ quicksvg::graph_fn daub(a, b, title, filename, 2048, GRAPH_WIDTH);
+ daub.set_stroke_width(1);
+ daub.set_gridlines(8, 2*p-1);
+
+ auto cond = [&phi](Real x)
+ {
+ Real y = phi(x);
+ Real dydx = phi.prime(x);
+ Real z = abs(x*dydx/y);
+ using std::isnan;
+ if (z==0)
+ {
+ return Real(-1);
+ }
+ if (isnan(z))
+ {
+ // Graphing libraries don't like nan's:
+ return Real(1);
+ }
+ return log10(z);
+ };
+ daub.add_fn(cond);
+ daub.write_all();
+}
+
+template<typename CoarseReal, typename PreciseReal, int p, class PsiPrecise>
+void do_ulp(int coarse_refinements, PsiPrecise psi_precise)
+{
+ auto psi_coarse = boost::math::daubechies_wavelet<CoarseReal, p>(coarse_refinements);
+
+ std::string title = std::to_string(p) + " vanishing moment ULP plot at " + std::to_string(coarse_refinements) + " refinements and " + boost::core::demangle(typeid(CoarseReal).name()) + " precision";
+ title = "";
+
+ std::string filename = "daubechies_" + std::to_string(p) + "_wavelet_" + boost::core::demangle(typeid(CoarseReal).name()) + "_" + std::to_string(coarse_refinements) + "_refinements.svg";
+ int samples = 20000;
+ int clip = 20;
+ int horizontal_lines = 8;
+ int vertical_lines = 2*p - 1;
+ quicksvg::ulp_plot<decltype(psi_coarse), CoarseReal, decltype(psi_precise), PreciseReal>(psi_coarse, psi_precise, CoarseReal(psi_coarse.support().first), psi_coarse.support().second, title, filename, samples, GRAPH_WIDTH, clip, horizontal_lines, vertical_lines);
+}
+
+
+int main()
+{
+ boost::hana::for_each(std::make_index_sequence<18>(), [&](auto i){ plot_psi<double, i+2>(); });
+ boost::hana::for_each(std::make_index_sequence<17>(), [&](auto i){ plot_dpsi<double, i+3>(); });
+ boost::hana::for_each(std::make_index_sequence<17>(), [&](auto i){ plot_condition_number<double, i+3>(); });
+ boost::hana::for_each(std::make_index_sequence<18>(), [&](auto i){ plot_convergence<double, i+2>(); });
+
+ using PreciseReal = float128;
+ using CoarseReal = double;
+ int precise_refinements = 22;
+ constexpr const int p = 9;
+ std::cout << "Computing precise wavelet function in " << boost::core::demangle(typeid(PreciseReal).name()) << " precision.\n";
+ auto phi_precise = boost::math::daubechies_wavelet<PreciseReal, p>(precise_refinements);
+ std::cout << "Beginning comparison with functions computed in " << boost::core::demangle(typeid(CoarseReal).name()) << " precision.\n";
+ for (int i = 7; i <= precise_refinements-1; ++i)
+ {
+ std::cout << "\tCoarse refinement " << i << "\n";
+ do_ulp<CoarseReal, PreciseReal, p>(i, phi_precise);
+ }
+}
diff --git a/src/boost/libs/math/example/daubechies_wavelets/find_best_daubechies_interpolator.cpp b/src/boost/libs/math/example/daubechies_wavelets/find_best_daubechies_interpolator.cpp
new file mode 100644
index 000000000..56c5ed3cb
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/find_best_daubechies_interpolator.cpp
@@ -0,0 +1,535 @@
+// Copyright Nick Thompson, 2020
+// 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)
+
+#include <iostream>
+#include <unordered_map>
+#include <string>
+#include <future>
+#include <thread>
+#include <fstream>
+#include <boost/hana/for_each.hpp>
+#include <boost/hana/ext/std/integer_sequence.hpp>
+#include <boost/math/special_functions/daubechies_scaling.hpp>
+#include <boost/math/special_functions/detail/daubechies_scaling_integer_grid.hpp>
+#include <boost/math/interpolators/cubic_hermite.hpp>
+#include <boost/math/interpolators/quintic_hermite.hpp>
+#include <boost/math/interpolators/quintic_hermite.hpp>
+#include <boost/math/interpolators/septic_hermite.hpp>
+#include <boost/math/interpolators/cardinal_quadratic_b_spline.hpp>
+#include <boost/math/interpolators/cardinal_cubic_b_spline.hpp>
+#include <boost/math/interpolators/cardinal_quintic_b_spline.hpp>
+#include <boost/math/interpolators/whittaker_shannon.hpp>
+#include <boost/math/interpolators/cardinal_trigonometric.hpp>
+#include <boost/math/special_functions/next.hpp>
+#include <boost/math/interpolators/makima.hpp>
+#include <boost/math/interpolators/pchip.hpp>
+#include <boost/multiprecision/float128.hpp>
+#include <boost/core/demangle.hpp>
+
+using boost::multiprecision::float128;
+
+
+template<typename Real, typename PreciseReal, int p>
+void choose_refinement()
+{
+ std::cout << "Choosing refinement for " << boost::core::demangle(typeid(Real).name()) << " precision Daubechies scaling function with " << p << " vanishing moments.\n";
+ using std::abs;
+ int rmax = 22;
+ auto phi_dense = boost::math::daubechies_scaling_dyadic_grid<PreciseReal, p, 0>(rmax);
+ Real dx_dense = (2*p-1)/static_cast<Real>(phi_dense.size()-1);
+
+ for (int r = 2; r <= 18; ++r)
+ {
+ Real dx = Real(1)/ (1 << r);
+ std::cout << "\tdx = 1/" << (1/dx) << " = 1/2^" << r << " = " << dx << "\n";
+ auto phi = boost::math::daubechies_scaling<Real, p>(r);
+ Real max_flt_distance = 0;
+ Real sup = 0;
+ Real rel_sup = 0;
+ Real worst_flt_abscissa = 0;
+ Real worst_flt_value = 0;
+ Real worst_flt_computed = 0;
+
+ Real worst_rel_abscissa = 0;
+ Real worst_rel_value = 0;
+ Real worst_rel_computed = 0;
+
+ Real worst_abs_abscissa = 0;
+ Real worst_abs_computed = 0;
+ Real worst_abs_expected = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real t = i*dx_dense;
+ Real computed = phi(t);
+ Real expected = Real(phi_dense[i]);
+ Real abs_diff = abs(computed - expected);
+ Real rel_diff = abs_diff/abs(expected);
+ Real flt_distance = abs(boost::math::float_distance(computed, expected));
+ if (flt_distance > max_flt_distance)
+ {
+ max_flt_distance = flt_distance;
+ worst_flt_abscissa = t;
+ worst_flt_value = expected;
+ worst_flt_computed = computed;
+ }
+ if (expected != 0 && rel_diff > rel_sup)
+ {
+ rel_sup = rel_diff;
+ worst_rel_abscissa = t;
+ worst_rel_value = expected;
+ worst_rel_computed = computed;
+
+ }
+ if (abs_diff > sup)
+ {
+ sup = abs_diff;
+ worst_abs_abscissa = t;
+ worst_abs_computed = computed;
+ worst_abs_expected = expected;
+ }
+ }
+ std::cout << "\t\tFloat distance at r = " << r << " is " << max_flt_distance << ", sup distance = " << sup << ", max relative error = " << rel_sup << "\n";
+ std::cout << "\t\tWorst flt abscissa = " << worst_flt_abscissa << ", worst expected value = " << worst_flt_value << ", computed = " << worst_flt_computed << "\n";
+ std::cout << "\t\tWorst rel abscissa = " << worst_rel_abscissa << ", worst expected value = " << worst_rel_value << ", computed = " << worst_rel_computed << "\n";
+ std::cout << "\t\tWorst abs abscissa = " << worst_abs_abscissa << ", worst expected value = " << worst_abs_computed << ", worst abs value (expected) = " << worst_abs_expected << "\n";
+ }
+ std::cout << "\n\n\n";
+}
+
+template<typename Real, typename PreciseReal, int p>
+void find_best_interpolator()
+{
+ std::string filename = "daubechies_" + std::to_string(p) + "_scaling_convergence.csv";
+ std::ofstream fs{filename};
+ static_assert(sizeof(PreciseReal) >= sizeof(Real), "sizeof(PreciseReal) >= sizeof(Real) is required.");
+ using std::abs;
+ int rmax = 18;
+ std::cout << "Computing phi_dense_precise\n";
+ auto phi_dense_precise = boost::math::daubechies_scaling_dyadic_grid<PreciseReal, p, 0>(rmax);
+ std::vector<Real> phi_dense(phi_dense_precise.size());
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ phi_dense[i] = static_cast<Real>(phi_dense_precise[i]);
+ }
+ phi_dense_precise.resize(0);
+ std::cout << "Done\n";
+
+ Real dx_dense = (2*p-1)/static_cast<Real>(phi_dense.size()-1);
+ fs << std::setprecision(std::numeric_limits<Real>::digits10 + 3);
+ fs << std::fixed;
+ fs << "r, matched_holder, linear, quadratic_b_spline, cubic_b_spline, quintic_b_spline, cubic_hermite, pchip, makima, fo_taylor";
+ if (p==2)
+ {
+ fs << "\n";
+ }
+ else
+ {
+ fs << ", quintic_hermite, second_order_taylor";
+ if (p > 3)
+ {
+ fs << ", third_order_taylor, septic_hermite\n";
+ }
+ else
+ {
+ fs << "\n";
+ }
+ }
+ for (int r = 2; r < 13; ++r)
+ {
+ fs << r << ", ";
+ std::map<Real, std::string> m;
+ auto phi = boost::math::daubechies_scaling_dyadic_grid<Real, p, 0>(r);
+ auto phi_prime = boost::math::daubechies_scaling_dyadic_grid<Real, p, 1>(r);
+
+ std::vector<Real> x(phi.size());
+ Real dx = (2*p-1)/static_cast<Real>(x.size()-1);
+ std::cout << "dx = 1/" << (1 << r) << " = " << dx << "\n";
+ for (size_t i = 0; i < x.size(); ++i)
+ {
+ x[i] = i*dx;
+ }
+
+ {
+ auto phi_copy = phi;
+ auto phi_prime_copy = phi_prime;
+ auto mh = boost::math::detail::matched_holder(std::move(phi_copy), std::move(phi_prime_copy), r, Real(0));
+ Real sup = 0;
+ // call to matched_holder is unchecked, so only go to phi_dense.size() -1.
+ for (size_t i = 0; i < phi_dense.size() - 1; ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - mh(x));
+ if (diff > sup)
+ {
+ sup = diff;
+ }
+ }
+ m.insert({sup, "matched_holder"});
+ fs << sup << ", ";
+ }
+
+
+ {
+ auto linear = [&phi, &dx, &r](Real x)->Real {
+ if (x <= 0 || x >= 2*p-1)
+ {
+ return Real(0);
+ }
+ using std::floor;
+
+ Real y = (1<<r)*x;
+ Real k = floor(y);
+
+ size_t kk = static_cast<size_t>(k);
+
+ Real t = y - k;
+ return (1-t)*phi[kk] + t*phi[kk+1];
+ };
+
+ Real linear_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - linear(x));
+ if (diff > linear_sup)
+ {
+ linear_sup = diff;
+ }
+ }
+ m.insert({linear_sup, "linear interpolation"});
+ fs << linear_sup << ", ";
+ }
+
+
+ {
+ auto qbs = boost::math::interpolators::cardinal_quadratic_b_spline(phi.data(), phi.size(), Real(0), dx, phi_prime.front(), phi_prime.back());
+ Real qbs_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - qbs(x));
+ if (diff > qbs_sup) {
+ qbs_sup = diff;
+ }
+ }
+ m.insert({qbs_sup, "quadratic_b_spline"});
+ fs << qbs_sup << ", ";
+ }
+
+ {
+ auto cbs = boost::math::interpolators::cardinal_cubic_b_spline(phi.data(), phi.size(), Real(0), dx, phi_prime.front(), phi_prime.back());
+ Real cbs_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - cbs(x));
+ if (diff > cbs_sup)
+ {
+ cbs_sup = diff;
+ }
+ }
+ m.insert({cbs_sup, "cubic_b_spline"});
+ fs << cbs_sup << ", ";
+ }
+
+ {
+ auto qbs = boost::math::interpolators::cardinal_quintic_b_spline(phi.data(), phi.size(), Real(0), dx, {0,0}, {0,0});
+ Real qbs_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - qbs(x));
+ if (diff > qbs_sup)
+ {
+ qbs_sup = diff;
+ }
+ }
+ m.insert({qbs_sup, "quintic_b_spline"});
+ fs << qbs_sup << ", ";
+ }
+
+ {
+ auto phi_copy = phi;
+ auto phi_prime_copy = phi_prime;
+ auto ch = boost::math::interpolators::cardinal_cubic_hermite(std::move(phi_copy), std::move(phi_prime_copy), Real(0), dx);
+ Real chs_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - ch(x));
+ if (diff > chs_sup)
+ {
+ chs_sup = diff;
+ }
+ }
+ m.insert({chs_sup, "cubic_hermite_spline"});
+ fs << chs_sup << ", ";
+ }
+
+ {
+ auto phi_copy = phi;
+ auto x_copy = x;
+ auto phi_prime_copy = phi_prime;
+ auto pc = boost::math::interpolators::pchip(std::move(x_copy), std::move(phi_copy));
+ Real pchip_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - pc(x));
+ if (diff > pchip_sup)
+ {
+ pchip_sup = diff;
+ }
+ }
+ m.insert({pchip_sup, "pchip"});
+ fs << pchip_sup << ", ";
+ }
+
+ {
+ auto phi_copy = phi;
+ auto x_copy = x;
+ auto pc = boost::math::interpolators::makima(std::move(x_copy), std::move(phi_copy));
+ Real makima_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i) {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - pc(x));
+ if (diff > makima_sup)
+ {
+ makima_sup = diff;
+ }
+ }
+ m.insert({makima_sup, "makima"});
+ fs << makima_sup << ", ";
+ }
+
+ // Whittaker-Shannon interpolation has linear complexity; test over all points and it's quadratic.
+ // I ran this a couple times and found it's not competitive; so comment out for now.
+ /*{
+ auto phi_copy = phi;
+ auto ws = boost::math::interpolators::whittaker_shannon(std::move(phi_copy), Real(0), dx);
+ Real sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i) {
+ Real x = i*dx_dense;
+ using std::abs;
+ Real diff = abs(phi_dense[i] - ws(x));
+ if (diff > sup) {
+ sup = diff;
+ }
+ }
+
+ m.insert({sup, "whittaker_shannon"});
+ }
+
+ // Again, linear complexity of evaluation => quadratic complexity of exhaustive checking.
+ {
+ auto trig = boost::math::interpolators::cardinal_trigonometric(phi, Real(0), dx);
+ Real sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i) {
+ Real x = i*dx_dense;
+ using std::abs;
+ Real diff = abs(phi_dense[i] - trig(x));
+ if (diff > sup) {
+ sup = diff;
+ }
+ }
+ m.insert({sup, "trig"});
+ }*/
+
+ {
+ auto fotaylor = [&phi, &phi_prime, &r](Real x)->Real
+ {
+ if (x <= 0 || x >= 2*p-1)
+ {
+ return 0;
+ }
+ using std::floor;
+
+ Real y = (1<<r)*x;
+ Real k = floor(y);
+
+ size_t kk = static_cast<size_t>(k);
+ if (y - k < k + 1 - y)
+ {
+ Real eps = (y-k)/(1<<r);
+ return phi[kk] + eps*phi_prime[kk];
+ }
+ else {
+ Real eps = (y-k-1)/(1<<r);
+ return phi[kk+1] + eps*phi_prime[kk+1];
+ }
+ };
+ Real fo_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - fotaylor(x));
+ if (diff > fo_sup)
+ {
+ fo_sup = diff;
+ }
+ }
+ m.insert({fo_sup, "First-order Taylor"});
+ if (p==2)
+ {
+ fs << fo_sup << "\n";
+ }
+ else
+ {
+ fs << fo_sup << ", ";
+ }
+ }
+
+ if constexpr (p > 2) {
+ auto phi_dbl_prime = boost::math::daubechies_scaling_dyadic_grid<Real, p, 2>(r);
+
+ {
+ auto phi_copy = phi;
+ auto phi_prime_copy = phi_prime;
+ auto phi_dbl_prime_copy = phi_dbl_prime;
+ auto qh = boost::math::interpolators::cardinal_quintic_hermite(std::move(phi_copy), std::move(phi_prime_copy), std::move(phi_dbl_prime_copy), Real(0), dx);
+ Real qh_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - qh(x));
+ if (diff > qh_sup)
+ {
+ qh_sup = diff;
+ }
+ }
+ m.insert({qh_sup, "quintic_hermite_spline"});
+ fs << qh_sup << ", ";
+ }
+
+ {
+ auto sotaylor = [&phi, &phi_prime, &phi_dbl_prime, &r](Real x)->Real {
+ if (x <= 0 || x >= 2*p-1)
+ {
+ return 0;
+ }
+ using std::floor;
+
+ Real y = (1<<r)*x;
+ Real k = floor(y);
+
+ size_t kk = static_cast<size_t>(k);
+ if (y - k < k + 1 - y)
+ {
+ Real eps = (y-k)/(1<<r);
+ return phi[kk] + eps*phi_prime[kk] + eps*eps*phi_dbl_prime[kk]/2;
+ }
+ else {
+ Real eps = (y-k-1)/(1<<r);
+ return phi[kk+1] + eps*phi_prime[kk+1] + eps*eps*phi_dbl_prime[kk+1]/2;
+ }
+ };
+ Real so_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - sotaylor(x));
+ if (diff > so_sup)
+ {
+ so_sup = diff;
+ }
+ }
+ m.insert({so_sup, "Second-order Taylor"});
+ if (p > 3)
+ {
+ fs << so_sup << ", ";
+ }
+ else
+ {
+ fs << so_sup << "\n";
+ }
+
+ }
+ }
+
+ if constexpr (p > 3)
+ {
+ auto phi_dbl_prime = boost::math::daubechies_scaling_dyadic_grid<Real, p, 2>(r);
+ auto phi_triple_prime = boost::math::daubechies_scaling_dyadic_grid<Real, p, 3>(r);
+
+ {
+ auto totaylor = [&phi, &phi_prime, &phi_dbl_prime, &phi_triple_prime, &r](Real x)->Real {
+ if (x <= 0 || x >= 2*p-1) {
+ return 0;
+ }
+ using std::floor;
+
+ Real y = (1<<r)*x;
+ Real k = floor(y);
+
+ size_t kk = static_cast<size_t>(k);
+ if (y - k < k + 1 - y)
+ {
+ Real eps = (y-k)/(1<<r);
+ return phi[kk] + eps*phi_prime[kk] + eps*eps*phi_dbl_prime[kk]/2 + eps*eps*eps*phi_triple_prime[kk]/6;
+ }
+ else {
+ Real eps = (y-k-1)/(1<<r);
+ return phi[kk+1] + eps*phi_prime[kk+1] + eps*eps*phi_dbl_prime[kk+1]/2 + eps*eps*eps*phi_triple_prime[kk]/6;
+ }
+ };
+ Real to_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - totaylor(x));
+ if (diff > to_sup)
+ {
+ to_sup = diff;
+ }
+ }
+
+ m.insert({to_sup, "Third-order Taylor"});
+ fs << to_sup << ", ";
+ }
+
+ {
+ auto phi_copy = phi;
+ auto phi_prime_copy = phi_prime;
+ auto phi_dbl_prime_copy = phi_dbl_prime;
+ auto phi_triple_prime_copy = phi_triple_prime;
+ auto sh = boost::math::interpolators::cardinal_septic_hermite(std::move(phi_copy), std::move(phi_prime_copy), std::move(phi_dbl_prime_copy), std::move(phi_triple_prime_copy), Real(0), dx);
+ Real septic_sup = 0;
+ for (size_t i = 0; i < phi_dense.size(); ++i)
+ {
+ Real x = i*dx_dense;
+ Real diff = abs(phi_dense[i] - sh(x));
+ if (diff > septic_sup)
+ {
+ septic_sup = diff;
+ }
+ }
+ m.insert({septic_sup, "septic_hermite_spline"});
+ fs << septic_sup << "\n";
+ }
+
+
+ }
+ std::string best = "none";
+ Real best_sup = 1000000000;
+ std::cout << std::setprecision(std::numeric_limits<Real>::digits10 + 3) << std::fixed;
+ for (auto & e : m)
+ {
+ std::cout << "\t" << e.first << " is error of " << e.second << "\n";
+ if (e.first < best_sup)
+ {
+ best = e.second;
+ best_sup = e.first;
+ }
+ }
+ std::cout << "\tThe best method for p = " << p << " is the " << best << "\n";
+ }
+}
+
+int main()
+{
+ //boost::hana::for_each(std::make_index_sequence<4>(), [&](auto i){ choose_refinement<double, float128, i+16>(); });
+ boost::hana::for_each(std::make_index_sequence<12>(), [&](auto i){ find_best_interpolator<double, float128, i+2>(); });
+}
diff --git a/src/boost/libs/math/example/daubechies_wavelets/regress_daubechies_accuracy.cpp b/src/boost/libs/math/example/daubechies_wavelets/regress_daubechies_accuracy.cpp
new file mode 100644
index 000000000..d7b0f3297
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/regress_daubechies_accuracy.cpp
@@ -0,0 +1,146 @@
+#include <iostream>
+#include <string>
+#include <fstream>
+#include <map>
+#include <cmath>
+#include <vector>
+#include <iomanip>
+#include <boost/algorithm/string.hpp>
+#include <boost/math/statistics/linear_regression.hpp>
+
+
+int main(int argc, char** argv)
+{
+ if (argc != 2)
+ {
+ std::cout << "Usage: ./regress_accuracy.x foo.csv\n";
+ return 1;
+ }
+ std::string filename = std::string(argv[1]);
+ std::ifstream ifs(filename.c_str());
+ if (!ifs.good())
+ {
+ std::cerr << "Couldn't find file " << filename << "\n";
+ return 1;
+ }
+ std::map<std::string, std::vector<double>> m;
+
+ std::string header_line;
+ std::getline(ifs, header_line);
+ std::cout << "Header line = " << header_line << "\n";
+ std::vector<std::string> header_strs;
+ boost::split(header_strs, header_line, boost::is_any_of(","));
+ for (auto & s : header_strs) {
+ boost::algorithm::trim(s);
+ }
+
+ std::string line;
+ std::vector<double> r;
+ std::vector<double> matched_holder;
+ std::vector<double> linear;
+ std::vector<double> quadratic_b_spline;
+ std::vector<double> cubic_b_spline;
+ std::vector<double> quintic_b_spline;
+ std::vector<double> cubic_hermite;
+ std::vector<double> pchip;
+ std::vector<double> makima;
+ std::vector<double> fotaylor;
+ std::vector<double> quintic_hermite;
+ std::vector<double> sotaylor;
+ std::vector<double> totaylor;
+ std::vector<double> septic_hermite;
+ while(std::getline(ifs, line))
+ {
+ std::vector<std::string> strs;
+ boost::split(strs, line, boost::is_any_of(","));
+ for (auto & s : strs)
+ {
+ boost::algorithm::trim(s);
+ }
+ std::vector<double> v(strs.size(), std::numeric_limits<double>::quiet_NaN());
+ for (size_t i = 0; i < v.size(); ++i)
+ {
+ v[i] = std::stod(strs[i]);
+ }
+ r.push_back(v[0]);
+ matched_holder.push_back(std::log2(v[1]));
+ linear.push_back(std::log2(v[2]));
+ quadratic_b_spline.push_back(std::log2(v[3]));
+ cubic_b_spline.push_back(std::log2(v[4]));
+ quintic_b_spline.push_back(std::log2(v[5]));
+ cubic_hermite.push_back(std::log2(v[6]));
+ pchip.push_back(std::log2(v[7]));
+ makima.push_back(std::log2(v[8]));
+ fotaylor.push_back(std::log2(v[9]));
+ if (v.size() > 10) {
+ quintic_hermite.push_back(std::log2(v[10]));
+ sotaylor.push_back(std::log2(v[11]));
+ }
+ if (v.size() > 12) {
+ totaylor.push_back(std::log2(v[12]));
+ septic_hermite.push_back(std::log2(v[13]));
+ }
+ }
+
+ std::cout << std::fixed << std::setprecision(16);
+ auto q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, matched_holder);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Matched Holder : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, linear);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Linear : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, quadratic_b_spline);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Quadratic B-spline: " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, cubic_b_spline);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Cubic B-spline : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, quintic_b_spline);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Quintic B-spline : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, cubic_hermite);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Cubic Hermite : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, pchip);
+ assert(std::get<1>(q) < 0);
+ std::cout << "PCHIP : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, makima);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Makima : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, fotaylor);
+ assert(std::get<1>(q) < 0);
+ std::cout << "First-order Taylor: " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ if (sotaylor.size() > 0)
+ {
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, quintic_hermite);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Quintic Hermite : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, sotaylor);
+ assert(std::get<1>(q) < 0);
+ std::cout << "2nd order Taylor : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ }
+
+ if (totaylor.size() > 0)
+ {
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, totaylor);
+ assert(std::get<1>(q) < 0);
+ std::cout << "3rd order Taylor : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ q = boost::math::statistics::simple_ordinary_least_squares_with_R_squared(r, septic_hermite);
+ assert(std::get<1>(q) < 0);
+ std::cout << "Septic Hermite : " << std::get<0>(q) << " - " << std::abs(std::get<1>(q)) << "r, R^2 = " << std::get<2>(q) << "\n";
+
+ }
+
+} \ No newline at end of file
diff --git a/src/boost/libs/math/example/daubechies_wavelets/wavelet_transform.cpp b/src/boost/libs/math/example/daubechies_wavelets/wavelet_transform.cpp
new file mode 100644
index 000000000..67cdde803
--- /dev/null
+++ b/src/boost/libs/math/example/daubechies_wavelets/wavelet_transform.cpp
@@ -0,0 +1,46 @@
+/*
+ * Copyright Nick Thompson, 2020
+ * 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)
+ */
+#include <cstdint>
+#include <cmath>
+#include <boost/math/quadrature/wavelet_transforms.hpp>
+#include <Eigen/Dense>
+
+
+int main()
+{
+ using boost::math::quadrature::daubechies_wavelet_transform;
+ double a = 1.3;
+ auto f = [&a](double t) {
+ if(t==0) {
+ return double(0);
+ }
+ return std::sin(a/t);
+ };
+
+ auto Wf = daubechies_wavelet_transform<decltype(f), double, 8>(f);
+
+ Eigen::MatrixXd grid(512, 512);
+ double s = 7;
+ double t = 0;
+ grid(0,0) = Wf(s, t);
+
+ auto g = [&a](double t)->std::complex<double> {
+ if (t==0) {
+ return {0.0, 0.0};
+ }
+ return std::exp(std::complex<double>(0.0, a/t));
+ };
+
+ auto Wg = daubechies_wavelet_transform<decltype(g), double, 8>(g);
+ std::cout << "W[f](s,t) = " << Wf(s,t) << "\n";
+ std::cout << "W[g](s,t) = " << Wg(s, t) << "\n";
+ std::cout << Wg(0.0, 3.5) << "\n";
+ std::cout << Wf(0.0, 4.8) << "\n";
+ std::cout << "W[f](-s,t) = " << Wf(-s, t) << "\n";
+ std::cout << "W[g](-s,t) = " << Wg(-s, t) << "\n";
+
+}
diff --git a/src/boost/libs/math/example/distribution_construction.cpp b/src/boost/libs/math/example/distribution_construction.cpp
new file mode 100644
index 000000000..a3d1a635d
--- /dev/null
+++ b/src/boost/libs/math/example/distribution_construction.cpp
@@ -0,0 +1,295 @@
+// distribution_construction.cpp
+
+// Copyright Paul A. Bristow 2007, 2010, 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)
+
+// Caution: this file contains Quickbook markup as well as code
+// and comments, don't change any of the special comment markups!
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4996) // disable -D_SCL_SECURE_NO_WARNINGS C++ 'Checked Iterators'
+#endif
+
+#include <iostream>
+#include <exception>
+
+//[distribution_construction_1
+
+/*`
+The structure of distributions is rather different from some other statistical libraries,
+for example, those written in less object-oriented language like FORTRAN and C that
+provide a few arguments to each free function.
+
+Boost.Math library instead provides each distribution as a template C++ class.
+A distribution is constructed with a few arguments, and then
+member and non-member functions are used to find values of the
+distribution, often a function of a random variate.
+
+For this demonstration, first we need some includes to access the
+negative binomial distribution (and the binomial, beta and gamma distributions too).
+
+To demonstrate the use with a high precision User-defined floating-point type
+`cpp_bin_float`, we also need an include from Boost.Multiprecision.
+(We could equally well have used a `cpp_dec_float` multiprecision type).
+
+We choose a typedef `cpp_bin_float_50` to provide a 50 decimal digit type,
+but we could equally have chosen at 128-bit type `cpp_bin_float_quad`,
+or on some platforms `__float128`, providing about 35 decimal digits.
+*/
+
+#include <boost/math/distributions/negative_binomial.hpp> // for negative_binomial_distribution
+ using boost::math::negative_binomial_distribution; // default type is double.
+ using boost::math::negative_binomial; // typedef provides default type is double.
+#include <boost/math/distributions/binomial.hpp> // for binomial_distribution.
+#include <boost/math/distributions/beta.hpp> // for beta_distribution.
+#include <boost/math/distributions/gamma.hpp> // for gamma_distribution.
+#include <boost/math/distributions/normal.hpp> // for normal_distribution.
+
+#include <boost/multiprecision/cpp_bin_float.hpp> // for cpp_bin_float_50
+/*`
+Several examples of constructing distributions follow:
+*/
+//] [/distribution_construction_1 end of Quickbook in C++ markup]
+
+int main()
+{
+ try
+ {
+//[distribution_construction_2
+/*`
+First, a negative binomial distribution with 8 successes
+and a success fraction 0.25, 25% or 1 in 4, is constructed like this:
+*/
+ boost::math::negative_binomial_distribution<double> mydist0(8., 0.25);
+ /*`
+ But this is inconveniently long, so we might be tempted to write
+ */
+ using namespace boost::math;
+ /*`
+ but this might risk ambiguity with names in `std random` so
+ [*much] better is explicit `using boost::math::` statements, for example:
+ */
+ using boost::math::negative_binomial_distribution;
+ /*`
+ and we can still reduce typing.
+
+ Since the vast majority of applications use will be using `double` precision,
+ the template argument to the distribution (`RealType`) defaults
+ to type `double`, so we can also write:
+ */
+
+ negative_binomial_distribution<> mydist9(8., 0.25); // Uses default `RealType = double`.
+
+ /*`
+ But the name `negative_binomial_distribution` is still inconveniently long,
+ so, for most distributions, a convenience `typedef` is provided, for example:
+
+ typedef negative_binomial_distribution<double> negative_binomial; // Reserved name of type double.
+
+ [caution
+ This convenience typedef is [*not provided] if a clash would occur
+ with the name of a function; currently only `beta` and `gamma`
+ fall into this category.
+ ]
+
+ So, after a using statement,
+ */
+
+ using boost::math::negative_binomial;
+
+ /*`
+ we have a convenient typedef to `negative_binomial_distribution<double>`:
+ */
+ negative_binomial mydist(8., 0.25);
+
+ /*`
+ Some more examples using the convenience typedef:
+ */
+ negative_binomial mydist10(5., 0.4); // Both arguments double.
+ /*`
+ And automatic conversion of arguments takes place, so you can use integers and floats:
+ */
+ negative_binomial mydist11(5, 0.4); // Using provided typedef of type double, and int and double arguments.
+ /*`
+ This is probably the most common usage.
+ Other combination are possible too:
+ */
+ negative_binomial mydist12(5., 0.4F); // Double and float arguments.
+ negative_binomial mydist13(5, 1); // Both arguments integer.
+
+ /*`
+ Similarly for most other distributions like the binomial.
+ */
+ binomial mybinomial(1, 0.5); // is more concise than
+ binomial_distribution<> mybinomd1(1, 0.5);
+
+ /*`
+ For cases when the typdef distribution name would clash with a math special function
+ (currently only beta and gamma)
+ the typedef is deliberately not provided, and the longer version of the name
+ must be used, so for example, do not use:
+
+ using boost::math::beta;
+ beta mybetad0(1, 0.5); // Error beta is a math FUNCTION!
+
+ Which produces the error messages:
+
+ [pre
+ error C2146: syntax error : missing ';' before identifier 'mybetad0'
+ warning C4551: function call missing argument list
+ error C3861: 'mybetad0': identifier not found
+ ]
+
+ Instead you should use:
+ */
+ using boost::math::beta_distribution;
+ beta_distribution<> mybetad1(1, 0.5);
+ /*`
+ or for the gamma distribution:
+ */
+ gamma_distribution<> mygammad1(1, 0.5);
+
+ /*`
+ We can, of course, still provide the type explicitly thus:
+ */
+
+ // Explicit double precision: both arguments are double:
+ negative_binomial_distribution<double> mydist1(8., 0.25);
+
+ // Explicit float precision, double arguments are truncated to float:
+ negative_binomial_distribution<float> mydist2(8., 0.25);
+
+ // Explicit float precision, integer & double arguments converted to float:
+ negative_binomial_distribution<float> mydist3(8, 0.25);
+
+ // Explicit float precision, float arguments, so no conversion:
+ negative_binomial_distribution<float> mydist4(8.F, 0.25F);
+
+ // Explicit float precision, integer arguments promoted to float.
+ negative_binomial_distribution<float> mydist5(8, 1);
+
+ // Explicit double precision:
+ negative_binomial_distribution<double> mydist6(5., 0.4);
+
+ // Explicit long double precision:
+ negative_binomial_distribution<long double> mydist7(8., 0.25);
+
+ /*`
+ And you can use your own template RealType,
+ for example, `boost::math::cpp_bin_float_50` (an arbitrary 50 decimal digits precision type),
+ then we can write:
+ */
+ using namespace boost::multiprecision;
+ negative_binomial_distribution<cpp_bin_float_50> mydist8(8, 0.25);
+
+ // `integer` arguments are promoted to your RealType exactly, but
+ // `double` argument are converted to RealType,
+ // most likely losing precision!
+
+ // So DON'T be tempted to write the 'obvious':
+ negative_binomial_distribution<cpp_bin_float_50> mydist20(8, 0.23456789012345678901234567890);
+ // to avoid truncation of second parameter to `0.2345678901234567` and loss of precision.
+
+ // Instead pass a quoted decimal digit string:
+ negative_binomial_distribution<cpp_bin_float_50> mydist21(8, cpp_bin_float_50("0.23456789012345678901234567890") );
+
+ // Ensure that all potentially significant digits are shown.
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::digits10);
+ //
+ cpp_bin_float_50 x("1.23456789012345678901234567890");
+ std::cout << pdf(mydist8, x) << std::endl;
+/*` showing 0.00012630010495970320103876754721976419438231705359935
+ 0.00012630010495970320103876754721976419438231528547467
+
+[warning When using multiprecision, it is all too easy to get accidental truncation!]
+
+For example, if you write
+*/
+ std::cout << pdf(mydist8, 1.23456789012345678901234567890) << std::endl;
+/*`
+showing 0.00012630010495970318465064569310967179576805651692929,
+which is wrong at about the 17th decimal digit!
+
+This is because the value provided is truncated to a `double`, effectively
+ `double x = 1.23456789012345678901234567890;`
+
+Then the now `double x` is passed to function `pdf`,
+and this truncated `double` value is finally promoted to `cpp_bin_float_50`.
+
+Another way of quietly getting the wrong answer is to write:
+*/
+ std::cout << pdf(mydist8, cpp_bin_float_50(1.23456789012345678901234567890)) << std::endl;
+/*`
+A correct way from a multi-digit string value is
+*/
+ std::cout << pdf(mydist8, cpp_bin_float_50("1.23456789012345678901234567890")) << std::endl;
+/*`
+
+[tip Getting about 17 decimal digits followed by many zeros is often a sign of accidental truncation.]
+*/
+
+/*`
+[h4 Default arguments to distribution constructors.]
+
+Note that default constructor arguments are only provided for some distributions.
+So if you wrongly assume a default argument, you will get an error message, for example:
+
+ negative_binomial_distribution<> mydist8;
+
+[pre error C2512 no appropriate default constructor available.]
+
+No default constructors are provided for the `negative binomial` distribution,
+because it is difficult to chose any sensible default values for this distribution.
+
+For other distributions, like the normal distribution,
+it is obviously very useful to provide 'standard'
+defaults for the mean (zero) and standard deviation (unity) thus:
+
+ normal_distribution(RealType mean = 0, RealType sd = 1);
+
+So in this case we can more tersely write:
+*/
+ using boost::math::normal;
+
+ normal norm1; // Standard normal distribution N[0,1].
+ normal norm2(2); // Mean = 2, std deviation = 1.
+ normal norm3(2, 3); // Mean = 2, std deviation = 3.
+
+ }
+ catch(std::exception &ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+
+ return 0;
+} // int main()
+
+/*`There is no useful output from this demonstration program, of course. */
+
+//] [/end of distribution_construction_2]
+
+/*
+//[distribution_construction_output
+
+ 0.00012630010495970320103876754721976419438231705359935
+ 0.00012630010495970318465064569310967179576805651692929
+ 0.00012630010495970318465064569310967179576805651692929
+ 0.00012630010495970320103876754721976419438231705359935
+
+//] [/distribution_construction_output]
+
+
+ 0.00012630010495970320103876754721976419438231528547467
+ 0.0001263001049597031846506456931096717957680547488046
+ 0.0001263001049597031846506456931096717957680547488046
+ 0.00012630010495970320103876754721976419438231528547467
+
+
+*/
+
+
+
diff --git a/src/boost/libs/math/example/double_exponential.cpp b/src/boost/libs/math/example/double_exponential.cpp
new file mode 100644
index 000000000..87e21b187
--- /dev/null
+++ b/src/boost/libs/math/example/double_exponential.cpp
@@ -0,0 +1,59 @@
+// Copyright Nick Thompson, 2017
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <cmath>
+#include <boost/math/quadrature/tanh_sinh.hpp>
+#include <boost/math/quadrature/sinh_sinh.hpp>
+#include <boost/math/quadrature/exp_sinh.hpp>
+
+using boost::math::quadrature::tanh_sinh;
+using boost::math::quadrature::sinh_sinh;
+using boost::math::quadrature::exp_sinh;
+using boost::math::constants::pi;
+using boost::math::constants::half_pi;
+using boost::math::constants::half;
+using boost::math::constants::third;
+using boost::math::constants::root_pi;
+using std::log;
+using std::cos;
+using std::cosh;
+using std::exp;
+using std::sqrt;
+
+int main()
+{
+ std::cout << std::setprecision(std::numeric_limits<double>::digits10);
+ double tol = sqrt(std::numeric_limits<double>::epsilon());
+ // For an integral over a finite domain, use tanh_sinh:
+ tanh_sinh<double> tanh_integrator(tol, 10);
+ auto f1 = [](double x) { return log(x)*log(1-x); };
+ double Q = tanh_integrator.integrate(f1, (double) 0, (double) 1);
+ double Q_expected = 2 - pi<double>()*pi<double>()*half<double>()*third<double>();
+
+ std::cout << "tanh_sinh quadrature of log(x)log(1-x) gives " << Q << std::endl;
+ std::cout << "The exact integral is " << Q_expected << std::endl;
+
+ // For an integral over the entire real line, use sinh-sinh quadrature:
+ sinh_sinh<double> sinh_integrator(tol, 10);
+ auto f2 = [](double t) { return cos(t)/cosh(t);};
+ Q = sinh_integrator.integrate(f2);
+ Q_expected = pi<double>()/cosh(half_pi<double>());
+ std::cout << "sinh_sinh quadrature of cos(x)/cosh(x) gives " << Q << std::endl;
+ std::cout << "The exact integral is " << Q_expected << std::endl;
+
+ // For half-infinite intervals, use exp-sinh.
+ // Endpoint singularities are handled well:
+ exp_sinh<double> exp_integrator(tol, 10);
+ auto f3 = [](double t) { return exp(-t)/sqrt(t); };
+ Q = exp_integrator.integrate(f3, 0, std::numeric_limits<double>::infinity());
+ Q_expected = root_pi<double>();
+ std::cout << "exp_sinh quadrature of exp(-t)/sqrt(t) gives " << Q << std::endl;
+ std::cout << "The exact integral is " << Q_expected << std::endl;
+
+
+
+}
diff --git a/src/boost/libs/math/example/error_handling_example.cpp b/src/boost/libs/math/example/error_handling_example.cpp
new file mode 100644
index 000000000..24543cdfa
--- /dev/null
+++ b/src/boost/libs/math/example/error_handling_example.cpp
@@ -0,0 +1,153 @@
+// example_error_handling.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+// Copyright John Maddock 2007.
+
+// 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)
+
+// Note that this file contains quickbook markup as well as code
+// and comments, don't change any of the special comment markups!
+
+// Optional macro definitions described in text below:
+// #define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
+// #define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
+// #define BOOST_MATH_DOMAIN_ERROR_POLICY is set to: throw_on_error
+
+//[error_handling_example
+/*`
+The following example demonstrates the effect of
+setting the macro BOOST_MATH_DOMAIN_ERROR_POLICY
+when an invalid argument is encountered. For the
+purposes of this example, we'll pass a negative
+degrees of freedom parameter to the student's t
+distribution.
+
+Since we know that this is a single file program we could
+just add:
+
+ #define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
+
+to the top of the source file to change the default policy
+to one that simply returns a NaN when a domain error occurs.
+Alternatively we could use:
+
+ #define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
+
+To ensure the `::errno` is set when a domain error occurs
+as well as returning a NaN.
+
+This is safe provided the program consists of a single
+translation unit /and/ we place the define /before/ any
+#includes. Note that should we add the define after the includes
+then it will have no effect! A warning such as:
+
+[pre warning C4005: 'BOOST_MATH_OVERFLOW_ERROR_POLICY' : macro redefinition]
+
+is a certain sign that it will /not/ have the desired effect.
+
+We'll begin our sample program with the needed includes:
+*/
+
+
+ #define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
+
+// Boost
+#include <boost/math/distributions/students_t.hpp>
+ using boost::math::students_t; // Probability of students_t(df, t).
+
+// std
+#include <iostream>
+ using std::cout;
+ using std::endl;
+
+#include <stdexcept>
+
+
+#include <cstddef>
+ // using ::errno
+
+/*`
+Next we'll define the program's main() to call the student's t
+distribution with an invalid degrees of freedom parameter,
+the program is set up to handle either an exception or a NaN:
+*/
+
+int main()
+{
+ cout << "Example error handling using Student's t function. " << endl;
+ cout << "BOOST_MATH_DOMAIN_ERROR_POLICY is set to: "
+ << BOOST_STRINGIZE(BOOST_MATH_DOMAIN_ERROR_POLICY) << endl;
+
+ double degrees_of_freedom = -1; // A bad argument!
+ double t = 10;
+
+ try
+ {
+ errno = 0; // Clear/reset.
+ students_t dist(degrees_of_freedom); // exception is thrown here if enabled.
+ double p = cdf(dist, t);
+ // Test for error reported by other means:
+ if((boost::math::isnan)(p))
+ {
+ cout << "cdf returned a NaN!" << endl;
+ if (errno != 0)
+ { // So errno has been set.
+ cout << "errno is set to: " << errno << endl;
+ }
+ }
+ else
+ cout << "Probability of Student's t is " << p << endl;
+ }
+ catch(const std::exception& e)
+ {
+ std::cout <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+/*`
+
+Here's what the program output looks like with a default build
+(one that *does throw exceptions*):
+
+[pre
+Example error handling using Student's t function.
+BOOST_MATH_DOMAIN_ERROR_POLICY is set to: throw_on_error
+
+Message from thrown exception was:
+ Error in function boost::math::students_t_distribution<double>::students_t_distribution:
+ Degrees of freedom argument is -1, but must be > 0 !
+]
+
+Alternatively let's build with:
+
+ #define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
+
+Now the program output is:
+
+[pre
+Example error handling using Student's t function.
+BOOST_MATH_DOMAIN_ERROR_POLICY is set to: ignore_error
+cdf returned a NaN!
+]
+
+And finally let's build with:
+
+ #define BOOST_MATH_DOMAIN_ERROR_POLICY errno_on_error
+
+Which gives the output show errno:
+
+[pre
+Example error handling using Student's t function.
+BOOST_MATH_DOMAIN_ERROR_POLICY is set to: errno_on_error
+cdf returned a NaN!
+errno is set to: 33
+]
+
+*/
+
+//] [error_handling_eg end quickbook markup]
diff --git a/src/boost/libs/math/example/error_policies_example.cpp b/src/boost/libs/math/example/error_policies_example.cpp
new file mode 100644
index 000000000..289d1016b
--- /dev/null
+++ b/src/boost/libs/math/example/error_policies_example.cpp
@@ -0,0 +1,105 @@
+// error_policies_example.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+// Copyright John Maddock 2007.
+
+// 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)
+
+#include <boost/math/distributions/normal.hpp>
+ using boost::math::normal_distribution;
+
+#include <boost/math/distributions/students_t.hpp>
+ using boost::math::students_t; // Probability of students_t(df, t).
+ using boost::math::students_t_distribution;
+
+// using namespace boost::math; causes:
+//.\error_policy_normal.cpp(30) : error C2872: 'policy' : ambiguous symbol
+// could be '\boost/math/policies/policy.hpp(392) : boost::math::policies::policy'
+// or 'boost::math::policies'
+
+// So should not use this 'using namespace boost::math;' command.
+
+// Suppose we want a statistical distribution to return infinities,
+// rather than throw exceptions (the default policy), then we can use:
+
+// std
+#include <iostream>
+ using std::cout;
+ using std::endl;
+
+// using namespace boost::math::policies; or
+
+using boost::math::policies::policy;
+// Possible errors
+using boost::math::policies::overflow_error;
+using boost::math::policies::underflow_error;
+using boost::math::policies::domain_error;
+using boost::math::policies::pole_error;
+using boost::math::policies::denorm_error;
+using boost::math::policies::evaluation_error;
+using boost::math::policies::ignore_error;
+
+// Define a custom policy to ignore just overflow:
+typedef policy<
+overflow_error<ignore_error>
+ > my_policy;
+
+// Define another custom policy (perhaps ill-advised?)
+// to ignore all errors: domain, pole, overflow, underflow, denorm & evaluation:
+typedef policy<
+domain_error<ignore_error>,
+pole_error<ignore_error>,
+overflow_error<ignore_error>,
+underflow_error<ignore_error>,
+denorm_error<ignore_error>,
+evaluation_error<ignore_error>
+ > my_ignoreall_policy;
+
+// Define a new distribution with a custom policy to ignore_error
+// (& thus perhaps return infinity for some arguments):
+typedef boost::math::normal_distribution<double, my_policy> my_normal;
+// Note: uses default parameters zero mean and unit standard deviation.
+
+// We could also do the same for another distribution, for example:
+using boost::math::students_t_distribution;
+typedef students_t_distribution<double, my_ignoreall_policy> my_students_t;
+
+int main()
+{
+ cout << "quantile(my_normal(), 0.05); = " << quantile(my_normal(), 0.05) << endl; // 0.05 is argument within normal range.
+ cout << "quantile(my_normal(), 0.); = " << quantile(my_normal(), 0.) << endl; // argument zero, so expect infinity.
+ cout << "quantile(my_normal(), 0.); = " << quantile(my_normal(), 0.F) << endl; // argument zero, so expect infinity.
+
+ cout << "quantile(my_students_t(), 0.); = " << quantile(my_students_t(-1), 0.F) << endl; // 'bad' argument negative, so expect NaN.
+
+#ifndef BOOST_MATH_NO_LONG_DOUBLE_MATH_FUNCTIONS
+ // Construct a (0, 1) normal distribution that ignores all errors,
+ // returning NaN, infinity, zero, or best guess,
+ // and NOT setting errno.
+ normal_distribution<long double, my_ignoreall_policy> my_normal2(0.L, 1.L); // explicit parameters for distribution.
+ cout << "quantile(my_normal2(), 0.); = " << quantile(my_normal2, 0.01) << endl; // argument 0.01, so result finite.
+ cout << "quantile(my_normal2(), 0.); = " << quantile(my_normal2, 0.) << endl; // argument zero, so expect infinity.
+#endif
+
+ return 0;
+}
+
+/*
+
+Output:
+
+error_policies_example.cpp
+ Generating code
+ Finished generating code
+ error_policy_normal_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\error_policies_example.exe
+ quantile(my_normal(), 0.05); = -1.64485
+ quantile(my_normal(), 0.); = -1.#INF
+ quantile(my_normal(), 0.); = -1.#INF
+ quantile(my_students_t(), 0.); = 1.#QNAN
+ quantile(my_normal2(), 0.); = -2.32635
+ quantile(my_normal2(), 0.); = -1.#INF
+
+*/
diff --git a/src/boost/libs/math/example/error_policy_example.cpp b/src/boost/libs/math/example/error_policy_example.cpp
new file mode 100644
index 000000000..37cb51633
--- /dev/null
+++ b/src/boost/libs/math/example/error_policy_example.cpp
@@ -0,0 +1,93 @@
+// example_policy_handling.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+// Copyright John Maddock 2007.
+
+// 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)
+
+// See error_handling_example.cpp for use of
+// macro definition to change policy for
+// domain_error - negative degrees of freedom argument
+// for student's t distribution CDF,
+// and catching the exception.
+
+// See error_handling_policies.cpp for more examples.
+
+// Boost
+#include <boost/math/distributions/students_t.hpp>
+using boost::math::students_t_distribution; // Probability of students_t(df, t).
+using boost::math::students_t; // Probability of students_t(df, t) convenience typedef for double.
+
+using boost::math::policies::policy;
+using boost::math::policies::domain_error;
+using boost::math::policies::ignore_error;
+
+// std
+#include <iostream>
+ using std::cout;
+ using std::endl;
+
+#include <stdexcept>
+
+
+// Define a (bad?) policy to ignore domain errors ('bad' arguments):
+typedef policy<
+ domain_error<ignore_error>
+ > my_policy;
+
+// Define my_students_t distribution with this different domain error policy:
+typedef students_t_distribution<double, my_policy> my_students_t;
+
+int main()
+{ // Example of error handling of bad argument(s) to a distribution.
+ cout << "Example error handling using Student's t function. " << endl;
+
+ double degrees_of_freedom = -1; double t = -1.; // Two 'bad' arguments!
+
+ try
+ {
+ cout << "Probability of ignore_error Student's t is "
+ << cdf(my_students_t(degrees_of_freedom), t) << endl;
+ cout << "Probability of default error policy Student's t is " << endl;
+ // By contrast the students_t distribution default domain error policy is to throw,
+ cout << cdf(students_t(-1), -1) << endl; // so this will throw.
+/*`
+ Message from thrown exception was:
+ Error in function boost::math::students_t_distribution<double>::students_t_distribution:
+ Degrees of freedom argument is -1, but must be > 0 !
+*/
+
+ // We could also define a 'custom' distribution
+ // with an "ignore overflow error policy" in a single statement:
+ using boost::math::policies::overflow_error;
+ students_t_distribution<double, policy<overflow_error<ignore_error> > > students_t_no_throw(-1);
+
+ }
+ catch(const std::exception& e)
+ {
+ std::cout <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+
+ return 0;
+} // int main()
+
+/*
+
+Output:
+
+ error_policy_example.cpp
+ Generating code
+ Finished generating code
+ error_policy_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\error_policy_example.exe
+ Example error handling using Student's t function.
+ Probability of ignore_error Student's t is 1.#QNAN
+ Probability of default error policy Student's t is
+
+ Message from thrown exception was:
+ Error in function boost::math::students_t_distribution<double>::students_t_distribution: Degrees of freedom argument is -1, but must be > 0 !
+
+*/
diff --git a/src/boost/libs/math/example/f_test.cpp b/src/boost/libs/math/example/f_test.cpp
new file mode 100644
index 000000000..f7fabdee3
--- /dev/null
+++ b/src/boost/libs/math/example/f_test.cpp
@@ -0,0 +1,250 @@
+// Copyright John Maddock 2006
+// Copyright Paul A. Bristow 2007, 2008, 2010
+
+// 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)
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4512) // assignment operator could not be generated.
+# pragma warning(disable: 4510) // default constructor could not be generated.
+# pragma warning(disable: 4610) // can never be instantiated - user defined constructor required.
+# pragma warning(disable: 4180) // qualifier has no effect (in Fusion).
+#endif
+
+#include <iostream>
+using std::cout; using std::endl;
+using std::left; using std::fixed; using std::right; using std::scientific;
+#include <iomanip>
+using std::setw;
+using std::setprecision;
+
+#include <boost/math/distributions/fisher_f.hpp>
+
+void f_test(
+ double sd1, // Sample 1 std deviation
+ double sd2, // Sample 2 std deviation
+ double N1, // Sample 1 size
+ double N2, // Sample 2 size
+ double alpha) // Significance level
+{
+ //
+ // An F test applied to two sets of data.
+ // We are testing the null hypothesis that the
+ // standard deviation of the samples is equal, and
+ // that any variation is down to chance. We can
+ // also test the alternative hypothesis that any
+ // difference is not down to chance.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda359.htm
+ //
+ // Avoid "using namespace boost::math;" because of potential name ambiguity.
+ using boost::math::fisher_f;
+
+ // Print header:
+ cout <<
+ "____________________________________\n"
+ "F test for equal standard deviations\n"
+ "____________________________________\n\n";
+ cout << setprecision(5);
+ cout << "Sample 1:\n";
+ cout << setw(55) << left << "Number of Observations" << "= " << N1 << "\n";
+ cout << setw(55) << left << "Sample Standard Deviation" << "= " << sd1 << "\n\n";
+ cout << "Sample 2:\n";
+ cout << setw(55) << left << "Number of Observations" << "= " << N2 << "\n";
+ cout << setw(55) << left << "Sample Standard Deviation" << "= " << sd2 << "\n\n";
+ //
+ // Now we can calculate and output some stats:
+ //
+ // F-statistic:
+ double F = (sd1 / sd2);
+ F *= F;
+ cout << setw(55) << left << "Test Statistic" << "= " << F << "\n\n";
+ //
+ // Finally define our distribution, and get the probability:
+ //
+ fisher_f dist(N1 - 1, N2 - 1);
+ double p = cdf(dist, F);
+ cout << setw(55) << left << "CDF of test statistic: " << "= "
+ << setprecision(3) << scientific << p << "\n";
+ double ucv = quantile(complement(dist, alpha));
+ double ucv2 = quantile(complement(dist, alpha / 2));
+ double lcv = quantile(dist, alpha);
+ double lcv2 = quantile(dist, alpha / 2);
+ cout << setw(55) << left << "Upper Critical Value at alpha: " << "= "
+ << setprecision(3) << scientific << ucv << "\n";
+ cout << setw(55) << left << "Upper Critical Value at alpha/2: " << "= "
+ << setprecision(3) << scientific << ucv2 << "\n";
+ cout << setw(55) << left << "Lower Critical Value at alpha: " << "= "
+ << setprecision(3) << scientific << lcv << "\n";
+ cout << setw(55) << left << "Lower Critical Value at alpha/2: " << "= "
+ << setprecision(3) << scientific << lcv2 << "\n\n";
+ //
+ // Finally print out results of null and alternative hypothesis:
+ //
+ cout << setw(55) << left <<
+ "Results for Alternative Hypothesis and alpha" << "= "
+ << setprecision(4) << fixed << alpha << "\n\n";
+ cout << "Alternative Hypothesis Conclusion\n";
+ cout << "Standard deviations are unequal (two sided test) ";
+ if((ucv2 < F) || (lcv2 > F))
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Standard deviation 1 is less than standard deviation 2 ";
+ if(lcv > F)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Standard deviation 1 is greater than standard deviation 2 ";
+ if(ucv < F)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << endl << endl;
+}
+
+int main()
+{
+ //
+ // Run tests for ceramic strength data:
+ // see http://www.itl.nist.gov/div898/handbook/eda/section4/eda42a1.htm
+ // The data for this case study were collected by Said Jahanmir of the
+ // NIST Ceramics Division in 1996 in connection with a NIST/industry
+ // ceramics consortium for strength optimization of ceramic strength.
+ //
+ f_test(65.54909, 61.85425, 240, 240, 0.05);
+ //
+ // And again for the process change comparison:
+ // see http://www.itl.nist.gov/div898/handbook/prc/section3/prc32.htm
+ // A new procedure to assemble a device is introduced and tested for
+ // possible improvement in time of assembly. The question being addressed
+ // is whether the standard deviation of the new assembly process (sample 2) is
+ // better (i.e., smaller) than the standard deviation for the old assembly
+ // process (sample 1).
+ //
+ f_test(4.9082, 2.5874, 11, 9, 0.05);
+ return 0;
+}
+
+/*
+
+Output:
+
+ f_test.cpp
+ F-test_example1.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Debug\F_test_example1.exe
+ ____________________________________
+ F test for equal standard deviations
+ ____________________________________
+
+ Sample 1:
+ Number of Observations = 240
+ Sample Standard Deviation = 65.549
+
+ Sample 2:
+ Number of Observations = 240
+ Sample Standard Deviation = 61.854
+
+ Test Statistic = 1.123
+
+ CDF of test statistic: = 8.148e-001
+ Upper Critical Value at alpha: = 1.238e+000
+ Upper Critical Value at alpha/2: = 1.289e+000
+ Lower Critical Value at alpha: = 8.080e-001
+ Lower Critical Value at alpha/2: = 7.756e-001
+
+ Results for Alternative Hypothesis and alpha = 0.0500
+
+ Alternative Hypothesis Conclusion
+ Standard deviations are unequal (two sided test) REJECTED
+ Standard deviation 1 is less than standard deviation 2 REJECTED
+ Standard deviation 1 is greater than standard deviation 2 REJECTED
+
+
+ ____________________________________
+ F test for equal standard deviations
+ ____________________________________
+
+ Sample 1:
+ Number of Observations = 11.00000
+ Sample Standard Deviation = 4.90820
+
+ Sample 2:
+ Number of Observations = 9.00000
+ Sample Standard Deviation = 2.58740
+
+ Test Statistic = 3.59847
+
+ CDF of test statistic: = 9.589e-001
+ Upper Critical Value at alpha: = 3.347e+000
+ Upper Critical Value at alpha/2: = 4.295e+000
+ Lower Critical Value at alpha: = 3.256e-001
+ Lower Critical Value at alpha/2: = 2.594e-001
+
+ Results for Alternative Hypothesis and alpha = 0.0500
+
+ Alternative Hypothesis Conclusion
+ Standard deviations are unequal (two sided test) REJECTED
+ Standard deviation 1 is less than standard deviation 2 REJECTED
+ Standard deviation 1 is greater than standard deviation 2 NOT REJECTED
+
+
+ ____________________________________
+ F test for equal standard deviations
+ ____________________________________
+
+ Sample 1:
+ Number of Observations = 240
+ Sample Standard Deviation = 65.549
+
+ Sample 2:
+ Number of Observations = 240
+ Sample Standard Deviation = 61.854
+
+ Test Statistic = 1.123
+
+ CDF of test statistic: = 8.148e-001
+ Upper Critical Value at alpha: = 1.238e+000
+ Upper Critical Value at alpha/2: = 1.289e+000
+ Lower Critical Value at alpha: = 8.080e-001
+ Lower Critical Value at alpha/2: = 7.756e-001
+
+ Results for Alternative Hypothesis and alpha = 0.0500
+
+ Alternative Hypothesis Conclusion
+ Standard deviations are unequal (two sided test) REJECTED
+ Standard deviation 1 is less than standard deviation 2 REJECTED
+ Standard deviation 1 is greater than standard deviation 2 REJECTED
+
+
+ ____________________________________
+ F test for equal standard deviations
+ ____________________________________
+
+ Sample 1:
+ Number of Observations = 11.00000
+ Sample Standard Deviation = 4.90820
+
+ Sample 2:
+ Number of Observations = 9.00000
+ Sample Standard Deviation = 2.58740
+
+ Test Statistic = 3.59847
+
+ CDF of test statistic: = 9.589e-001
+ Upper Critical Value at alpha: = 3.347e+000
+ Upper Critical Value at alpha/2: = 4.295e+000
+ Lower Critical Value at alpha: = 3.256e-001
+ Lower Critical Value at alpha/2: = 2.594e-001
+
+ Results for Alternative Hypothesis and alpha = 0.0500
+
+ Alternative Hypothesis Conclusion
+ Standard deviations are unequal (two sided test) REJECTED
+ Standard deviation 1 is less than standard deviation 2 REJECTED
+ Standard deviation 1 is greater than standard deviation 2 NOT REJECTED
+
+
+
+*/
+
diff --git a/src/boost/libs/math/example/factorial_example.cpp b/src/boost/libs/math/example/factorial_example.cpp
new file mode 100644
index 000000000..7a51e0746
--- /dev/null
+++ b/src/boost/libs/math/example/factorial_example.cpp
@@ -0,0 +1,97 @@
+// TestFactorial.cpp
+//
+// Factorials and Binomial Coefficients.
+//
+// Copyright Datasim Education BV 2009-2010
+// Copyright John Maddock and Paul A. Bristow 2010
+
+// 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)
+
+#include <boost/math/special_functions/factorials.hpp>
+#include <boost/math/special_functions.hpp>
+
+#include <iostream>
+using namespace std;
+
+int main()
+{
+ using namespace boost::math;
+
+ // Factorials
+ unsigned int n = 3;
+
+ try
+ {
+ cout << "Factorial: " << factorial<double>(n) << endl;
+
+ // Caution: You must provide a return type template value, so this will not compile
+ // unsigned int nfac = factorial(n); // could not deduce template argument for 'T'
+ // You must provide an explicit floating-point (not integer) return type.
+ // If you do provide an integer type, like this:
+ // unsigned int uintfac = factorial<unsigned int>(n);
+ // you will also get a compile error, for MSVC C2338.
+ // If you really want an integer type, you can convert from double:
+ unsigned int intfac = static_cast<unsigned int>(factorial<double>(n));
+ // this will be exact, until the result of the factorial overflows the integer type.
+
+ cout << "Unchecked factorial: " << boost::math::unchecked_factorial<float>(n) << endl;
+ // Note:
+ // unsigned int unfac = boost::math::unchecked_factorial<unsigned int>(n);
+ // also fails to compile for the same reasons.
+ }
+ catch(exception& e)
+ {
+ cout << e.what() << endl;
+ }
+
+ // Double factorial n!!
+ try
+ {
+ //cout << "Double factorial: " << boost::math::double_factorial<unsigned>(n);
+ }
+ catch(exception& e)
+ {
+ cout << e.what() << endl;
+ }
+
+ // Rising and falling factorials
+ try
+ {
+ int i = 2; double x = 8;
+ cout << "Rising factorial: " << rising_factorial(x,i) << endl;
+ cout << "Falling factorial: " << falling_factorial(x,i) << endl;
+ }
+ catch(exception& e)
+ {
+ cout << e.what() << endl;
+ }
+
+ // Binomial coefficients
+ try
+ {
+ unsigned n = 10; unsigned k = 2;
+ // cout << "Binomial coefficient: " << boost::math::binomial_coefficient<unsigned>(n,k) << endl;
+ }
+ catch(exception& e)
+ {
+ cout << e.what() << endl;
+ }
+ return 0;
+}
+
+/*
+
+Output:
+
+ factorial_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\factorial_example.exe
+ Factorial: 6
+ Unchecked factorial: 6
+ Rising factorial: 72
+ Falling factorial: 56
+
+*/
+
+
diff --git a/src/boost/libs/math/example/fft_sines_table.cpp b/src/boost/libs/math/example/fft_sines_table.cpp
new file mode 100644
index 000000000..82345f0d8
--- /dev/null
+++ b/src/boost/libs/math/example/fft_sines_table.cpp
@@ -0,0 +1,270 @@
+// 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)
+
+// Copyright Paul A. Bristow 2013.
+// Copyright Christopher Kormanyos 2012, 2013.
+// Copyright John Maddock 2013.
+
+// This file is written to be included from a Quickbook .qbk document.
+// It can be compiled by the C++ compiler, and run. Any output can
+// also be added here as comment or included or pasted in elsewhere.
+// Caution: this file contains Quickbook markup as well as code
+// and comments: don't change any of the special comment markups!
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4996) // -D_SCL_SECURE_NO_WARNINGS.
+#endif
+
+//[fft_sines_table_example_1
+
+/*`[h5 Using Boost.Multiprecision to generate a high-precision array of sine coefficients for use with FFT.]
+
+The Boost.Multiprecision library can be used for computations requiring precision
+exceeding that of standard built-in types such as `float`, `double`
+and `long double`. For extended-precision calculations, Boost.Multiprecision
+supplies a template data type called `cpp_bin_float`. The number of decimal
+digits of precision is fixed at compile-time via a template parameter.
+
+One often needs to compute tables of numbers in mathematical software.
+To avoid the
+[@https://en.wikipedia.org/wiki/Rounding#Table-maker's_dilemma Table-maker's dilemma]
+it is necessary to use a higher precision type to compute the table values so that they have
+the nearest representable bit-pattern for the type, say `double`, of the table value.
+
+This example is a program `fft_since_table.cpp` that writes a header file `sines.hpp`
+containing an array of sine coefficients for use with a Fast Fourier Transform (FFT),
+that can be included by the FFT program.
+
+To use Boost.Multiprecision's high-precision floating-point types and constants, we need some includes:
+*/
+#include <boost/math/constants/constants.hpp>
+// using boost::math::constants::pi;
+
+#include <boost/multiprecision/cpp_bin_float.hpp> // for
+// using boost::multiprecision::cpp_bin_float and
+// using boost::multiprecision::cpp_bin_float_50;
+// using boost::multiprecision::cpp_bin_float_quad;
+
+#include <boost/array.hpp> // or <array> for std::array
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+#include <fstream>
+
+/*`First, this example defines a prolog text string which is a C++ comment with the program licence, copyright etc.
+(You would of course, tailor this to your needs, including *your* copyright claim).
+This will appear at the top of the written header file `sines.hpp`.
+*/
+
+//] [fft_sines_table_example_1]
+
+static const char* prolog =
+{
+ "// Use, modification and distribution are subject to the\n"
+ "// Boost Software License, Version 1.0.\n"
+ "// (See accompanying file LICENSE_1_0.txt\n"
+ "// or copy at ""http://www.boost.org/LICENSE_1_0.txt)\n\n"
+
+ "// Copyright A N Other, 2019.\n\n"
+};
+
+//[fft_sines_table_example_2
+
+using boost::multiprecision::cpp_bin_float_50;
+using boost::math::constants::pi;
+
+//] [fft_sines_table_example_2]
+
+// VS 2010 (wrongly) requires these at file scope, not local scope in `main`.
+// This program also requires `-std=c++11` option to compile using Clang and GCC.
+
+int main()
+{
+//[fft_sines_table_example_3
+/*`A fast Fourier transform (FFT), for example, may use a table of the values of
+sin(([pi]/2[super n]) in its implementation details. In order to maximize the precision in
+the FFT implementation, the precision of the tabulated trigonometric values
+should exceed that of the built-in floating-point type used in the FFT.
+
+The sample below computes a table of the values of sin([pi]/2[super n])
+in the range 1 <= n <= 31.
+
+This program makes use of, among other program elements, the data type
+`boost::multiprecision::cpp_bin_float_50`
+for a precision of 50 decimal digits from Boost.Multiprecision,
+the value of constant [pi] retrieved from Boost.Math,
+guaranteed to be initialized with the very last bit of precision for the type,
+here `cpp_bin_float_50`,
+and a C++11 lambda function combined with `std::for_each()`.
+*/
+
+/*`define the number of values (32) in the array of sines.
+*/
+
+ std::size_t size = 32U;
+ //cpp_bin_float_50 p = pi<cpp_bin_float_50>();
+ cpp_bin_float_50 p = boost::math::constants::pi<cpp_bin_float_50>();
+
+ std::vector <cpp_bin_float_50> sin_values (size);
+ unsigned n = 1U;
+ // Generate the sine values.
+ std::for_each
+ (
+ sin_values.begin (),
+ sin_values.end (),
+ [&n](cpp_bin_float_50& y)
+ {
+ y = sin( pi<cpp_bin_float_50>() / pow(cpp_bin_float_50 (2), n));
+ ++n;
+ }
+ );
+
+/*`Define the floating-point type for the generated file, either built-in
+`double, `float, or `long double`, or a user defined type like `cpp_bin_float_50`.
+*/
+
+std::string fp_type = "double";
+
+std::cout << "Generating an `std::array` or `boost::array` for floating-point type: "
+ << fp_type << ". " << std::endl;
+
+/*`By default, output would only show the standard 6 decimal digits,
+so set precision to show enough significant digits for the chosen floating-point type.
+For `cpp_bin_float_50` is 50. (50 decimal digits should be ample for most applications).
+
+*/
+ std::streamsize precision = std::numeric_limits<cpp_bin_float_50>::digits10;
+
+ std::cout << "Sines table precision is " << precision << " decimal digits. " << std::endl;
+
+/*`Of course, one could also choose a lower precision for the table values, for example,
+
+`std::streamsize precision = std::numeric_limits<cpp_bin_float_quad>::max_digits10;`
+
+128-bit 'quad' precision of 36 decimal digits would be sufficient
+for the most precise current `long double` implementations using 128-bit.
+In general, it should be a couple of decimal digits more (guard digits) than
+`std::numeric_limits<RealType>::max_digits10` for the target system floating-point type.
+(If the implementation does not provide `max_digits10`, the the Kahan formula
+`std::numeric_limits<RealType>::digits * 3010/10000 + 2` can be used instead).
+
+The compiler will read these values as decimal digits strings and
+use the nearest representation for the floating-point type.
+
+Now output all the sine table, to a file of your chosen name.
+*/
+ const char sines_name[] = "sines.hpp"; // Assuming in same directory as .exe
+
+ std::ofstream fout(sines_name, std::ios_base::out); // Creates if no file exists,
+ // & uses default overwrite/ ios::replace.
+ if (fout.is_open() == false)
+ { // failed to open OK!
+ std::cout << "Open file " << sines_name << " failed!" << std::endl;
+ return EXIT_FAILURE;
+ }
+ else
+ { // Write prolog etc as a C++ comment.
+ std::cout << "Open file " << sines_name << " for output OK." << std::endl;
+ fout << prolog
+ << "// Table of " << sin_values.size() << " values with "
+ << precision << " decimal digits precision,\n"
+ "// generated by program fft_sines_table.cpp.\n" << std::endl;
+
+ fout << "#include <array> // std::array" << std::endl;
+
+ // Write the table of sines as a C++ array.
+ fout << "\nstatic const std::array<double, " << size << "> sines =\n"
+ "{{\n"; // 2nd { needed for some old GCC compiler versions.
+ fout.precision(precision);
+
+ for (unsigned int i = 0U; ;)
+ {
+ fout << " " << sin_values[i];
+ if (i == sin_values.size()-1)
+ { // next is last value.
+ fout << "\n}}; // array sines\n"; // 2nd } needed for some old GCC compiler versions.
+ break;
+ }
+ else
+ {
+ fout << ",\n";
+ i++;
+ }
+ } // for
+
+ fout.close();
+ std::cout << "Closed file " << sines_name << " for output." << std::endl;
+ }
+//`The output file generated can be seen at [@../../example/sines.hpp]
+
+//] [/fft_sines_table_example_3]
+
+ return EXIT_SUCCESS;
+
+} // int main()
+
+/*
+//[fft_sines_table_example_output
+
+The printed table is:
+
+ 1
+ 0.70710678118654752440084436210484903928483593768847
+ 0.38268343236508977172845998403039886676134456248563
+ 0.19509032201612826784828486847702224092769161775195
+ 0.098017140329560601994195563888641845861136673167501
+ 0.049067674327418014254954976942682658314745363025753
+ 0.024541228522912288031734529459282925065466119239451
+ 0.012271538285719926079408261951003212140372319591769
+ 0.0061358846491544753596402345903725809170578863173913
+ 0.003067956762965976270145365490919842518944610213452
+ 0.0015339801862847656123036971502640790799548645752374
+ 0.00076699031874270452693856835794857664314091945206328
+ 0.00038349518757139558907246168118138126339502603496474
+ 0.00019174759731070330743990956198900093346887403385916
+ 9.5873799095977345870517210976476351187065612851145e-05
+ 4.7936899603066884549003990494658872746866687685767e-05
+ 2.3968449808418218729186577165021820094761474895673e-05
+ 1.1984224905069706421521561596988984804731977538387e-05
+ 5.9921124526424278428797118088908617299871778780951e-06
+ 2.9960562263346607504548128083570598118251878683408e-06
+ 1.4980281131690112288542788461553611206917585861527e-06
+ 7.4901405658471572113049856673065563715595930217207e-07
+ 3.7450702829238412390316917908463317739740476297248e-07
+ 1.8725351414619534486882457659356361712045272098287e-07
+ 9.3626757073098082799067286680885620193236507169473e-08
+ 4.681337853654909269511551813854009695950362701667e-08
+ 2.3406689268274552759505493419034844037886207223779e-08
+ 1.1703344634137277181246213503238103798093456639976e-08
+ 5.8516723170686386908097901008341396943900085051757e-09
+ 2.9258361585343193579282304690689559020175857150074e-09
+ 1.4629180792671596805295321618659637103742615227834e-09
+*/
+
+//] [/fft_sines_table_example_output]
+
+//[fft_sines_table_example_check
+
+/*`
+The output can be copied as text and readily integrated into a given source
+code. Alternatively, the output can be written to a text or even be used
+within a self-written automatic code generator as this example.
+
+A computer algebra system can be used to verify the results obtained from
+Boost.Math and Boost.Multiprecision. For example, the __Mathematica
+computer algebra system can obtain a similar table with the command:
+
+ Table[N[Sin[Pi / (2^n)], 50], {n, 1, 31, 1}]
+
+The __WolframAlpha computational knowledge engine can also be used to generate
+this table. The same command can be pasted into the compute box.
+
+*/
+
+//] [/fft_sines_table_example_check]
diff --git a/src/boost/libs/math/example/find_location_example.cpp b/src/boost/libs/math/example/find_location_example.cpp
new file mode 100644
index 000000000..c9ce58d62
--- /dev/null
+++ b/src/boost/libs/math/example/find_location_example.cpp
@@ -0,0 +1,174 @@
+// find_location.cpp
+
+// Copyright Paul A. Bristow 2008, 2010.
+
+// 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)
+
+// Example of finding location (mean)
+// for normal (Gaussian) & Cauchy distribution.
+
+// 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
+
+//[find_location1
+/*`
+First we need some includes to access the normal distribution,
+the algorithms to find location (and some std output of course).
+*/
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+ using boost::math::normal; // typedef provides default type is double.
+#include <boost/math/distributions/cauchy.hpp> // for cauchy_distribution
+ using boost::math::cauchy; // typedef provides default type is double.
+#include <boost/math/distributions/find_location.hpp>
+ using boost::math::find_location; // for mean
+#include <boost/math/distributions/find_scale.hpp>
+ using boost::math::find_scale; // for standard deviation
+ using boost::math::complement; // Needed if you want to use the complement version.
+ using boost::math::policies::policy;
+
+#include <iostream>
+ using std::cout; using std::endl;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+
+//] [/find_location1]
+
+int main()
+{
+ cout << "Example: Find location (or mean)." << endl;
+ try
+ {
+//[find_location2
+/*`
+For this example, we will use the standard normal distribution,
+with mean (location) zero and standard deviation (scale) unity.
+This is also the default for this implementation.
+*/
+ normal N01; // Default 'standard' normal distribution with zero mean and
+ double sd = 1.; // normal default standard deviation is 1.
+/*`Suppose we want to find a different normal distribution whose mean is shifted
+so that only fraction p (here 0.001 or 0.1%) are below a certain chosen limit
+(here -2, two standard deviations).
+*/
+ double z = -2.; // z to give prob p
+ double p = 0.001; // only 0.1% below z
+
+ cout << "Normal distribution with mean = " << N01.location()
+ << ", standard deviation " << N01.scale()
+ << ", has " << "fraction <= " << z
+ << ", p = " << cdf(N01, z) << endl;
+ cout << "Normal distribution with mean = " << N01.location()
+ << ", standard deviation " << N01.scale()
+ << ", has " << "fraction > " << z
+ << ", p = " << cdf(complement(N01, z)) << endl; // Note: uses complement.
+/*`
+[pre
+Normal distribution with mean = 0, standard deviation 1, has fraction <= -2, p = 0.0227501
+Normal distribution with mean = 0, standard deviation 1, has fraction > -2, p = 0.97725
+]
+We can now use ''find_location'' to give a new offset mean.
+*/
+ double l = find_location<normal>(z, p, sd);
+ cout << "offset location (mean) = " << l << endl;
+/*`
+that outputs:
+[pre
+offset location (mean) = 1.09023
+]
+showing that we need to shift the mean just over one standard deviation from its previous value of zero.
+
+Then we can check that we have achieved our objective
+by constructing a new distribution
+with the offset mean (but same standard deviation):
+*/
+ normal np001pc(l, sd); // Same standard_deviation (scale) but with mean (location) shifted.
+/*`
+And re-calculating the fraction below our chosen limit.
+*/
+cout << "Normal distribution with mean = " << l
+ << " has " << "fraction <= " << z
+ << ", p = " << cdf(np001pc, z) << endl;
+ cout << "Normal distribution with mean = " << l
+ << " has " << "fraction > " << z
+ << ", p = " << cdf(complement(np001pc, z)) << endl;
+/*`
+[pre
+Normal distribution with mean = 1.09023 has fraction <= -2, p = 0.001
+Normal distribution with mean = 1.09023 has fraction > -2, p = 0.999
+]
+
+[h4 Controlling Error Handling from find_location]
+We can also control the policy for handling various errors.
+For example, we can define a new (possibly unwise)
+policy to ignore domain errors ('bad' arguments).
+
+Unless we are using the boost::math namespace, we will need:
+*/
+ using boost::math::policies::policy;
+ using boost::math::policies::domain_error;
+ using boost::math::policies::ignore_error;
+
+/*`
+Using a typedef is often convenient, especially if it is re-used,
+although it is not required, as the various examples below show.
+*/
+ typedef policy<domain_error<ignore_error> > ignore_domain_policy;
+ // find_location with new policy, using typedef.
+ l = find_location<normal>(z, p, sd, ignore_domain_policy());
+ // Default policy policy<>, needs "using boost::math::policies::policy;"
+ l = find_location<normal>(z, p, sd, policy<>());
+ // Default policy, fully specified.
+ l = find_location<normal>(z, p, sd, boost::math::policies::policy<>());
+ // A new policy, ignoring domain errors, without using a typedef.
+ l = find_location<normal>(z, p, sd, policy<domain_error<ignore_error> >());
+/*`
+If we want to use a probability that is the __complements of our probability,
+we should not even think of writing `find_location<normal>(z, 1 - p, sd)`,
+but use the complement version, see __why_complements.
+*/
+ z = 2.;
+ double q = 0.95; // = 1 - p; // complement.
+ l = find_location<normal>(complement(z, q, sd));
+
+ normal np95pc(l, sd); // Same standard_deviation (scale) but with mean(location) shifted
+ cout << "Normal distribution with mean = " << l << " has "
+ << "fraction <= " << z << " = " << cdf(np95pc, z) << endl;
+ cout << "Normal distribution with mean = " << l << " has "
+ << "fraction > " << z << " = " << cdf(complement(np95pc, z)) << endl;
+ //] [/find_location2]
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+//[find_location_example_output
+/*`
+[pre
+Example: Find location (mean).
+Normal distribution with mean = 0, standard deviation 1, has fraction <= -2, p = 0.0227501
+Normal distribution with mean = 0, standard deviation 1, has fraction > -2, p = 0.97725
+offset location (mean) = 1.09023
+Normal distribution with mean = 1.09023 has fraction <= -2, p = 0.001
+Normal distribution with mean = 1.09023 has fraction > -2, p = 0.999
+Normal distribution with mean = 0.355146 has fraction <= 2 = 0.95
+Normal distribution with mean = 0.355146 has fraction > 2 = 0.05
+]
+*/
+//] [/find_location_example_output]
diff --git a/src/boost/libs/math/example/find_mean_and_sd_normal.cpp b/src/boost/libs/math/example/find_mean_and_sd_normal.cpp
new file mode 100644
index 000000000..752c06a7f
--- /dev/null
+++ b/src/boost/libs/math/example/find_mean_and_sd_normal.cpp
@@ -0,0 +1,413 @@
+// find_mean_and_sd_normal.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+// Example of finding mean or sd for normal distribution.
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[normal_std
+/*`
+First we need some includes to access the normal distribution,
+the algorithms to find location and scale
+(and some std output of course).
+*/
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+ using boost::math::normal; // typedef provides default type is double.
+#include <boost/math/distributions/cauchy.hpp> // for cauchy_distribution
+ using boost::math::cauchy; // typedef provides default type is double.
+#include <boost/math/distributions/find_location.hpp>
+ using boost::math::find_location;
+#include <boost/math/distributions/find_scale.hpp>
+ using boost::math::find_scale;
+ using boost::math::complement;
+ using boost::math::policies::policy;
+
+#include <iostream>
+ using std::cout; using std::endl; using std::left; using std::showpoint; using std::noshowpoint;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+#include <stdexcept>
+
+//] [/normal_std Quickbook]
+
+int main()
+{
+ cout << "Find_location (mean) and find_scale (standard deviation) examples." << endl;
+ try
+ {
+
+//[normal_find_location_and_scale_eg
+
+/*`
+[h4 Using find_location and find_scale to meet dispensing and measurement specifications]
+
+Consider an example from K Krishnamoorthy,
+Handbook of Statistical Distributions with Applications,
+ISBN 1-58488-635-8, (2006) p 126, example 10.3.7.
+
+"A machine is set to pack 3 kg of ground beef per pack.
+Over a long period of time it is found that the average packed was 3 kg
+with a standard deviation of 0.1 kg.
+Assume the packing is normally distributed."
+
+We start by constructing a normal distribution with the given parameters:
+*/
+
+double mean = 3.; // kg
+double standard_deviation = 0.1; // kg
+normal packs(mean, standard_deviation);
+/*`We can then find the fraction (or %) of packages that weigh more than 3.1 kg.
+*/
+
+double max_weight = 3.1; // kg
+cout << "Percentage of packs > " << max_weight << " is "
+<< cdf(complement(packs, max_weight)) * 100. << endl; // P(X > 3.1)
+
+/*`We might want to ensure that 95% of packs are over a minimum weight specification,
+then we want the value of the mean such that P(X < 2.9) = 0.05.
+
+Using the mean of 3 kg, we can estimate
+the fraction of packs that fail to meet the specification of 2.9 kg.
+*/
+
+double minimum_weight = 2.9;
+cout <<"Fraction of packs <= " << minimum_weight << " with a mean of " << mean
+ << " is " << cdf(complement(packs, minimum_weight)) << endl;
+// fraction of packs <= 2.9 with a mean of 3 is 0.841345
+
+/*`This is 0.84 - more than the target fraction of 0.95.
+If we want 95% to be over the minimum weight,
+what should we set the mean weight to be?
+
+Using the KK StatCalc program supplied with the book and the method given on page 126 gives 3.06449.
+
+We can confirm this by constructing a new distribution which we call 'xpacks'
+with a safety margin mean of 3.06449 thus:
+*/
+double over_mean = 3.06449;
+normal xpacks(over_mean, standard_deviation);
+cout << "Fraction of packs >= " << minimum_weight
+<< " with a mean of " << xpacks.mean()
+ << " is " << cdf(complement(xpacks, minimum_weight)) << endl;
+// fraction of packs >= 2.9 with a mean of 3.06449 is 0.950005
+
+/*`Using this Math Toolkit, we can calculate the required mean directly thus:
+*/
+double under_fraction = 0.05; // so 95% are above the minimum weight mean - sd = 2.9
+double low_limit = standard_deviation;
+double offset = mean - low_limit - quantile(packs, under_fraction);
+double nominal_mean = mean + offset;
+// mean + (mean - low_limit - quantile(packs, under_fraction));
+
+normal nominal_packs(nominal_mean, standard_deviation);
+cout << "Setting the packer to " << nominal_mean << " will mean that "
+ << "fraction of packs >= " << minimum_weight
+ << " is " << cdf(complement(nominal_packs, minimum_weight)) << endl;
+// Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95
+
+/*`
+This calculation is generalized as the free function called `find_location`,
+see __algorithms.
+
+To use this we will need to
+*/
+
+#include <boost/math/distributions/find_location.hpp>
+ using boost::math::find_location;
+/*`and then use find_location function to find safe_mean,
+& construct a new normal distribution called 'goodpacks'.
+*/
+double safe_mean = find_location<normal>(minimum_weight, under_fraction, standard_deviation);
+normal good_packs(safe_mean, standard_deviation);
+/*`with the same confirmation as before:
+*/
+cout << "Setting the packer to " << nominal_mean << " will mean that "
+ << "fraction of packs >= " << minimum_weight
+ << " is " << cdf(complement(good_packs, minimum_weight)) << endl;
+// Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95
+
+/*`
+[h4 Using Cauchy-Lorentz instead of normal distribution]
+
+After examining the weight distribution of a large number of packs, we might decide that,
+after all, the assumption of a normal distribution is not really justified.
+We might find that the fit is better to a __cauchy_distrib.
+This distribution has wider 'wings', so that whereas most of the values
+are closer to the mean than the normal, there are also more values than 'normal'
+that lie further from the mean than the normal.
+
+This might happen because a larger than normal lump of meat is either included or excluded.
+
+We first create a __cauchy_distrib with the original mean and standard deviation,
+and estimate the fraction that lie below our minimum weight specification.
+*/
+
+cauchy cpacks(mean, standard_deviation);
+cout << "Cauchy Setting the packer to " << mean << " will mean that "
+ << "fraction of packs >= " << minimum_weight
+ << " is " << cdf(complement(cpacks, minimum_weight)) << endl;
+// Cauchy Setting the packer to 3 will mean that fraction of packs >= 2.9 is 0.75
+
+/*`Note that far fewer of the packs meet the specification, only 75% instead of 95%.
+Now we can repeat the find_location, using the cauchy distribution as template parameter,
+in place of the normal used above.
+*/
+
+double lc = find_location<cauchy>(minimum_weight, under_fraction, standard_deviation);
+cout << "find_location<cauchy>(minimum_weight, over fraction, standard_deviation); " << lc << endl;
+// find_location<cauchy>(minimum_weight, over fraction, packs.standard_deviation()); 3.53138
+/*`Note that the safe_mean setting needs to be much higher, 3.53138 instead of 3.06449,
+so we will make rather less profit.
+
+And again confirm that the fraction meeting specification is as expected.
+*/
+cauchy goodcpacks(lc, standard_deviation);
+cout << "Cauchy Setting the packer to " << lc << " will mean that "
+ << "fraction of packs >= " << minimum_weight
+ << " is " << cdf(complement(goodcpacks, minimum_weight)) << endl;
+// Cauchy Setting the packer to 3.53138 will mean that fraction of packs >= 2.9 is 0.95
+
+/*`Finally we could estimate the effect of a much tighter specification,
+that 99% of packs met the specification.
+*/
+
+cout << "Cauchy Setting the packer to "
+ << find_location<cauchy>(minimum_weight, 0.99, standard_deviation)
+ << " will mean that "
+ << "fraction of packs >= " << minimum_weight
+ << " is " << cdf(complement(goodcpacks, minimum_weight)) << endl;
+
+/*`Setting the packer to 3.13263 will mean that fraction of packs >= 2.9 is 0.99,
+but will more than double the mean loss from 0.0644 to 0.133 kg per pack.
+
+Of course, this calculation is not limited to packs of meat, it applies to dispensing anything,
+and it also applies to a 'virtual' material like any measurement.
+
+The only caveat is that the calculation assumes that the standard deviation (scale) is known with
+a reasonably low uncertainty, something that is not so easy to ensure in practice.
+And that the distribution is well defined, __normal_distrib or __cauchy_distrib, or some other.
+
+If one is simply dispensing a very large number of packs,
+then it may be feasible to measure the weight of hundreds or thousands of packs.
+With a healthy 'degrees of freedom', the confidence intervals for the standard deviation
+are not too wide, typically about + and - 10% for hundreds of observations.
+
+For other applications, where it is more difficult or expensive to make many observations,
+the confidence intervals are depressingly wide.
+
+See [link math_toolkit.stat_tut.weg.cs_eg.chi_sq_intervals Confidence Intervals on the standard deviation]
+for a worked example
+[@../../example/chi_square_std_dev_test.cpp chi_square_std_dev_test.cpp]
+of estimating these intervals.
+
+
+[h4 Changing the scale or standard deviation]
+
+Alternatively, we could invest in a better (more precise) packer
+(or measuring device) with a lower standard deviation, or scale.
+
+This might cost more, but would reduce the amount we have to 'give away'
+in order to meet the specification.
+
+To estimate how much better (how much smaller standard deviation) it would have to be,
+we need to get the 5% quantile to be located at the under_weight limit, 2.9
+*/
+double p = 0.05; // wanted p th quantile.
+cout << "Quantile of " << p << " = " << quantile(packs, p)
+ << ", mean = " << packs.mean() << ", sd = " << packs.standard_deviation() << endl;
+/*`
+Quantile of 0.05 = 2.83551, mean = 3, sd = 0.1
+
+With the current packer (mean = 3, sd = 0.1), the 5% quantile is at 2.8551 kg,
+a little below our target of 2.9 kg.
+So we know that the standard deviation is going to have to be smaller.
+
+Let's start by guessing that it (now 0.1) needs to be halved, to a standard deviation of 0.05 kg.
+*/
+normal pack05(mean, 0.05);
+cout << "Quantile of " << p << " = " << quantile(pack05, p)
+ << ", mean = " << pack05.mean() << ", sd = " << pack05.standard_deviation() << endl;
+// Quantile of 0.05 = 2.91776, mean = 3, sd = 0.05
+
+cout <<"Fraction of packs >= " << minimum_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack05.standard_deviation()
+ << " is " << cdf(complement(pack05, minimum_weight)) << endl;
+// Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.05 is 0.97725
+/*`
+So 0.05 was quite a good guess, but we are a little over the 2.9 target,
+so the standard deviation could be a tiny bit more. So we could do some
+more guessing to get closer, say by increasing standard deviation to 0.06 kg,
+constructing another new distribution called pack06.
+*/
+normal pack06(mean, 0.06);
+cout << "Quantile of " << p << " = " << quantile(pack06, p)
+ << ", mean = " << pack06.mean() << ", sd = " << pack06.standard_deviation() << endl;
+// Quantile of 0.05 = 2.90131, mean = 3, sd = 0.06
+
+cout <<"Fraction of packs >= " << minimum_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack06.standard_deviation()
+ << " is " << cdf(complement(pack06, minimum_weight)) << endl;
+// Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.06 is 0.95221
+/*`
+Now we are getting really close, but to do the job properly,
+we might need to use root finding method, for example the tools provided,
+and used elsewhere, in the Math Toolkit, see __root_finding_without_derivatives
+
+But in this (normal) distribution case, we can and should be even smarter
+and make a direct calculation.
+*/
+
+/*`Our required limit is minimum_weight = 2.9 kg, often called the random variate z.
+For a standard normal distribution, then probability p = N((minimum_weight - mean) / sd).
+
+We want to find the standard deviation that would be required to meet this limit,
+so that the p th quantile is located at z (minimum_weight).
+In this case, the 0.05 (5%) quantile is at 2.9 kg pack weight, when the mean is 3 kg,
+ensuring that 0.95 (95%) of packs are above the minimum weight.
+
+Rearranging, we can directly calculate the required standard deviation:
+*/
+normal N01; // standard normal distribution with mean zero and unit standard deviation.
+p = 0.05;
+double qp = quantile(N01, p);
+double sd95 = (minimum_weight - mean) / qp;
+
+cout << "For the "<< p << "th quantile to be located at "
+ << minimum_weight << ", would need a standard deviation of " << sd95 << endl;
+// For the 0.05th quantile to be located at 2.9, would need a standard deviation of 0.0607957
+
+/*`We can now construct a new (normal) distribution pack95 for the 'better' packer,
+and check that our distribution will meet the specification.
+*/
+
+normal pack95(mean, sd95);
+cout <<"Fraction of packs >= " << minimum_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack95.standard_deviation()
+ << " is " << cdf(complement(pack95, minimum_weight)) << endl;
+// Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.0607957 is 0.95
+
+/*`This calculation is generalized in the free function find_scale,
+as shown below, giving the same standard deviation.
+*/
+double ss = find_scale<normal>(minimum_weight, under_fraction, packs.mean());
+cout << "find_scale<normal>(minimum_weight, under_fraction, packs.mean()); " << ss << endl;
+// find_scale<normal>(minimum_weight, under_fraction, packs.mean()); 0.0607957
+
+/*`If we had defined an over_fraction, or percentage that must pass specification
+*/
+double over_fraction = 0.95;
+/*`And (wrongly) written
+
+ double sso = find_scale<normal>(minimum_weight, over_fraction, packs.mean());
+
+With the default policy, we would get a message like
+
+[pre
+Message from thrown exception was:
+ Error in function boost::math::find_scale<Dist, Policy>(double, double, double, Policy):
+ Computed scale (-0.060795683191176959) is <= 0! Was the complement intended?
+]
+
+But this would return a *negative* standard deviation - obviously impossible.
+The probability should be 1 - over_fraction, not over_fraction, thus:
+*/
+
+double ss1o = find_scale<normal>(minimum_weight, 1 - over_fraction, packs.mean());
+cout << "find_scale<normal>(minimum_weight, under_fraction, packs.mean()); " << ss1o << endl;
+// find_scale<normal>(minimum_weight, under_fraction, packs.mean()); 0.0607957
+
+/*`But notice that using '1 - over_fraction' - will lead to a
+loss of accuracy, especially if over_fraction was close to unity. (See __why_complements).
+In this (very common) case, we should instead use the __complements,
+giving the most accurate result.
+*/
+
+double ssc = find_scale<normal>(complement(minimum_weight, over_fraction, packs.mean()));
+cout << "find_scale<normal>(complement(minimum_weight, over_fraction, packs.mean())); " << ssc << endl;
+// find_scale<normal>(complement(minimum_weight, over_fraction, packs.mean())); 0.0607957
+
+/*`Note that our guess of 0.06 was close to the accurate value of 0.060795683191176959.
+
+We can again confirm our prediction thus:
+*/
+
+normal pack95c(mean, ssc);
+cout <<"Fraction of packs >= " << minimum_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack95c.standard_deviation()
+ << " is " << cdf(complement(pack95c, minimum_weight)) << endl;
+// Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.0607957 is 0.95
+
+/*`Notice that these two deceptively simple questions:
+
+* Do we over-fill to make sure we meet a minimum specification (or under-fill to avoid an overdose)?
+
+and/or
+
+* Do we measure better?
+
+are actually extremely common.
+
+The weight of beef might be replaced by a measurement of more or less anything,
+from drug tablet content, Apollo landing rocket firing, X-ray treatment doses...
+
+The scale can be variation in dispensing or uncertainty in measurement.
+*/
+//] [/normal_find_location_and_scale_eg Quickbook end]
+
+ }
+ 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.
+ // 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.
+ cout <<
+ "\n""Message from thrown exception was:\n " << e.what() << endl;
+ }
+ return 0;
+} // int main()
+
+
+/*
+
+Output is:
+
+//[normal_find_location_and_scale_output
+
+Find_location (mean) and find_scale (standard deviation) examples.
+Percentage of packs > 3.1 is 15.8655
+Fraction of packs <= 2.9 with a mean of 3 is 0.841345
+Fraction of packs >= 2.9 with a mean of 3.06449 is 0.950005
+Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95
+Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95
+Cauchy Setting the packer to 3 will mean that fraction of packs >= 2.9 is 0.75
+find_location<cauchy>(minimum_weight, over fraction, standard_deviation); 3.53138
+Cauchy Setting the packer to 3.53138 will mean that fraction of packs >= 2.9 is 0.95
+Cauchy Setting the packer to -0.282052 will mean that fraction of packs >= 2.9 is 0.95
+Quantile of 0.05 = 2.83551, mean = 3, sd = 0.1
+Quantile of 0.05 = 2.91776, mean = 3, sd = 0.05
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.05 is 0.97725
+Quantile of 0.05 = 2.90131, mean = 3, sd = 0.06
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.06 is 0.95221
+For the 0.05th quantile to be located at 2.9, would need a standard deviation of 0.0607957
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.0607957 is 0.95
+find_scale<normal>(minimum_weight, under_fraction, packs.mean()); 0.0607957
+find_scale<normal>(minimum_weight, under_fraction, packs.mean()); 0.0607957
+find_scale<normal>(complement(minimum_weight, over_fraction, packs.mean())); 0.0607957
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.0607957 is 0.95
+
+//] [/normal_find_location_and_scale_eg_output]
+
+*/
+
+
+
diff --git a/src/boost/libs/math/example/find_root_example.cpp b/src/boost/libs/math/example/find_root_example.cpp
new file mode 100644
index 000000000..e944e09e8
--- /dev/null
+++ b/src/boost/libs/math/example/find_root_example.cpp
@@ -0,0 +1,169 @@
+// find_root_example.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+// Example of using root finding.
+
+// 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_find1
+/*`
+First we need some includes to access the normal distribution
+(and some std output of course).
+*/
+
+#include <boost/math/tools/roots.hpp> // root finding.
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+ using boost::math::normal; // typedef provides default type is double.
+
+#include <iostream>
+ using std::cout; using std::endl; using std::left; using std::showpoint; using std::noshowpoint;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+#include <stdexcept>
+
+
+//] //[/root_find1]
+
+int main()
+{
+ cout << "Example: Normal distribution, root finding.";
+ try
+ {
+
+//[root_find2
+
+/*`A machine is set to pack 3 kg of ground beef per pack.
+Over a long period of time it is found that the average packed was 3 kg
+with a standard deviation of 0.1 kg.
+Assuming the packing is normally distributed,
+we can find the fraction (or %) of packages that weigh more than 3.1 kg.
+*/
+
+double mean = 3.; // kg
+double standard_deviation = 0.1; // kg
+normal packs(mean, standard_deviation);
+
+double max_weight = 3.1; // kg
+cout << "Percentage of packs > " << max_weight << " is "
+<< cdf(complement(packs, max_weight)) << endl; // P(X > 3.1)
+
+double under_weight = 2.9;
+cout <<"fraction of packs <= " << under_weight << " with a mean of " << mean
+ << " is " << cdf(complement(packs, under_weight)) << endl;
+// fraction of packs <= 2.9 with a mean of 3 is 0.841345
+// This is 0.84 - more than the target 0.95
+// Want 95% to be over this weight, so what should we set the mean weight to be?
+// KK StatCalc says:
+double over_mean = 3.0664;
+normal xpacks(over_mean, standard_deviation);
+cout << "fraction of packs >= " << under_weight
+<< " with a mean of " << xpacks.mean()
+ << " is " << cdf(complement(xpacks, under_weight)) << endl;
+// fraction of packs >= 2.9 with a mean of 3.06449 is 0.950005
+double under_fraction = 0.05; // so 95% are above the minimum weight mean - sd = 2.9
+double low_limit = standard_deviation;
+double offset = mean - low_limit - quantile(packs, under_fraction);
+double nominal_mean = mean + offset;
+
+normal nominal_packs(nominal_mean, standard_deviation);
+cout << "Setting the packer to " << nominal_mean << " will mean that "
+ << "fraction of packs >= " << under_weight
+ << " is " << cdf(complement(nominal_packs, under_weight)) << endl;
+
+/*`
+Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95.
+
+Setting the packer to 3.13263 will mean that fraction of packs >= 2.9 is 0.99,
+but will more than double the mean loss from 0.0644 to 0.133.
+
+Alternatively, we could invest in a better (more precise) packer with a lower standard deviation.
+
+To estimate how much better (how much smaller standard deviation) it would have to be,
+we need to get the 5% quantile to be located at the under_weight limit, 2.9
+*/
+double p = 0.05; // wanted p th quantile.
+cout << "Quantile of " << p << " = " << quantile(packs, p)
+ << ", mean = " << packs.mean() << ", sd = " << packs.standard_deviation() << endl; //
+/*`
+Quantile of 0.05 = 2.83551, mean = 3, sd = 0.1
+
+With the current packer (mean = 3, sd = 0.1), the 5% quantile is at 2.8551 kg,
+a little below our target of 2.9 kg.
+So we know that the standard deviation is going to have to be smaller.
+
+Let's start by guessing that it (now 0.1) needs to be halved, to a standard deviation of 0.05
+*/
+normal pack05(mean, 0.05);
+cout << "Quantile of " << p << " = " << quantile(pack05, p)
+ << ", mean = " << pack05.mean() << ", sd = " << pack05.standard_deviation() << endl;
+
+cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack05.standard_deviation()
+ << " is " << cdf(complement(pack05, under_weight)) << endl;
+//
+/*`
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.05 is 0.9772
+
+So 0.05 was quite a good guess, but we are a little over the 2.9 target,
+so the standard deviation could be a tiny bit more. So we could do some
+more guessing to get closer, say by increasing to 0.06
+*/
+
+normal pack06(mean, 0.06);
+cout << "Quantile of " << p << " = " << quantile(pack06, p)
+ << ", mean = " << pack06.mean() << ", sd = " << pack06.standard_deviation() << endl;
+
+cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack06.standard_deviation()
+ << " is " << cdf(complement(pack06, under_weight)) << endl;
+/*`
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.06 is 0.9522
+
+Now we are getting really close, but to do the job properly,
+we could use root finding method, for example the tools provided, and used elsewhere,
+in the Math Toolkit, see __root_finding_without_derivatives.
+
+But in this normal distribution case, we could be even smarter and make a direct calculation.
+*/
+//] [/root_find2]
+
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+/*
+Output is:
+
+//[root_find_output
+
+Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\find_root_example.exe"
+Example: Normal distribution, root finding.Percentage of packs > 3.1 is 0.158655
+fraction of packs <= 2.9 with a mean of 3 is 0.841345
+fraction of packs >= 2.9 with a mean of 3.0664 is 0.951944
+Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95
+Quantile of 0.05 = 2.83551, mean = 3, sd = 0.1
+Quantile of 0.05 = 2.91776, mean = 3, sd = 0.05
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.05 is 0.97725
+Quantile of 0.05 = 2.90131, mean = 3, sd = 0.06
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.06 is 0.95221
+
+//] [/root_find_output]
+*/
diff --git a/src/boost/libs/math/example/find_scale_example.cpp b/src/boost/libs/math/example/find_scale_example.cpp
new file mode 100644
index 000000000..29e474f0f
--- /dev/null
+++ b/src/boost/libs/math/example/find_scale_example.cpp
@@ -0,0 +1,180 @@
+// find_scale.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+// Example of finding scale (standard deviation) for normal (Gaussian).
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[find_scale1
+/*`
+First we need some includes to access the __normal_distrib,
+the algorithms to find scale (and some std output of course).
+*/
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+ using boost::math::normal; // typedef provides default type is double.
+#include <boost/math/distributions/find_scale.hpp>
+ using boost::math::find_scale;
+ using boost::math::complement; // Needed if you want to use the complement version.
+ using boost::math::policies::policy; // Needed to specify the error handling policy.
+
+#include <iostream>
+ using std::cout; using std::endl;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+//] [/find_scale1]
+
+int main()
+{
+ cout << "Example: Find scale (standard deviation)." << endl;
+ try
+ {
+//[find_scale2
+/*`
+For this example, we will use the standard __normal_distrib,
+with location (mean) zero and standard deviation (scale) unity.
+Conveniently, this is also the default for this implementation's constructor.
+*/
+ normal N01; // Default 'standard' normal distribution with zero mean
+ double sd = 1.; // and standard deviation is 1.
+/*`Suppose we want to find a different normal distribution with standard deviation
+so that only fraction p (here 0.001 or 0.1%) are below a certain chosen limit
+(here -2. standard deviations).
+*/
+ double z = -2.; // z to give prob p
+ double p = 0.001; // only 0.1% below z = -2
+
+ cout << "Normal distribution with mean = " << N01.location() // aka N01.mean()
+ << ", standard deviation " << N01.scale() // aka N01.standard_deviation()
+ << ", has " << "fraction <= " << z
+ << ", p = " << cdf(N01, z) << endl;
+ cout << "Normal distribution with mean = " << N01.location()
+ << ", standard deviation " << N01.scale()
+ << ", has " << "fraction > " << z
+ << ", p = " << cdf(complement(N01, z)) << endl; // Note: uses complement.
+/*`
+[pre
+Normal distribution with mean = 0 has fraction <= -2, p = 0.0227501
+Normal distribution with mean = 0 has fraction > -2, p = 0.97725
+]
+Noting that p = 0.02 instead of our target of 0.001,
+we can now use `find_scale` to give a new standard deviation.
+*/
+ double l = N01.location();
+ double s = find_scale<normal>(z, p, l);
+ cout << "scale (standard deviation) = " << s << endl;
+/*`
+that outputs:
+[pre
+scale (standard deviation) = 0.647201
+]
+showing that we need to reduce the standard deviation from 1. to 0.65.
+
+Then we can check that we have achieved our objective
+by constructing a new distribution
+with the new standard deviation (but same zero mean):
+*/
+ normal np001pc(N01.location(), s);
+/*`
+And re-calculating the fraction below (and above) our chosen limit.
+*/
+ cout << "Normal distribution with mean = " << l
+ << " has " << "fraction <= " << z
+ << ", p = " << cdf(np001pc, z) << endl;
+ cout << "Normal distribution with mean = " << l
+ << " has " << "fraction > " << z
+ << ", p = " << cdf(complement(np001pc, z)) << endl;
+/*`
+[pre
+Normal distribution with mean = 0 has fraction <= -2, p = 0.001
+Normal distribution with mean = 0 has fraction > -2, p = 0.999
+]
+
+[h4 Controlling how Errors from find_scale are handled]
+We can also control the policy for handling various errors.
+For example, we can define a new (possibly unwise)
+policy to ignore domain errors ('bad' arguments).
+
+Unless we are using the boost::math namespace, we will need:
+*/
+ using boost::math::policies::policy;
+ using boost::math::policies::domain_error;
+ using boost::math::policies::ignore_error;
+
+/*`
+Using a typedef is convenient, especially if it is re-used,
+although it is not required, as the various examples below show.
+*/
+ typedef policy<domain_error<ignore_error> > ignore_domain_policy;
+ // find_scale with new policy, using typedef.
+ l = find_scale<normal>(z, p, l, ignore_domain_policy());
+ // Default policy policy<>, needs using boost::math::policies::policy;
+
+ l = find_scale<normal>(z, p, l, policy<>());
+ // Default policy, fully specified.
+ l = find_scale<normal>(z, p, l, boost::math::policies::policy<>());
+ // New policy, without typedef.
+ l = find_scale<normal>(z, p, l, policy<domain_error<ignore_error> >());
+/*`
+If we want to express a probability, say 0.999, that is a complement, `1 - p`
+we should not even think of writing `find_scale<normal>(z, 1 - p, l)`,
+but use the __complements version (see __why_complements).
+*/
+ z = -2.;
+ double q = 0.999; // = 1 - p; // complement of 0.001.
+ sd = find_scale<normal>(complement(z, q, l));
+
+ normal np95pc(l, sd); // Same standard_deviation (scale) but with mean(scale) shifted
+ cout << "Normal distribution with mean = " << l << " has "
+ << "fraction <= " << z << " = " << cdf(np95pc, z) << endl;
+ cout << "Normal distribution with mean = " << l << " has "
+ << "fraction > " << z << " = " << cdf(complement(np95pc, z)) << endl;
+
+/*`
+Sadly, it is all too easy to get probabilities the wrong way round,
+when you may get a warning like this:
+[pre
+Message from thrown exception was:
+ Error in function boost::math::find_scale<Dist, Policy>(complement(double, double, double, Policy)):
+ Computed scale (-0.48043523852179076) is <= 0! Was the complement intended?
+]
+The default error handling policy is to throw an exception with this message,
+but if you chose a policy to ignore the error,
+the (impossible) negative scale is quietly returned.
+*/
+//] [/find_scale2]
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+//[find_scale_example_output
+/*`
+[pre
+Example: Find scale (standard deviation).
+Normal distribution with mean = 0, standard deviation 1, has fraction <= -2, p = 0.0227501
+Normal distribution with mean = 0, standard deviation 1, has fraction > -2, p = 0.97725
+scale (standard deviation) = 0.647201
+Normal distribution with mean = 0 has fraction <= -2, p = 0.001
+Normal distribution with mean = 0 has fraction > -2, p = 0.999
+Normal distribution with mean = 0.946339 has fraction <= -2 = 0.001
+Normal distribution with mean = 0.946339 has fraction > -2 = 0.999
+]
+*/
+//] [/find_scale_example_output]
diff --git a/src/boost/libs/math/example/float128_example.cpp b/src/boost/libs/math/example/float128_example.cpp
new file mode 100644
index 000000000..23e01666a
--- /dev/null
+++ b/src/boost/libs/math/example/float128_example.cpp
@@ -0,0 +1,289 @@
+// Copyright John Maddock 2016
+// Copyright Christopher Kormanyos 2016.
+// Copyright Paul A. Bristow 2016.
+
+// 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)
+
+// Contains Quickbook snippets as C++ comments - do not remove.
+
+// http://gcc.gnu.org/onlinedocs/libquadmath/ GCC Quad-Precision Math Library
+// https://en.wikipedia.org/wiki/Quadruple-precision_floating-point_format
+
+// https://gcc.gnu.org/onlinedocs/gcc/C_002b_002b-Dialect-Options.html#C_002b_002b-Dialect-Options GNU 3.5 Options Controlling C++ Dialect
+// https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options 3.4 Options Controlling C Dialect
+
+//[float128_includes_1
+
+#include <boost/cstdfloat.hpp> // For float_64_t, float128_t. Must be first include!
+//#include <boost/config.hpp>
+#include <boost/multiprecision/float128.hpp>
+#include <boost/math/special_functions.hpp> // For gamma function.
+#include <boost/math/constants/constants.hpp> // For constants pi, e ...
+#include <typeinfo> //
+
+#include <cmath> // for pow function.
+
+// #include <quadmath.h>
+// C:\program files\gcc-6-win64\lib\gcc\x86_64-w64-mingw32\6.1.1\include\quadmath.h
+
+// i:\modular-boost\boost\multiprecision\float128.hpp|210| undefined reference to `quadmath_snprintf'.
+
+//] [/float128_includes_1]
+
+//[float128_dialect_1
+/*`To make float128 available it is vital to get the dialect and options on the command line correct.
+
+Quad type is forbidden by all the strict C++ standards, so using or adding -std=c++11 and later standards will prevent its use.
+so explicitly use -std=gnu++11, 1y, 14, 17, or 1z or ...
+
+For GCC 6.1.1, for example, the default is if no C++ language dialect options are given, is -std=gnu++14.
+
+See https://gcc.gnu.org/onlinedocs/gcc/C-Dialect-Options.html#C-Dialect-Options
+https://gcc.gnu.org/onlinedocs/gcc/Standards.html#Standards 2 Language Standards Supported by GCC
+
+ g++.exe -Wall -fexceptions -std=gnu++17 -g -fext-numeric-literals -fpermissive -lquadmath
+ -II:\modular-boost\libs\math\include -Ii:\modular-boost -c J:\Cpp\float128\float128\float128_example.cpp -o obj\Debug\float128_example.o
+
+Requires GCC linker option -lquadmath
+
+If this is missing, then get errors like:
+
+ \modular-boost\boost\multiprecision\float128.hpp|210|undefined reference to `quadmath_snprintf'|
+ \modular-boost\boost\multiprecision\float128.hpp|351|undefined reference to `sqrtq'|
+
+Requires compile option
+
+ -fext-numeric-literals
+
+If missing, then get errors like:
+
+\modular-boost\libs\math\include/boost/math/cstdfloat/cstdfloat_types.hpp:229:43: error: unable to find numeric literal operator 'operator""Q'
+
+A successful build log was:
+
+ g++.exe -Wall -std=c++11 -fexceptions -std=gnu++17 -g -fext-numeric-literals -II:\modular-boost\libs\math\include -Ii:\modular-boost -c J:\Cpp\float128\float128\float128_example.cpp -o obj\Debug\float128_example.o
+ g++.exe -o bin\Debug\float128.exe obj\Debug\float128_example.o -lquadmath
+*/
+
+//] [/float128_dialect_1]
+
+void show_versions(std::string title)
+{
+ std::cout << title << std::endl;
+
+ std::cout << "Platform: " << BOOST_PLATFORM << '\n'
+ << "Compiler: " << BOOST_COMPILER << '\n'
+ << "STL : " << BOOST_STDLIB << '\n'
+ << "Boost : " << BOOST_VERSION / 100000 << "."
+ << BOOST_VERSION / 100 % 1000 << "."
+ << BOOST_VERSION % 100
+ << std::endl;
+#ifdef _MSC_VER
+ std::cout << "_MSC_FULL_VER = " << _MSC_FULL_VER << std::endl; // VS 2015 190023026
+#if defined _M_IX86
+ std::cout << "(x86)" << std::endl;
+#endif
+#if defined _M_X64
+ std::cout << " (x64)" << std::endl;
+#endif
+#if defined _M_IA64
+ std::cout << " (Itanium)" << std::endl;
+#endif
+ // Something very wrong if more than one is defined (so show them in all just in case)!
+#endif // _MSC_VER
+#ifdef __GNUC__
+//PRINT_MACRO(__GNUC__);
+//PRINT_MACRO(__GNUC_MINOR__);
+//PRINT_MACRO(__GNUC_PATCH__);
+std::cout << "GCC " << __VERSION__ << std::endl;
+//PRINT_MACRO(LONG_MAX);
+#endif // __GNUC__
+ return;
+} // void show_version(std::string title)
+
+int main()
+{
+ try
+ {
+
+//[float128_example_3
+// Always use try'n'catch blocks to ensure any error messages are displayed.
+//`Ensure that all possibly significant digits (17) including trailing zeros are shown.
+
+ std::cout.precision(std::numeric_limits<boost::float64_t>::max_digits10);
+ std::cout.setf(std::ios::showpoint); // Show all significant trailing zeros.
+ //] [/ float128_example_3]
+
+#ifdef BOOST_FLOAT128_C
+ std::cout << "Floating-point type boost::float128_t is available." << std::endl;
+ std::cout << " std::numeric_limits<boost::float128_t>::digits10 == "
+ << std::numeric_limits<boost::float128_t>::digits10 << std::endl;
+ std::cout << " std::numeric_limits<boost::float128_t>::max_digits10 == "
+ << std::numeric_limits<boost::float128_t>::max_digits10 << std::endl;
+#else
+ std::cout << "Floating-point type boost::float128_t is NOT available." << std::endl;
+#endif
+
+ show_versions("");
+
+ using boost::multiprecision::float128; // Wraps, for example, __float128 or _Quad.
+ // or
+ //using namespace boost::multiprecision;
+
+ std::cout.precision(std::numeric_limits<float128>::max_digits10); // Show all potentially meaningful digits.
+ std::cout.setf(std::ios::showpoint); // Show all significant trailing zeros.
+
+ // float128 pi0 = boost::math::constants::pi(); // Compile fails - need to specify a type for the constant!
+
+ float128 pi1 = boost::math::constants::pi<float128>(); // Returns a constant of type float128.
+ std::cout << sqrt(pi1) << std::endl; // 1.77245385090551602729816748334114514
+
+ float128 pi2 = boost::math::constants::pi<__float128>(); // Constant of type __float128 gets converted to float128 on the assignment.
+ std::cout << sqrt(pi2) << std::endl; // 1.77245385090551602729816748334114514
+
+ // DIY decimal digit literal constant, with suffix Q.
+ float128 pi3 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348Q;
+ std::cout << sqrt(pi3) << std::endl; // 1.77245385090551602729816748334114514
+
+ // Compare to ready-rolled sqrt(pi) constant from Boost.Math:
+ std::cout << boost::math::constants::root_pi<float128>() << std::endl; // 1.77245385090551602729816748334114514
+
+ // DIY decimal digit literal constant, without suffix Q, suffering seventeen silent digits loss of precision!
+ float128 pi4 = 3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348;
+ std::cout << sqrt(pi4) << std::endl; // 1.77245385090551599275151910313924857
+
+ // float128 variables constructed from a quad-type literal can be declared constexpr if required:
+
+#ifndef BOOST_NO_CXX11_CONSTEXPR
+ constexpr float128 pi_constexpr = 3.1415926535897932384626433832795028841971693993751058Q;
+#endif
+ std::cout << pi_constexpr << std::endl; // 3.14159265358979323846264338327950280
+
+ // But sadly functions like sqrt are not yet available constexpr for float128.
+
+ // constexpr float128 root_pi_constexpr = sqrt(pi_constexpr); // Fails - not constexpr (yet).
+ // constexpr float128 root_pi_constexpr = std::sqrt(pi_constexpr); // Fails - no known conversion for argument 1 from 'const float128'.
+ // constexpr float128 root_pi_constexpr = sqrt(pi_constexpr); // Call to non-constexpr
+ // constexpr float128 root_pi_constexpr = boost::math::constants::root_pi(); // Missing type for constant.
+
+ // Best current way to get a constexpr is to use a Boost.Math constant if one is available.
+ constexpr float128 root_pi_constexpr = boost::math::constants::root_pi<float128>();
+ std::cout << root_pi_constexpr << std::endl; // 1.77245385090551602729816748334114514
+
+ // Note that casts within the sqrt call are NOT NEEDED (nor allowed),
+ // since all the variables are the correct type to begin with.
+ // std::cout << sqrt<float128>(pi3) << std::endl;
+ // But note examples of catastrophic (but hard to see) loss of precision below.
+
+ // Note also that the library functions, here sqrt, is NOT defined using std::sqrt,
+ // so that the correct overload is found using Argument Dependent LookUp (ADL).
+
+ float128 ee = boost::math::constants::e<float128>();
+ std::cout << ee << std::endl; // 2.71828182845904523536028747135266231
+
+ float128 e1 = exp(1.Q); // Note argument to exp is type float128.
+ std::cout << e1 << std::endl; // 2.71828182845904523536028747135266231
+
+ // Beware - it is all too easy to silently get a much lower precision by mistake.
+
+ float128 e1d = exp(1.); // Caution - only double 17 decimal digits precision!
+ std::cout << e1d << std::endl; // 2.71828182845904509079559829842764884
+
+ float128 e1i = exp(1); // Caution int promoted to double so only 17 decimal digits precision!
+ std::cout << e1i << std::endl; // 2.71828182845904509079559829842764884
+
+ float f1 = 1.F;
+ float128 e1f = exp(f1); // Caution float so only 6 decimal digits precision out of 36!
+ std::cout << e1f << std::endl; // 2.71828174591064453125000000000000000
+
+ // In all these cases you get what you asked for and not what you expected or wanted.
+
+ // Casting is essential if you start with a lower precision type.
+
+ float128 e1q = exp(static_cast<float128>(f1)); // Full 36 decimal digits precision!
+ std::cout << e1q << std::endl; // 2.71828182845904523536028747135266231
+
+ float128 e1qc = exp((float128)f1); // Full 36 decimal digits precision!
+ std::cout << e1qc << std::endl; // 2.71828182845904523536028747135266231
+
+ float128 e1qcc = exp(float128(f1)); // Full 36 decimal digits precision!
+ std::cout << e1qcc << std::endl; // 2.71828182845904523536028747135266231
+
+ //float128 e1q = exp<float128>(1.); // Compile fails.
+ // std::cout << e1q << std::endl; //
+
+// http://en.cppreference.com/w/cpp/language/typeid
+// The name()is implementation-dependent mangled, and may not be able to be output.
+// The example showing output using one of the implementations where type_info::name prints full type names;
+// filter through c++filt -t if using gcc or similar.
+
+//[float128_type_info
+const std::type_info& tifu128 = typeid(__float128); // OK.
+//std::cout << tifu128.name() << std::endl; // On GCC, aborts (because not printable string).
+//std::cout << typeid(__float128).name() << std::endl; // Aborts -
+// string name cannot be output.
+
+const std::type_info& tif128 = typeid(float128); // OK.
+std::cout << tif128.name() << std::endl; // OK.
+std::cout << typeid(float128).name() << std::endl; // OK.
+
+const std::type_info& tpi = typeid(pi1); // OK using GCC 6.1.1.
+// (from GCC 5 according to http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43622)
+std::cout << tpi.name() << std::endl; // OK, Output implementation-dependent mangled name:
+
+// N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE
+
+//] [/float128_type_info]
+
+ }
+ catch (std::exception ex)
+ { // Display details about why any exceptions are thrown.
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+} // int main()
+
+/*
+[float128_output
+
+-std=c++11 or -std=c++17 don't work
+
+Floating-point type boost::float128_t is NOT available.
+
+Platform: Win32
+Compiler: GNU C++ version 6.1.1 20160609
+STL : GNU libstdc++ version 20160609
+Boost : 1.62.0
+GCC 6.1.1 20160609
+
+
+Added -fext-numeric-literals to
+
+-std=gnu++11 -fext-numeric-literals -lquadmath
+
+Floating-point type boost::float128_t is available.
+ std::numeric_limits<boost::float128_t>::digits10 == 33
+ std::numeric_limits<boost::float128_t>::max_digits10 == 36
+
+Platform: Win32
+Compiler: GNU C++ version 6.1.1 20160609
+STL : GNU libstdc++ version 20160609
+Boost : 1.62.0
+GCC 6.1.1 20160609
+1.77245385090551602729816748334114514
+1.77245385090551602729816748334114514
+1.77245385090551602729816748334114514
+1.77245385090551602729816748334114514
+N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE
+N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE
+N5boost14multiprecision6numberINS0_8backends16float128_backendELNS0_26expression_template_optionE0EEE
+
+Process returned 0 (0x0) execution time : 0.033 s
+Press any key to continue.
+
+
+
+//] [/float128_output]
+
+*/
diff --git a/src/boost/libs/math/example/float_comparison_example.cpp b/src/boost/libs/math/example/float_comparison_example.cpp
new file mode 100644
index 000000000..6c892fa21
--- /dev/null
+++ b/src/boost/libs/math/example/float_comparison_example.cpp
@@ -0,0 +1,444 @@
+//!file
+//! \brief floating-point comparison from Boost.Test
+// Copyright Paul A. Bristow 2015.
+// Copyright John Maddock 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)
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <boost/math/special_functions/relative_difference.hpp>
+#include <boost/math/special_functions/next.hpp>
+
+#include <iostream>
+#include <limits> // for std::numeric_limits<T>::epsilon().
+
+int main()
+{
+ std::cout << "Compare floats using Boost.Math functions/classes" << std::endl;
+
+
+//[compare_floats_using
+/*`Some using statements will ensure that the functions we need are accessible.
+*/
+
+ using namespace boost::math;
+
+//`or
+
+ using boost::math::relative_difference;
+ using boost::math::epsilon_difference;
+ using boost::math::float_next;
+ using boost::math::float_prior;
+
+//] [/compare_floats_using]
+
+
+//[compare_floats_example_1
+/*`The following examples display values with all possibly significant digits.
+Newer compilers should provide `std::numeric_limits<FPT>::max_digits10`
+for this purpose, and here we use `float` precision where `max_digits10` = 9
+to avoid displaying a distracting number of decimal digits.
+
+[note Older compilers can use this formula to calculate `max_digits10`
+from `std::numeric_limits<FPT>::digits10`:
+__spaces `int max_digits10 = 2 + std::numeric_limits<FPT>::digits10 * 3010/10000;`
+] [/note]
+
+One can set the display including all trailing zeros
+(helpful for this example to show all potentially significant digits),
+and also to display `bool` values as words rather than integers:
+*/
+ std::cout.precision(std::numeric_limits<float>::max_digits10);
+ std::cout << std::boolalpha << std::showpoint << std::endl;
+
+//] [/compare_floats_example_1]
+
+//[compare_floats_example_2]
+/*`
+When comparing values that are ['quite close] or ['approximately equal],
+we could use either `float_distance` or `relative_difference`/`epsilon_difference`, for example
+with type `float`, these two values are adjacent to each other:
+*/
+
+ float a = 1;
+ float b = 1 + std::numeric_limits<float>::epsilon();
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "float_distance = " << float_distance(a, b) << std::endl;
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ std::cout << "epsilon_difference = " << epsilon_difference(a, b) << std::endl;
+
+/*`
+Which produces the output:
+
+[pre
+a = 1.00000000
+b = 1.00000012
+float_distance = 1.00000000
+relative_difference = 1.19209290e-007
+epsilon_difference = 1.00000000
+]
+*/
+ //] [/compare_floats_example_2]
+
+//[compare_floats_example_3]
+/*`
+In the example above, it just so happens that the edit distance as measured by `float_distance`, and the
+difference measured in units of epsilon were equal. However, due to the way floating point
+values are represented, that is not always the case:*/
+
+ a = 2.0f / 3.0f; // 2/3 inexactly represented as a float
+ b = float_next(float_next(float_next(a))); // 3 floating point values above a
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "float_distance = " << float_distance(a, b) << std::endl;
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ std::cout << "epsilon_difference = " << epsilon_difference(a, b) << std::endl;
+
+/*`
+Which produces the output:
+
+[pre
+a = 0.666666687
+b = 0.666666865
+float_distance = 3.00000000
+relative_difference = 2.68220901e-007
+epsilon_difference = 2.25000000
+]
+
+There is another important difference between `float_distance` and the
+`relative_difference/epsilon_difference` functions in that `float_distance`
+returns a signed result that reflects which argument is larger in magnitude,
+where as `relative_difference/epsilon_difference` simply return an unsigned
+value that represents how far apart the values are. For example if we swap
+the order of the arguments:
+*/
+
+ std::cout << "float_distance = " << float_distance(b, a) << std::endl;
+ std::cout << "relative_difference = " << relative_difference(b, a) << std::endl;
+ std::cout << "epsilon_difference = " << epsilon_difference(b, a) << std::endl;
+
+ /*`
+ The output is now:
+
+ [pre
+ float_distance = -3.00000000
+ relative_difference = 2.68220901e-007
+ epsilon_difference = 2.25000000
+ ]
+*/
+ //] [/compare_floats_example_3]
+
+//[compare_floats_example_4]
+/*`
+Zeros are always treated as equal, as are infinities as long as they have the same sign:*/
+
+ a = 0;
+ b = -0; // signed zero
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ a = b = std::numeric_limits<float>::infinity();
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ std::cout << "relative_difference = " << relative_difference(a, -b) << std::endl;
+
+/*`
+Which produces the output:
+
+[pre
+relative_difference = 0.000000000
+relative_difference = 0.000000000
+relative_difference = 3.40282347e+038
+]
+*/
+//] [/compare_floats_example_4]
+
+//[compare_floats_example_5]
+/*`
+Note that finite values are always infinitely far away from infinities even if those finite values are very large:*/
+
+ a = (std::numeric_limits<float>::max)();
+ b = std::numeric_limits<float>::infinity();
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ std::cout << "epsilon_difference = " << epsilon_difference(a, b) << std::endl;
+
+/*`
+Which produces the output:
+
+[pre
+a = 3.40282347e+038
+b = 1.#INF0000
+relative_difference = 3.40282347e+038
+epsilon_difference = 3.40282347e+038
+]
+*/
+//] [/compare_floats_example_5]
+
+//[compare_floats_example_6]
+/*`
+Finally, all denormalized values and zeros are treated as being effectively equal:*/
+
+ a = std::numeric_limits<float>::denorm_min();
+ b = a * 2;
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "float_distance = " << float_distance(a, b) << std::endl;
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ std::cout << "epsilon_difference = " << epsilon_difference(a, b) << std::endl;
+ a = 0;
+ std::cout << "a = " << a << std::endl;
+ std::cout << "b = " << b << std::endl;
+ std::cout << "float_distance = " << float_distance(a, b) << std::endl;
+ std::cout << "relative_difference = " << relative_difference(a, b) << std::endl;
+ std::cout << "epsilon_difference = " << epsilon_difference(a, b) << std::endl;
+
+/*`
+Which produces the output:
+
+[pre
+a = 1.40129846e-045
+b = 2.80259693e-045
+float_distance = 1.00000000
+relative_difference = 0.000000000
+epsilon_difference = 0.000000000
+a = 0.000000000
+b = 2.80259693e-045
+float_distance = 2.00000000
+relative_difference = 0.000000000
+epsilon_difference = 0.000000000]
+
+Notice how, in the above example, two denormalized values that are a factor of 2 apart are
+none the less only one representation apart!
+
+*/
+//] [/compare_floats_example_6]
+
+
+#if 0
+//[old_compare_floats_example_3
+//`The simplest use is to compare two values with a tolerance thus:
+
+ bool is_close = is_close_to(1.F, 1.F + epsilon, epsilon); // One epsilon apart is close enough.
+ std::cout << "is_close_to(1.F, 1.F + epsilon, epsilon); is " << is_close << std::endl; // true
+
+ is_close = is_close_to(1.F, 1.F + 2 * epsilon, epsilon); // Two epsilon apart isn't close enough.
+ std::cout << "is_close_to(1.F, 1.F + epsilon, epsilon); is " << is_close << std::endl; // false
+
+/*`
+[note The type FPT of the tolerance and the type of the values [*must match].
+
+So `is_close(0.1F, 1., 1.)` will fail to compile because "template parameter 'FPT' is ambiguous".
+Always provide the same type, using `static_cast<FPT>` if necessary.]
+*/
+
+
+/*`An instance of class `close_at_tolerance` is more convenient
+when multiple tests with the same conditions are planned.
+A class that stores a tolerance of three epsilon (and the default ['strong] test) is:
+*/
+
+ close_at_tolerance<float> three_rounds(3 * epsilon); // 'strong' by default.
+
+//`and we can confirm these settings:
+
+ std::cout << "fraction_tolerance = "
+ << three_rounds.fraction_tolerance()
+ << std::endl; // +3.57627869e-007
+ std::cout << "strength = "
+ << (three_rounds.strength() == FPC_STRONG ? "strong" : "weak")
+ << std::endl; // strong
+
+//`To start, let us use two values that are truly equal (having identical bit patterns)
+
+ float a = 1.23456789F;
+ float b = 1.23456789F;
+
+//`and make a comparison using our 3*epsilon `three_rounds` functor:
+
+ bool close = three_rounds(a, b);
+ std::cout << "three_rounds(a, b) = " << close << std::endl; // true
+
+//`Unsurprisingly, the result is true, and the failed fraction is zero.
+
+ std::cout << "failed_fraction = " << three_rounds.failed_fraction() << std::endl;
+
+/*`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>
+
+and some using declarations:
+*/
+
+ using boost::math::float_next;
+ using boost::math::float_prior;
+ using boost::math::nextafter;
+ using boost::math::float_distance;
+
+//`To add a few __ulp to one value:
+ b = float_next(a); // Add just one ULP to a.
+ b = float_next(b); // Add another one ULP.
+ b = float_next(b); // Add another one ULP.
+ // 3 epsilon would pass.
+ b = float_next(b); // Add another one ULP.
+
+//`and repeat our comparison:
+
+ close = three_rounds(a, b);
+ std::cout << "three_rounds(a, b) = " << close << std::endl; // false
+ std::cout << "failed_fraction = " << three_rounds.failed_fraction()
+ << std::endl; // abs(u-v) / abs(v) = 3.86237957e-007
+
+//`We can also 'measure' the number of bits different using the `float_distance` function:
+
+ std::cout << "float_distance = " << float_distance(a, b) << std::endl; // 4
+
+/*`Now consider two values that are much further apart
+than one might expect from ['computational noise],
+perhaps the result of two measurements of some physical property like length
+where an uncertainty of a percent or so might be expected.
+*/
+ float fp1 = 0.01000F;
+ float fp2 = 0.01001F; // Slightly different.
+
+ float tolerance = 0.0001F;
+
+ close_at_tolerance<float> strong(epsilon); // Default is strong.
+ bool rs = strong(fp1, fp2);
+ std::cout << "strong(fp1, fp2) is " << rs << std::endl;
+
+//`Or we could contrast using the ['weak] criterion:
+ close_at_tolerance<float> weak(epsilon, FPC_WEAK); // Explicitly weak.
+ bool rw = weak(fp1, fp2); //
+ std::cout << "weak(fp1, fp2) is " << rw << std::endl;
+
+//`We can also construct, setting tolerance and strength, and compare in one statement:
+
+ std::cout << a << " #= " << b << " is "
+ << close_at_tolerance<float>(epsilon, FPC_STRONG)(a, b) << std::endl;
+ std::cout << a << " ~= " << b << " is "
+ << close_at_tolerance<float>(epsilon, FPC_WEAK)(a, b) << std::endl;
+
+//`but this has little advantage over using function `is_close_to` directly.
+
+//] [/old_compare_floats_example_3]
+
+
+/*When the floating-point values become very small and near zero, using
+//a relative test becomes unhelpful because one is dividing by zero or tiny,
+
+//Instead, an absolute test is needed, comparing one (or usually both) values with zero,
+//using a tolerance.
+//This is provided by the `small_with_tolerance` class and `is_small` function.
+
+ namespace boost {
+ namespace math {
+ namespace fpc {
+
+
+ template<typename FPT>
+ class small_with_tolerance
+ {
+ public:
+ // Public typedefs.
+ typedef bool result_type;
+
+ // Constructor.
+ explicit small_with_tolerance(FPT tolerance); // tolerance >= 0
+
+ // Functor
+ bool operator()(FPT value) const; // return true if <= absolute tolerance (near zero).
+ };
+
+ template<typename FPT>
+ bool
+ is_small(FPT value, FPT tolerance); // return true if value <= absolute tolerance (near zero).
+
+ }}} // namespaces.
+
+/*`
+[note The type FPT of the tolerance and the type of the value [*must match].
+
+So `is_small(0.1F, 0.000001)` will fail to compile because "template parameter 'FPT' is ambiguous".
+Always provide the same type, using `static_cast<FPT>` if necessary.]
+
+A few values near zero are tested with varying tolerance below.
+*/
+//[compare_floats_small_1
+
+ float c = 0;
+ std::cout << "0 is_small " << is_small(c, epsilon) << std::endl; // true
+
+ c = std::numeric_limits<float>::denorm_min(); // 1.40129846e-045
+ std::cout << "denorm_ min =" << c << ", is_small is " << is_small(c, epsilon) << std::endl; // true
+
+ c = (std::numeric_limits<float>::min)(); // 1.17549435e-038
+ std::cout << "min = " << c << ", is_small is " << is_small(c, epsilon) << std::endl; // true
+
+ c = 1 * epsilon; // 1.19209290e-007
+ std::cout << "epsilon = " << c << ", is_small is " << is_small(c, epsilon) << std::endl; // false
+
+ c = 1 * epsilon; // 1.19209290e-007
+ std::cout << "2 epsilon = " << c << ", is_small is " << is_small(c, 2 * epsilon) << std::endl; // true
+
+ c = 2 * epsilon; //2.38418579e-007
+ std::cout << "4 epsilon = " << c << ", is_small is " << is_small(c, 2 * epsilon) << std::endl; // false
+
+ c = 0.00001F;
+ std::cout << "0.00001 = " << c << ", is_small is " << is_small(c, 0.0001F) << std::endl; // true
+
+ c = -0.00001F;
+ std::cout << "0.00001 = " << c << ", is_small is " << is_small(c, 0.0001F) << std::endl; // true
+
+/*`Using the class `small_with_tolerance` allows storage of the tolerance,
+convenient if you make repeated tests with the same tolerance.
+*/
+
+ small_with_tolerance<float>my_test(0.01F);
+
+ std::cout << "my_test(0.001F) is " << my_test(0.001F) << std::endl; // true
+ std::cout << "my_test(0.001F) is " << my_test(0.01F) << std::endl; // false
+
+ //] [/compare_floats_small_1]
+#endif
+ return 0;
+} // int main()
+
+/*
+
+Example output is:
+
+//[compare_floats_output
+Compare floats using Boost.Test functions/classes
+
+float epsilon = 1.19209290e-007
+is_close_to(1.F, 1.F + epsilon, epsilon); is true
+is_close_to(1.F, 1.F + epsilon, epsilon); is false
+fraction_tolerance = 3.57627869e-007
+strength = strong
+three_rounds(a, b) = true
+failed_fraction = 0.000000000
+three_rounds(a, b) = false
+failed_fraction = 3.86237957e-007
+float_distance = 4.00000000
+strong(fp1, fp2) is false
+weak(fp1, fp2) is false
+1.23456788 #= 1.23456836 is false
+1.23456788 ~= 1.23456836 is false
+0 is_small true
+denorm_ min =1.40129846e-045, is_small is true
+min = 1.17549435e-038, is_small is true
+epsilon = 1.19209290e-007, is_small is false
+2 epsilon = 1.19209290e-007, is_small is true
+4 epsilon = 2.38418579e-007, is_small is false
+0.00001 = 9.99999975e-006, is_small is true
+0.00001 = -9.99999975e-006, is_small is true
+my_test(0.001F) is true
+
+my_test(0.001F) is false//] [/compare_floats_output]
+*/
diff --git a/src/boost/libs/math/example/gauss_example.cpp b/src/boost/libs/math/example/gauss_example.cpp
new file mode 100644
index 000000000..466d58b4c
--- /dev/null
+++ b/src/boost/libs/math/example/gauss_example.cpp
@@ -0,0 +1,142 @@
+/*
+ * Copyright John Maddock, 2017
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * This example Illustrates numerical integration via Gauss and Gauss-Kronrod quadrature.
+ */
+
+#include <iostream>
+#include <cmath>
+#include <limits>
+#include <boost/math/quadrature/gauss.hpp>
+#include <boost/math/quadrature/gauss_kronrod.hpp>
+#include <boost/math/constants/constants.hpp>
+#include <boost/math/special_functions/relative_difference.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+
+void gauss_examples()
+{
+ //[gauss_example
+
+ /*`
+ We'll begin by integrating t[super 2] atan(t) over (0,1) using a 7 term Gauss-Legendre rule,
+ and begin by defining the function to integrate as a C++ lambda expression:
+ */
+ using namespace boost::math::quadrature;
+
+ auto f = [](const double& t) { return t * t * std::atan(t); };
+
+ /*`
+ Integration is simply a matter of calling the `gauss<double, 7>::integrate` method:
+ */
+
+ double Q = gauss<double, 7>::integrate(f, 0, 1);
+
+ /*`
+ Which yields a value 0.2106572512 accurate to 1e-10.
+
+ For more accurate evaluations, we'll move to a multiprecision type and use a 20-point integration scheme:
+ */
+
+ using boost::multiprecision::cpp_bin_float_quad;
+
+ auto f2 = [](const cpp_bin_float_quad& t) { return t * t * atan(t); };
+
+ cpp_bin_float_quad Q2 = gauss<cpp_bin_float_quad, 20>::integrate(f2, 0, 1);
+
+ /*`
+ Which yields 0.2106572512258069881080923020669, which is accurate to 5e-28.
+ */
+
+ //]
+
+ std::cout << std::setprecision(18) << Q << std::endl;
+ std::cout << boost::math::relative_difference(Q, (boost::math::constants::pi<double>() - 2 + 2 * boost::math::constants::ln_two<double>()) / 12) << std::endl;
+
+ std::cout << std::setprecision(34) << Q2 << std::endl;
+ std::cout << boost::math::relative_difference(Q2, (boost::math::constants::pi<cpp_bin_float_quad>() - 2 + 2 * boost::math::constants::ln_two<cpp_bin_float_quad>()) / 12) << std::endl;
+}
+
+void gauss_kronrod_examples()
+{
+ //[gauss_kronrod_example
+
+ /*`
+ We'll begin by integrating exp(-t[super 2]/2) over (0,+[infin]) using a 7 term Gauss rule
+ and 15 term Kronrod rule,
+ and begin by defining the function to integrate as a C++ lambda expression:
+ */
+ using namespace boost::math::quadrature;
+
+ auto f1 = [](double t) { return std::exp(-t*t / 2); };
+
+ //<-
+ double Q_expected = sqrt(boost::math::constants::half_pi<double>());
+ //->
+
+ /*`
+ We'll start off with a one shot (ie non-adaptive)
+ integration, and keep track of the estimated error:
+ */
+ double error;
+ double Q = gauss_kronrod<double, 15>::integrate(f1, 0, std::numeric_limits<double>::infinity(), 0, 0, &error);
+
+ /*`
+ This yields Q = 1.25348207361, which has an absolute error of 1e-4 compared to the estimated error
+ of 5e-3: this is fairly typical, with the difference between Gauss and Gauss-Kronrod schemes being
+ much higher than the actual error. Before moving on to adaptive quadrature, lets try again
+ with more points, in fact with the largest Gauss-Kronrod scheme we have cached (30/61):
+ */
+ //<-
+ std::cout << std::setprecision(16) << Q << std::endl;
+ std::cout << boost::math::relative_difference(Q, Q_expected) << std::endl;
+ std::cout << fabs(Q - Q_expected) << std::endl;
+ std::cout << error << std::endl;
+ //->
+ Q = gauss_kronrod<double, 61>::integrate(f1, 0, std::numeric_limits<double>::infinity(), 0, 0, &error);
+ //<-
+ std::cout << std::setprecision(16) << Q << std::endl;
+ std::cout << boost::math::relative_difference(Q, Q_expected) << std::endl;
+ std::cout << fabs(Q - Q_expected) << std::endl;
+ std::cout << error << std::endl;
+ //->
+ /*`
+ This yields an absolute error of 3e-15 against an estimate of 1e-8, which is about as good as we're going to get
+ at double precision
+
+ However, instead of continuing with ever more points, lets switch to adaptive integration, and set the desired relative
+ error to 1e-14 against a maximum depth of 5:
+ */
+ Q = gauss_kronrod<double, 15>::integrate(f1, 0, std::numeric_limits<double>::infinity(), 5, 1e-14, &error);
+ //<-
+ std::cout << std::setprecision(16) << Q << std::endl;
+ std::cout << boost::math::relative_difference(Q, Q_expected) << std::endl;
+ std::cout << fabs(Q - Q_expected) << std::endl;
+ std::cout << error << std::endl;
+ //->
+ /*`
+ This yields an actual error of zero, against an estimate of 4e-15. In fact in this case the requested tolerance was almost
+ certainly set too low: as we've seen above, for smooth functions, the precision achieved is often double
+ that of the estimate, so if we integrate with a tolerance of 1e-9:
+ */
+ Q = gauss_kronrod<double, 15>::integrate(f1, 0, std::numeric_limits<double>::infinity(), 5, 1e-9, &error);
+ //<-
+ std::cout << std::setprecision(16) << Q << std::endl;
+ std::cout << boost::math::relative_difference(Q, Q_expected) << std::endl;
+ std::cout << fabs(Q - Q_expected) << std::endl;
+ std::cout << error << std::endl;
+ //->
+ /*`
+ We still achieve 1e-15 precision, with an error estimate of 1e-10.
+ */
+ //]
+}
+
+int main()
+{
+ gauss_examples();
+ gauss_kronrod_examples();
+ return 0;
+}
diff --git a/src/boost/libs/math/example/geometric_examples.cpp b/src/boost/libs/math/example/geometric_examples.cpp
new file mode 100644
index 000000000..92ea28e56
--- /dev/null
+++ b/src/boost/libs/math/example/geometric_examples.cpp
@@ -0,0 +1,364 @@
+// geometric_examples.cpp
+
+// Copyright Paul A. Bristow 2010.
+
+// 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)
+
+// This file is written to be included from a Quickbook .qbk document.
+// It can still be compiled by the C++ compiler, and run.
+// Any output can also be added here as comment or included or pasted in elsewhere.
+// Caution: this file contains Quickbook markup as well as code
+// and comments: don't change any of the special comment markups!
+
+// Examples of using the geometric distribution.
+
+//[geometric_eg1_1
+/*`
+For this example, we will opt to #define two macros to control
+the error and discrete handling policies.
+For this simple example, we want to avoid throwing
+an exception (the default policy) and just return infinity.
+We want to treat the distribution as if it was continuous,
+so we choose a discrete_quantile policy of real,
+rather than the default policy integer_round_outwards.
+*/
+#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
+#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
+/*`
+[caution It is vital to #include distributions etc *after* the above #defines]
+After that we need some includes to provide easy access to the negative binomial distribution,
+and we need some std library iostream, of course.
+*/
+#include <boost/math/distributions/geometric.hpp>
+ // for geometric_distribution
+ using ::boost::math::geometric_distribution; //
+ using ::boost::math::geometric; // typedef provides default type is double.
+ using ::boost::math::pdf; // Probability mass function.
+ using ::boost::math::cdf; // Cumulative density function.
+ using ::boost::math::quantile;
+
+#include <boost/math/distributions/negative_binomial.hpp>
+ // for negative_binomial_distribution
+ using boost::math::negative_binomial; // typedef provides default type is double.
+
+#include <boost/math/distributions/normal.hpp>
+ // for negative_binomial_distribution
+ using boost::math::normal; // typedef provides default type is double.
+
+#include <iostream>
+ using std::cout; using std::endl;
+ using std::noshowpoint; using std::fixed; using std::right; using std::left;
+#include <iomanip>
+ using std::setprecision; using std::setw;
+
+#include <limits>
+ using std::numeric_limits;
+//] [geometric_eg1_1]
+
+int main()
+{
+ cout <<"Geometric distribution example" << endl;
+ cout << endl;
+
+ cout.precision(4); // But only show a few for this example.
+ try
+ {
+//[geometric_eg1_2
+/*`
+It is always sensible to use try and catch blocks because defaults policies are to
+throw an exception if anything goes wrong.
+
+Simple try'n'catch blocks (see below) will ensure that you get a
+helpful error message instead of an abrupt (and silent) program abort.
+
+[h6 Throwing a dice]
+The Geometric distribution describes the probability (/p/) of a number of failures
+to get the first success in /k/ Bernoulli trials.
+(A [@http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli trial]
+is one with only two possible outcomes, success of failure,
+and /p/ is the probability of success).
+
+Suppose an 'fair' 6-face dice is thrown repeatedly:
+*/
+ double success_fraction = 1./6; // success_fraction (p) = 0.1666
+ // (so failure_fraction is 1 - success_fraction = 5./6 = 1- 0.1666 = 0.8333)
+
+/*`If the dice is thrown repeatedly until the *first* time a /three/ appears.
+The probability distribution of the number of times it is thrown *not* getting a /three/
+ (/not-a-threes/ number of failures to get a /three/)
+is a geometric distribution with the success_fraction = 1/6 = 0.1666[recur].
+
+We therefore start by constructing a geometric distribution
+with the one parameter success_fraction, the probability of success.
+*/
+ geometric g6(success_fraction); // type double by default.
+/*`
+To confirm, we can echo the success_fraction parameter of the distribution.
+*/
+ cout << "success fraction of a six-sided dice is " << g6.success_fraction() << endl;
+/*`So the probability of getting a three at the first throw (zero failures) is
+*/
+ cout << pdf(g6, 0) << endl; // 0.1667
+ cout << cdf(g6, 0) << endl; // 0.1667
+/*`Note that the cdf and pdf are identical because the is only one throw.
+If we want the probability of getting the first /three/ on the 2nd throw:
+*/
+ cout << pdf(g6, 1) << endl; // 0.1389
+
+/*`If we want the probability of getting the first /three/ on the 1st or 2nd throw
+(allowing one failure):
+*/
+ cout << "pdf(g6, 0) + pdf(g6, 1) = " << pdf(g6, 0) + pdf(g6, 1) << endl;
+/*`Or more conveniently, and more generally,
+we can use the Cumulative Distribution Function CDF.*/
+
+ cout << "cdf(g6, 1) = " << cdf(g6, 1) << endl; // 0.3056
+
+/*`If we allow many more (12) throws, the probability of getting our /three/ gets very high:*/
+ cout << "cdf(g6, 12) = " << cdf(g6, 12) << endl; // 0.9065 or 90% probability.
+/*`If we want to be much more confident, say 99%,
+we can estimate the number of throws to be this sure
+using the inverse or quantile.
+*/
+ cout << "quantile(g6, 0.99) = " << quantile(g6, 0.99) << endl; // 24.26
+/*`Note that the value returned is not an integer:
+if you want an integer result you should use either floor, round or ceil functions,
+or use the policies mechanism.
+
+See __understand_dis_quant.
+
+The geometric distribution is related to the negative binomial
+__spaces `negative_binomial_distribution(RealType r, RealType p);` with parameter /r/ = 1.
+So we could get the same result using the negative binomial,
+but using the geometric the results will be faster, and may be more accurate.
+*/
+ negative_binomial nb(1, success_fraction);
+ cout << pdf(nb, 1) << endl; // 0.1389
+ cout << cdf(nb, 1) << endl; // 0.3056
+/*`We could also the complement to express the required probability
+as 1 - 0.99 = 0.01 (and get the same result):
+*/
+ cout << "quantile(complement(g6, 1 - p)) " << quantile(complement(g6, 0.01)) << endl; // 24.26
+/*`
+Note too that Boost.Math geometric distribution is implemented as a continuous function.
+Unlike other implementations (for example R) it *uses* the number of failures as a *real* parameter,
+not as an integer. If you want this integer behaviour, you may need to enforce this by
+rounding the parameter you pass, probably rounding down, to the nearest integer.
+For example, R returns the success fraction probability for all values of failures
+from 0 to 0.999999 thus:
+[pre
+__spaces R> formatC(pgeom(0.0001,0.5, FALSE), digits=17) " 0.5"
+] [/pre]
+So in Boost.Math the equivalent is
+*/
+ geometric g05(0.5); // Probability of success = 0.5 or 50%
+ // Output all potentially significant digits for the type, here double.
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ int max_digits10 = 2 + (boost::math::policies::digits<double, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
+ cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined" << endl;
+#else
+ int max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+ cout << "Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = "
+ << max_digits10 << endl;
+ cout.precision(max_digits10); //
+
+ cout << cdf(g05, 0.0001) << endl; // returns 0.5000346561579232, not exact 0.5.
+/*`To get the R discrete behaviour, you simply need to round with,
+for example, the `floor` function.
+*/
+ cout << cdf(g05, floor(0.0001)) << endl; // returns exactly 0.5
+/*`
+[pre
+`> formatC(pgeom(0.9999999,0.5, FALSE), digits=17) [1] " 0.25"`
+`> formatC(pgeom(1.999999,0.5, FALSE), digits=17)[1] " 0.25" k = 1`
+`> formatC(pgeom(1.9999999,0.5, FALSE), digits=17)[1] "0.12500000000000003" k = 2`
+] [/pre]
+shows that R makes an arbitrary round-up decision at about 1e7 from the next integer above.
+This may be convenient in practice, and could be replicated in C++ if desired.
+
+[h6 Surveying customers to find one with a faulty product]
+A company knows from warranty claims that 2% of their products will be faulty,
+so the 'success_fraction' of finding a fault is 0.02.
+It wants to interview a purchaser of faulty products to assess their 'user experience'.
+
+To estimate how many customers they will probably need to contact
+in order to find one who has suffered from the fault,
+we first construct a geometric distribution with probability 0.02,
+and then chose a confidence, say 80%, 95%, or 99% to finding a customer with a fault.
+Finally, we probably want to round up the result to the integer above using the `ceil` function.
+(We could also use a policy, but that is hardly worthwhile for this simple application.)
+
+(This also assumes that each customer only buys one product:
+if customers bought more than one item,
+the probability of finding a customer with a fault obviously improves.)
+*/
+ cout.precision(5);
+ geometric g(0.02); // On average, 2 in 100 products are faulty.
+ double c = 0.95; // 95% confidence.
+ cout << " quantile(g, " << c << ") = " << quantile(g, c) << endl;
+
+ cout << "To be " << c * 100
+ << "% confident of finding we customer with a fault, need to survey "
+ << ceil(quantile(g, c)) << " customers." << endl; // 148
+ c = 0.99; // Very confident.
+ cout << "To be " << c * 100
+ << "% confident of finding we customer with a fault, need to survey "
+ << ceil(quantile(g, c)) << " customers." << endl; // 227
+ c = 0.80; // Only reasonably confident.
+ cout << "To be " << c * 100
+ << "% confident of finding we customer with a fault, need to survey "
+ << ceil(quantile(g, c)) << " customers." << endl; // 79
+
+/*`[h6 Basket Ball Shooters]
+According to Wikipedia, average pro basket ball players get
+[@http://en.wikipedia.org/wiki/Free_throw free throws]
+in the baskets 70 to 80 % of the time,
+but some get as high as 95%, and others as low as 50%.
+Suppose we want to compare the probabilities
+of failing to get a score only on the first or on the fifth shot?
+To start we will consider the average shooter, say 75%.
+So we construct a geometric distribution
+with success_fraction parameter 75/100 = 0.75.
+*/
+ cout.precision(2);
+ geometric gav(0.75); // Shooter averages 7.5 out of 10 in the basket.
+/*`What is probability of getting 1st try in the basket, that is with no failures? */
+ cout << "Probability of score on 1st try = " << pdf(gav, 0) << endl; // 0.75
+/*`This is, of course, the success_fraction probability 75%.
+What is the probability that the shooter only scores on the fifth shot?
+So there are 5-1 = 4 failures before the first success.*/
+ cout << "Probability of score on 5th try = " << pdf(gav, 4) << endl; // 0.0029
+/*`Now compare this with the poor and the best players success fraction.
+We need to constructing new distributions with the different success fractions,
+and then get the corresponding probability density functions values:
+*/
+ geometric gbest(0.95);
+ cout << "Probability of score on 5th try = " << pdf(gbest, 4) << endl; // 5.9e-6
+ geometric gmediocre(0.50);
+ cout << "Probability of score on 5th try = " << pdf(gmediocre, 4) << endl; // 0.031
+/*`So we can see the very much smaller chance (0.000006) of 4 failures by the best shooters,
+compared to the 0.03 of the mediocre.*/
+
+/*`[h6 Estimating failures]
+Of course one man's failure is an other man's success.
+So a fault can be defined as a 'success'.
+
+If a fault occurs once after 100 flights, then one might naively say
+that the risk of fault is obviously 1 in 100 = 1/100, a probability of 0.01.
+
+This is the best estimate we can make, but while it is the truth,
+it is not the whole truth,
+for it hides the big uncertainty when estimating from a single event.
+"One swallow doesn't make a summer."
+To show the magnitude of the uncertainty, the geometric
+(or the negative binomial) distribution can be used.
+
+If we chose the popular 95% confidence in the limits, corresponding to an alpha of 0.05,
+because we are calculating a two-sided interval, we must divide alpha by two.
+*/
+ double alpha = 0.05;
+ double k = 100; // So frequency of occurrence is 1/100.
+ cout << "Probability is failure is " << 1/k << endl;
+ double t = geometric::find_lower_bound_on_p(k, alpha/2);
+ cout << "geometric::find_lower_bound_on_p(" << int(k) << ", " << alpha/2 << ") = "
+ << t << endl; // 0.00025
+ t = geometric::find_upper_bound_on_p(k, alpha/2);
+ cout << "geometric::find_upper_bound_on_p(" << int(k) << ", " << alpha/2 << ") = "
+ << t << endl; // 0.037
+/*`So while we estimate the probability is 0.01, it might lie between 0.0003 and 0.04.
+Even if we relax our confidence to alpha = 90%, the bounds only contract to 0.0005 and 0.03.
+And if we require a high confidence, they widen to 0.00005 to 0.05.
+*/
+ alpha = 0.1; // 90% confidence.
+ t = geometric::find_lower_bound_on_p(k, alpha/2);
+ cout << "geometric::find_lower_bound_on_p(" << int(k) << ", " << alpha/2 << ") = "
+ << t << endl; // 0.0005
+ t = geometric::find_upper_bound_on_p(k, alpha/2);
+ cout << "geometric::find_upper_bound_on_p(" << int(k) << ", " << alpha/2 << ") = "
+ << t << endl; // 0.03
+
+ alpha = 0.01; // 99% confidence.
+ t = geometric::find_lower_bound_on_p(k, alpha/2);
+ cout << "geometric::find_lower_bound_on_p(" << int(k) << ", " << alpha/2 << ") = "
+ << t << endl; // 5e-005
+ t = geometric::find_upper_bound_on_p(k, alpha/2);
+ cout << "geometric::find_upper_bound_on_p(" << int(k) << ", " << alpha/2 << ") = "
+ << t << endl; // 0.052
+/*`In real life, there will usually be more than one event (fault or success),
+when the negative binomial, which has the necessary extra parameter, will be needed.
+*/
+
+/*`As noted above, using a catch block is always a good idea,
+even if you hope not to use it!
+*/
+ }
+ catch(const std::exception& e)
+ { // Since we have set an overflow policy of ignore_error,
+ // an overflow exception should never be thrown.
+ std::cout << "\nMessage from thrown exception was:\n " << e.what() << std::endl;
+/*`
+For example, without a ignore domain error policy,
+if we asked for ``pdf(g, -1)`` for example,
+we would get an unhelpful abort, but with a catch:
+[pre
+Message from thrown exception was:
+ Error in function boost::math::pdf(const exponential_distribution<double>&, double):
+ Number of failures argument is -1, but must be >= 0 !
+] [/pre]
+*/
+//] [/ geometric_eg1_2]
+ }
+ return 0;
+} // int main()
+
+
+/*
+Output is:
+
+ Geometric distribution example
+
+ success fraction of a six-sided dice is 0.1667
+ 0.1667
+ 0.1667
+ 0.1389
+ pdf(g6, 0) + pdf(g6, 1) = 0.3056
+ cdf(g6, 1) = 0.3056
+ cdf(g6, 12) = 0.9065
+ quantile(g6, 0.99) = 24.26
+ 0.1389
+ 0.3056
+ quantile(complement(g6, 1 - p)) 24.26
+ 0.5000346561579232
+ 0.5
+ quantile(g, 0.95) = 147.28
+ To be 95% confident of finding we customer with a fault, need to survey 148 customers.
+ To be 99% confident of finding we customer with a fault, need to survey 227 customers.
+ To be 80% confident of finding we customer with a fault, need to survey 79 customers.
+ Probability of score on 1st try = 0.75
+ Probability of score on 5th try = 0.0029
+ Probability of score on 5th try = 5.9e-006
+ Probability of score on 5th try = 0.031
+ Probability is failure is 0.01
+ geometric::find_lower_bound_on_p(100, 0.025) = 0.00025
+ geometric::find_upper_bound_on_p(100, 0.025) = 0.037
+ geometric::find_lower_bound_on_p(100, 0.05) = 0.00051
+ geometric::find_upper_bound_on_p(100, 0.05) = 0.03
+ geometric::find_lower_bound_on_p(100, 0.005) = 5e-005
+ geometric::find_upper_bound_on_p(100, 0.005) = 0.052
+
+*/
+
+
+
+
+
+
+
+
+
+
diff --git a/src/boost/libs/math/example/handle_test_result.hpp b/src/boost/libs/math/example/handle_test_result.hpp
new file mode 100644
index 000000000..cb1432a58
--- /dev/null
+++ b/src/boost/libs/math/example/handle_test_result.hpp
@@ -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
+
diff --git a/src/boost/libs/math/example/hyperexponential_more_snips.cpp b/src/boost/libs/math/example/hyperexponential_more_snips.cpp
new file mode 100644
index 000000000..ba9d5010e
--- /dev/null
+++ b/src/boost/libs/math/example/hyperexponential_more_snips.cpp
@@ -0,0 +1,155 @@
+// Copyright 2014 Marco Guazzone (marco.guazzone@gmail.com).
+
+// 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)
+
+// Caution: this file contains Quickbook markup as well as code
+// and comments, don't change any of the special comment markups!
+
+
+//[hyperexponential_more_snip1
+#include <boost/math/distributions.hpp>
+#include <iostream>
+#include <string>
+
+struct ds_info
+{
+ std::string name;
+ double iat_sample_mean;
+ double iat_sample_sd;
+ boost::math::hyperexponential iat_he;
+ double multi_lt_sample_mean;
+ double multi_lt_sample_sd;
+ boost::math::hyperexponential multi_lt_he;
+ double single_lt_sample_mean;
+ double single_lt_sample_sd;
+ boost::math::hyperexponential single_lt_he;
+};
+
+// DS1 dataset
+ds_info make_ds1()
+{
+ ds_info ds;
+
+ ds.name = "DS1";
+
+ // VM interarrival time distribution
+ const double iat_fit_probs[] = { 0.34561,0.08648,0.56791 };
+ const double iat_fit_rates[] = { 0.0008,0.00005,0.02894 };
+ ds.iat_sample_mean = 2202.1;
+ ds.iat_sample_sd = 2.2e+4;
+ ds.iat_he = boost::math::hyperexponential(iat_fit_probs, iat_fit_rates);
+
+ // Multi-core VM lifetime distribution
+ const double multi_lt_fit_probs[] = { 0.24667,0.37948,0.37385 };
+ const double multi_lt_fit_rates[] = { 0.00004,0.000002,0.00059 };
+ ds.multi_lt_sample_mean = 257173;
+ ds.multi_lt_sample_sd = 4.6e+5;
+ ds.multi_lt_he = boost::math::hyperexponential(multi_lt_fit_probs, multi_lt_fit_rates);
+
+ // Single-core VM lifetime distribution
+ const double single_lt_fit_probs[] = { 0.09325,0.22251,0.68424 };
+ const double single_lt_fit_rates[] = { 0.000003,0.00109,0.00109 };
+ ds.single_lt_sample_mean = 28754.4;
+ ds.single_lt_sample_sd = 1.6e+5;
+ ds.single_lt_he = boost::math::hyperexponential(single_lt_fit_probs, single_lt_fit_rates);
+
+ return ds;
+}
+
+// DS2 dataset
+ds_info make_ds2()
+{
+ ds_info ds;
+
+ ds.name = "DS2";
+
+ // VM interarrival time distribution
+ const double iat_fit_probs[] = { 0.38881,0.18227,0.42892 };
+ const double iat_fit_rates[] = { 0.000006,0.05228,0.00081 };
+ ds.iat_sample_mean = 41285.7;
+ ds.iat_sample_sd = 1.1e+05;
+ ds.iat_he = boost::math::hyperexponential(iat_fit_probs, iat_fit_rates);
+
+ // Multi-core VM lifetime distribution
+ const double multi_lt_fit_probs[] = { 0.42093,0.43960,0.13947 };
+ const double multi_lt_fit_rates[] = { 0.00186,0.00008,0.0000008 };
+ ds.multi_lt_sample_mean = 144669.0;
+ ds.multi_lt_sample_sd = 7.9e+05;
+ ds.multi_lt_he = boost::math::hyperexponential(multi_lt_fit_probs, multi_lt_fit_rates);
+
+ // Single-core VM lifetime distribution
+ const double single_lt_fit_probs[] = { 0.44885,0.30675,0.2444 };
+ const double single_lt_fit_rates[] = { 0.00143,0.00005,0.0000004 };
+ ds.single_lt_sample_mean = 599815.0;
+ ds.single_lt_sample_sd = 1.7e+06;
+ ds.single_lt_he = boost::math::hyperexponential(single_lt_fit_probs, single_lt_fit_rates);
+
+ return ds;
+}
+
+// DS3 dataset
+ds_info make_ds3()
+{
+ ds_info ds;
+
+ ds.name = "DS3";
+
+ // VM interarrival time distribution
+ const double iat_fit_probs[] = { 0.39442,0.24644,0.35914 };
+ const double iat_fit_rates[] = { 0.00030,0.00003,0.00257 };
+ ds.iat_sample_mean = 11238.8;
+ ds.iat_sample_sd = 3.0e+04;
+ ds.iat_he = boost::math::hyperexponential(iat_fit_probs, iat_fit_rates);
+
+ // Multi-core VM lifetime distribution
+ const double multi_lt_fit_probs[] = { 0.37621,0.14838,0.47541 };
+ const double multi_lt_fit_rates[] = { 0.00498,0.000005,0.00022 };
+ ds.multi_lt_sample_mean = 30739.2;
+ ds.multi_lt_sample_sd = 1.6e+05;
+ ds.multi_lt_he = boost::math::hyperexponential(multi_lt_fit_probs, multi_lt_fit_rates);
+
+ // Single-core VM lifetime distribution
+ const double single_lt_fit_probs[] = { 0.34131,0.12544,0.53325 };
+ const double single_lt_fit_rates[] = { 0.000297,0.000003,0.00410 };
+ ds.single_lt_sample_mean = 44447.8;
+ ds.single_lt_sample_sd = 2.2e+05;
+ ds.single_lt_he = boost::math::hyperexponential(single_lt_fit_probs, single_lt_fit_rates);
+
+ return ds;
+}
+
+void print_fitted(ds_info const& ds)
+{
+ const double secs_in_a_hour = 3600;
+ const double secs_in_a_month = 30 * 24 * secs_in_a_hour;
+
+ std::cout << "### " << ds.name << std::endl;
+ std::cout << "* Fitted Request Interarrival Time" << std::endl;
+ std::cout << " - Mean (SD): " << boost::math::mean(ds.iat_he) << " (" << boost::math::standard_deviation(ds.iat_he) << ") seconds." << std::endl;
+ std::cout << " - 99th Percentile: " << boost::math::quantile(ds.iat_he, 0.99) << " seconds." << std::endl;
+ std::cout << " - Probability that a VM will arrive within 30 minutes: " << boost::math::cdf(ds.iat_he, secs_in_a_hour / 2.0) << std::endl;
+ std::cout << " - Probability that a VM will arrive after 1 hour: " << boost::math::cdf(boost::math::complement(ds.iat_he, secs_in_a_hour)) << std::endl;
+ std::cout << "* Fitted Multi-core VM Lifetime" << std::endl;
+ std::cout << " - Mean (SD): " << boost::math::mean(ds.multi_lt_he) << " (" << boost::math::standard_deviation(ds.multi_lt_he) << ") seconds." << std::endl;
+ std::cout << " - 99th Percentile: " << boost::math::quantile(ds.multi_lt_he, 0.99) << " seconds." << std::endl;
+ std::cout << " - Probability that a VM will last for less than 1 month: " << boost::math::cdf(ds.multi_lt_he, secs_in_a_month) << std::endl;
+ std::cout << " - Probability that a VM will last for more than 3 months: " << boost::math::cdf(boost::math::complement(ds.multi_lt_he, 3.0*secs_in_a_month)) << std::endl;
+ std::cout << "* Fitted Single-core VM Lifetime" << std::endl;
+ std::cout << " - Mean (SD): " << boost::math::mean(ds.single_lt_he) << " (" << boost::math::standard_deviation(ds.single_lt_he) << ") seconds." << std::endl;
+ std::cout << " - 99th Percentile: " << boost::math::quantile(ds.single_lt_he, 0.99) << " seconds." << std::endl;
+ std::cout << " - Probability that a VM will last for less than 1 month: " << boost::math::cdf(ds.single_lt_he, secs_in_a_month) << std::endl;
+ std::cout << " - Probability that a VM will last for more than 3 months: " << boost::math::cdf(boost::math::complement(ds.single_lt_he, 3.0*secs_in_a_month)) << std::endl;
+}
+
+int main()
+{
+ print_fitted(make_ds1());
+
+ print_fitted(make_ds2());
+
+ print_fitted(make_ds3());
+}
+//]
diff --git a/src/boost/libs/math/example/hyperexponential_snips.cpp b/src/boost/libs/math/example/hyperexponential_snips.cpp
new file mode 100644
index 000000000..785e500d2
--- /dev/null
+++ b/src/boost/libs/math/example/hyperexponential_snips.cpp
@@ -0,0 +1,103 @@
+// Copyright John Maddock 2014.
+
+// 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)
+
+// Caution: this file contains Quickbook markup as well as code
+// and comments, don't change any of the special comment markups!
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4996) // disable -D_SCL_SECURE_NO_WARNINGS C++ 'Checked Iterators'
+#endif
+
+#include <boost/math/distributions/hyperexponential.hpp>
+#include <iostream>
+
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+#include <array>
+#endif
+
+int main()
+{
+ {
+//[hyperexponential_snip1
+//=#include <boost/math/distributions/hyperexponential.hpp>
+//=#include <iostream>
+//=int main()
+//={
+ const double rates[] = { 1.0 / 10.0, 1.0 / 12.0 };
+
+ boost::math::hyperexponential he(rates);
+
+ std::cout << "Average lifetime: "
+ << boost::math::mean(he)
+ << " years" << std::endl;
+ std::cout << "Probability that the appliance will work for more than 15 years: "
+ << boost::math::cdf(boost::math::complement(he, 15.0))
+ << std::endl;
+//=}
+//]
+ }
+ using namespace boost::math;
+#ifndef BOOST_NO_CXX11_HDR_ARRAY
+ {
+ //[hyperexponential_snip2
+ std::array<double, 2> phase_prob = { 0.5, 0.5 };
+ std::array<double, 2> rates = { 1.0 / 10, 1.0 / 12 };
+
+ hyperexponential he(phase_prob.begin(), phase_prob.end(), rates.begin(), rates.end());
+ //]
+ }
+
+ {
+ //[hyperexponential_snip3
+ // We could be using any standard library container here... vector, deque, array, list etc:
+ std::array<double, 2> phase_prob = { 0.5, 0.5 };
+ std::array<double, 2> rates = { 1.0 / 10, 1.0 / 12 };
+
+ hyperexponential he1(phase_prob, rates); // Construct from standard library container.
+
+ double phase_probs2[] = { 0.5, 0.5 };
+ double rates2[] = { 1.0 / 10, 1.0 / 12 };
+
+ hyperexponential he2(phase_probs2, rates2); // Construct from native C++ array.
+ //]
+ }
+ {
+ //[hyperexponential_snip4
+ // We could be using any standard library container here... vector, deque, array, list etc:
+ std::array<double, 2> rates = { 1.0 / 10, 1.0 / 12 };
+
+ hyperexponential he(rates.begin(), rates.end());
+
+ BOOST_ASSERT(he.probabilities()[0] == 0.5); // Phase probabilities will be equal and normalised to unity.
+ //]
+ }
+ {
+ //[hyperexponential_snip5
+ std::array<double, 2> rates = { 1.0 / 10, 1.0 / 12 };
+
+ hyperexponential he(rates);
+
+ BOOST_ASSERT(he.probabilities()[0] == 0.5); // Phase probabilities will be equal and normalised to unity.
+ //]
+ }
+#endif
+#if !defined(BOOST_NO_CXX11_HDR_INITIALIZER_LIST) && !(defined(BOOST_GCC_VERSION) && (BOOST_GCC_VERSION < 40500))
+ {
+ //[hyperexponential_snip6
+ hyperexponential he = { { 0.5, 0.5 }, { 1.0 / 10, 1.0 / 12 } };
+ //]
+ }
+ {
+ //[hyperexponential_snip7
+ hyperexponential he = { 1.0 / 10, 1.0 / 12 };
+
+ BOOST_ASSERT(he.probabilities()[0] == 0.5);
+ //]
+ }
+#endif
+ return 0;
+}
diff --git a/src/boost/libs/math/example/inspect_fp.cpp b/src/boost/libs/math/example/inspect_fp.cpp
new file mode 100644
index 000000000..0838b8ddd
--- /dev/null
+++ b/src/boost/libs/math/example/inspect_fp.cpp
@@ -0,0 +1,224 @@
+// inspect.cpp
+
+// Copyright (c) 2006 Johan Rade
+
+// 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)
+
+//-------------------------------------
+
+#include <cstring>
+
+#include <iomanip>
+#include <iostream>
+#include <limits>
+#include <boost/detail/endian.hpp>
+
+//------------------------------------------------------------------------------
+
+bool is_big_endian()
+{
+ float x = 1.0f;
+ unsigned char first_byte;
+ memcpy(&first_byte, &x, 1);
+ return first_byte != 0;
+}
+
+//------------------------------------------------------------------------------
+
+void print_processor();
+void print_endianness();
+template<class T> void print_table();
+template<class T> void print_row(const char* name, T val, bool ok = true);
+
+//------------------------------------------------------------------------------
+
+int main()
+{
+ std::cout << '\n';
+
+ print_processor();
+
+ print_endianness();
+
+ std::cout << "---------- float --------------------\n\n";
+ print_table<float>();
+
+ std::cout << "---------- double -------------------\n\n";
+ print_table<double>();
+
+ std::cout << "---------- long double --------------\n\n";
+ print_table<long double>();
+
+ return 0;
+}
+
+//------------------------------------------------------------------------------
+
+void print_processor()
+{
+#if defined(__i386) || defined(__i386__) || defined(_M_IX86) \
+ || defined(__amd64) || defined(__amd64__) || defined(_M_AMD64) \
+ || defined(__x86_64) || defined(__x86_64__) || defined(_M_X64)
+
+ std::cout << "Processor: x86 or x64\n\n";
+
+#elif defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
+
+ std::cout << "Processor: ia64\n\n";
+
+#elif defined(__powerpc) || defined(__powerpc__) || defined(__POWERPC__) \
+ || defined(__ppc) || defined(__ppc__) || defined(__PPC__)
+
+ std::cout << "Processor: PowerPC\n\n";
+
+#elif defined(__m68k) || defined(__m68k__) \
+ || defined(__mc68000) || defined(__mc68000__) \
+
+ std::cout << "Processor: Motorola 68K\n\n";
+
+#else
+
+ std::cout << "Processor: Unknown\n\n";
+
+#endif
+}
+
+void print_endianness()
+{
+ if(is_big_endian())
+ std::cout << "This platform is big-endian.\n";
+ else
+ std::cout << "This platform is little-endian.\n";
+
+#ifdef BOOST_BIG_ENDIAN
+ std::cout << "BOOST_BIG_ENDIAN is defined.\n\n";
+#endif
+#if defined BOOST_LITTLE_ENDIAN
+ std::cout << "BOOST_LITTTLE_ENDIAN is defined.\n\n";
+#endif
+}
+
+//..............................................................................
+
+template<class T> void print_table()
+{
+ print_row("0", (T)0);
+ print_row("sn.min", std::numeric_limits<T>::denorm_min(),
+ std::numeric_limits<T>::has_denorm);
+ print_row("-sn.min", -std::numeric_limits<T>::denorm_min(),
+ std::numeric_limits<T>::has_denorm);
+ print_row("n.min/256", (std::numeric_limits<T>::min)()/256);
+ print_row("n.min/2", (std::numeric_limits<T>::min)()/2);
+ print_row("-n.min/2", -(std::numeric_limits<T>::min)()/2);
+ print_row("n.min", (std::numeric_limits<T>::min)());
+ print_row("1", (T)1);
+ print_row("3/4", (T)3/(T)4);
+ print_row("4/3", (T)4/(T)3);
+ print_row("max", (std::numeric_limits<T>::max)());
+ print_row("inf", std::numeric_limits<T>::infinity(),
+ std::numeric_limits<T>::has_infinity);
+ print_row("q.nan", std::numeric_limits<T>::quiet_NaN(),
+ std::numeric_limits<T>::has_quiet_NaN);
+ print_row("s.nan", std::numeric_limits<T>::signaling_NaN(),
+ std::numeric_limits<T>::has_signaling_NaN);
+
+ std::cout << "\n\n";
+}
+
+template<class T>
+void print_row(const char* name, T val, bool ok)
+{
+ std::cout << std::left << std::setw(10) << name << std::right;
+
+ std::cout << std::hex << std::setfill('0');
+
+ if(ok) {
+ if(is_big_endian()) {
+ for(size_t i = 0; i < sizeof(T); ++i) {
+ unsigned char c = *(reinterpret_cast<unsigned char*>(&val) + i);
+ std::cout << std::setw(2)
+ << static_cast<unsigned int>(c) << ' ';
+ }
+ }
+ else {
+ for(size_t i = sizeof(T) - 1; i < sizeof(T); --i) {
+ unsigned char c = *(reinterpret_cast<unsigned char*>(&val) + i);
+ std::cout << std::setw(2)
+ << static_cast<unsigned int>(c) << ' ';
+ }
+ }
+ }
+ else {
+ for(size_t i = 0; i < sizeof(T); ++i)
+ std::cout << "-- ";
+ }
+
+ std::cout << '\n';
+ std::cout << std::dec << std::setfill(' ');
+}
+
+/*
+
+Sample output on an AMD Quadcore running MSVC 10
+
+ Processor: x86 or x64
+
+ This platform is little-endian.
+ BOOST_LITTTLE_ENDIAN is defined.
+
+ ---------- float --------------------
+
+ 0 00 00 00 00
+ sn.min 00 00 00 01
+ -sn.min 80 00 00 01
+ n.min/256 00 00 80 00
+ n.min/2 00 40 00 00
+ -n.min/2 80 40 00 00
+ n.min 00 80 00 00
+ 1 3f 80 00 00
+ 3/4 3f 40 00 00
+ 4/3 3f aa aa ab
+ max 7f 7f ff ff
+ inf 7f 80 00 00
+ q.nan 7f c0 00 00
+ s.nan 7f c0 00 01
+
+
+ ---------- double -------------------
+
+ 0 00 00 00 00 00 00 00 00
+ sn.min 00 00 00 00 00 00 00 01
+ -sn.min 80 00 00 00 00 00 00 01
+ n.min/256 00 00 10 00 00 00 00 00
+ n.min/2 00 08 00 00 00 00 00 00
+ -n.min/2 80 08 00 00 00 00 00 00
+ n.min 00 10 00 00 00 00 00 00
+ 1 3f f0 00 00 00 00 00 00
+ 3/4 3f e8 00 00 00 00 00 00
+ 4/3 3f f5 55 55 55 55 55 55
+ max 7f ef ff ff ff ff ff ff
+ inf 7f f0 00 00 00 00 00 00
+ q.nan 7f f8 00 00 00 00 00 00
+ s.nan 7f f8 00 00 00 00 00 01
+
+
+ ---------- long double --------------
+
+ 0 00 00 00 00 00 00 00 00
+ sn.min 00 00 00 00 00 00 00 01
+ -sn.min 80 00 00 00 00 00 00 01
+ n.min/256 00 00 10 00 00 00 00 00
+ n.min/2 00 08 00 00 00 00 00 00
+ -n.min/2 80 08 00 00 00 00 00 00
+ n.min 00 10 00 00 00 00 00 00
+ 1 3f f0 00 00 00 00 00 00
+ 3/4 3f e8 00 00 00 00 00 00
+ 4/3 3f f5 55 55 55 55 55 55
+ max 7f ef ff ff ff ff ff ff
+ inf 7f f0 00 00 00 00 00 00
+ q.nan 7f f8 00 00 00 00 00 00
+ s.nan 7f f8 00 00 00 00 00 01
+
+ */
diff --git a/src/boost/libs/math/example/inverse_chi_squared_bayes_eg.cpp b/src/boost/libs/math/example/inverse_chi_squared_bayes_eg.cpp
new file mode 100644
index 000000000..364094325
--- /dev/null
+++ b/src/boost/libs/math/example/inverse_chi_squared_bayes_eg.cpp
@@ -0,0 +1,338 @@
+// inverse_chi_squared_bayes_eg.cpp
+
+// Copyright Thomas Mang 2011.
+// Copyright Paul A. Bristow 2011.
+
+// 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)
+
+// This file is written to be included from a Quickbook .qbk document.
+// It can still be compiled by the C++ compiler, and run.
+// Any output can also be added here as comment or included or pasted in elsewhere.
+// Caution: this file contains Quickbook markup as well as code
+// and comments: don't change any of the special comment markups!
+
+#include <iostream>
+// using std::cout; using std::endl;
+
+//#define define possible error-handling macros here?
+
+#include "boost/math/distributions.hpp"
+// using ::boost::math::inverse_chi_squared;
+
+int main()
+{
+ using std::cout; using std::endl;
+
+ using ::boost::math::inverse_chi_squared;
+ using ::boost::math::inverse_gamma;
+ using ::boost::math::quantile;
+ using ::boost::math::cdf;
+
+ cout << "Inverse_chi_squared_distribution Bayes example: " << endl <<endl;
+
+ cout.precision(3);
+// Examples of using the inverse_chi_squared distribution.
+
+//[inverse_chi_squared_bayes_eg_1
+/*`
+The scaled-inversed-chi-squared distribution is the conjugate prior distribution
+for the variance ([sigma][super 2]) parameter of a normal distribution
+with known expectation ([mu]).
+As such it has widespread application in Bayesian statistics:
+
+In [@http://en.wikipedia.org/wiki/Bayesian_inference Bayesian inference],
+the strength of belief into certain parameter values is
+itself described through a distribution. Parameters
+hence become themselves modelled and interpreted as random variables.
+
+In this worked example, we perform such a Bayesian analysis by using
+the scaled-inverse-chi-squared distribution as prior and posterior distribution
+for the variance parameter of a normal distribution.
+
+For more general information on Bayesian type of analyses,
+see:
+
+* Andrew Gelman, John B. Carlin, Hal E. Stern, Donald B. Rubin, Bayesian Data Analysis,
+2003, ISBN 978-1439840955.
+
+* Jim Albert, Bayesian Computation with R, Springer, 2009, ISBN 978-0387922973.
+
+(As the scaled-inversed-chi-squared is another parameterization of the inverse-gamma distribution,
+this example could also have used the inverse-gamma distribution).
+
+Consider precision machines which produce balls for a high-quality ball bearing.
+Ideally each ball should have a diameter of precisely 3000 [mu]m (3 mm).
+Assume that machines generally produce balls of that size on average (mean),
+but individual balls can vary slightly in either direction
+following (approximately) a normal distribution. Depending on various production conditions
+(e.g. raw material used for balls, workplace temperature and humidity, maintenance frequency and quality)
+some machines produce balls tighter distributed around the target of 3000 [mu]m,
+while others produce balls with a wider distribution.
+Therefore the variance parameter of the normal distribution of the ball sizes varies
+from machine to machine. An extensive survey by the precision machinery manufacturer, however,
+has shown that most machines operate with a variance between 15 and 50,
+and near 25 [mu]m[super 2] on average.
+
+Using this information, we want to model the variance of the machines.
+The variance is strictly positive, and therefore we look for a statistical distribution
+with support in the positive domain of the real numbers.
+Given the expectation of the normal distribution of the balls is known (3000 [mu]m),
+for reasons of conjugacy, it is customary practice in Bayesian statistics
+to model the variance to be scaled-inverse-chi-squared distributed.
+
+In a first step, we will try to use the survey information to model
+the general knowledge about the variance parameter of machines measured by the manufacturer.
+This will provide us with a generic prior distribution that is applicable
+if nothing more specific is known about a particular machine.
+
+In a second step, we will then combine the prior-distribution information in a Bayesian analysis
+with data on a specific single machine to derive a posterior distribution for that machine.
+
+[h5 Step one: Using the survey information.]
+
+Using the survey results, we try to find the parameter set
+of a scaled-inverse-chi-squared distribution
+so that the properties of this distribution match the results.
+Using the mathematical properties of the scaled-inverse-chi-squared distribution
+as guideline, we see that that both the mean and mode of the scaled-inverse-chi-squared distribution
+are approximately given by the scale parameter (s) of the distribution. As the survey machines operated at a
+variance of 25 [mu]m[super 2] on average, we hence set the scale parameter (s[sub prior]) of our prior distribution
+equal to this value. Using some trial-and-error and calls to the global quantile function, we also find that a
+value of 20 for the degrees-of-freedom ([nu][sub prior]) parameter is adequate so that
+most of the prior distribution mass is located between 15 and 50 (see figure below).
+
+We first construct our prior distribution using these values, and then list out a few quantiles:
+
+*/
+ double priorDF = 20.0;
+ double priorScale = 25.0;
+
+ inverse_chi_squared prior(priorDF, priorScale);
+ // Using an inverse_gamma distribution instead, we could equivalently write
+ // inverse_gamma prior(priorDF / 2.0, priorScale * priorDF / 2.0);
+
+ cout << "Prior distribution:" << endl << endl;
+ cout << " 2.5% quantile: " << quantile(prior, 0.025) << endl;
+ cout << " 50% quantile: " << quantile(prior, 0.5) << endl;
+ cout << " 97.5% quantile: " << quantile(prior, 0.975) << endl << endl;
+
+ //] [/inverse_chi_squared_bayes_eg_1]
+
+//[inverse_chi_squared_bayes_eg_output_1
+/*`This produces this output:
+
+ Prior distribution:
+
+ 2.5% quantile: 14.6
+ 50% quantile: 25.9
+ 97.5% quantile: 52.1
+
+*/
+//] [/inverse_chi_squared_bayes_eg_output_1]
+
+//[inverse_chi_squared_bayes_eg_2
+/*`
+Based on this distribution, we can now calculate the probability of having a machine
+working with an unusual work precision (variance) at <= 15 or > 50.
+For this task, we use calls to the `boost::math::` functions `cdf` and `complement`,
+respectively, and find a probability of about 0.031 (3.1%) for each case.
+*/
+
+ cout << " probability variance <= 15: " << boost::math::cdf(prior, 15.0) << endl;
+ cout << " probability variance <= 25: " << boost::math::cdf(prior, 25.0) << endl;
+ cout << " probability variance > 50: "
+ << boost::math::cdf(boost::math::complement(prior, 50.0))
+ << endl << endl;
+ //] [/inverse_chi_squared_bayes_eg_2]
+
+//[inverse_chi_squared_bayes_eg_output_2
+/*`This produces this output:
+
+ probability variance <= 15: 0.031
+ probability variance <= 25: 0.458
+ probability variance > 50: 0.0318
+
+*/
+//] [/inverse_chi_squared_bayes_eg_output_2]
+
+//[inverse_chi_squared_bayes_eg_3
+/*`Therefore, only 3.1% of all precision machines produce balls with a variance of 15 or less
+(particularly precise machines),
+but also only 3.2% of all machines produce balls
+with a variance of as high as 50 or more (particularly imprecise machines). Moreover, slightly more than
+one-half (1 - 0.458 = 54.2%) of the machines work at a variance greater than 25.
+
+Notice here the distinction between a
+[@http://en.wikipedia.org/wiki/Bayesian_inference Bayesian] analysis and a
+[@http://en.wikipedia.org/wiki/Frequentist_inference frequentist] analysis:
+because we model the variance as random variable itself,
+we can calculate and straightforwardly interpret probabilities for given parameter values directly,
+while such an approach is not possible (and interpretationally a strict ['must-not]) in the frequentist
+world.
+
+[h5 Step 2: Investigate a single machine]
+
+In the second step, we investigate a single machine,
+which is suspected to suffer from a major fault
+as the produced balls show fairly high size variability.
+Based on the prior distribution of generic machinery performance (derived above)
+and data on balls produced by the suspect machine, we calculate the posterior distribution for that
+machine and use its properties for guidance regarding continued machine operation or suspension.
+
+It can be shown that if the prior distribution
+was chosen to be scaled-inverse-chi-square distributed,
+then the posterior distribution is also scaled-inverse-chi-squared-distributed
+(prior and posterior distributions are hence conjugate).
+For more details regarding conjugacy and formula to derive the parameters set
+for the posterior distribution see
+[@http://en.wikipedia.org/wiki/Conjugate_prior Conjugate prior].
+
+
+Given the prior distribution parameters and sample data (of size n), the posterior distribution parameters
+are given by the two expressions:
+
+__spaces [nu][sub posterior] = [nu][sub prior] + n
+
+which gives the posteriorDF below, and
+
+__spaces s[sub posterior] = ([nu][sub prior]s[sub prior] + [Sigma][super n][sub i=1](x[sub i] - [mu])[super 2]) / ([nu][sub prior] + n)
+
+which after some rearrangement gives the formula for the posteriorScale below.
+
+Machine-specific data consist of 100 balls which were accurately measured
+and show the expected mean of 3000 [mu]m and a sample variance of 55 (calculated for a sample mean defined to be 3000 exactly).
+From these data, the prior parameterization, and noting that the term
+[Sigma][super n][sub i=1](x[sub i] - [mu])[super 2] equals the sample variance multiplied by n - 1,
+it follows that the posterior distribution of the variance parameter
+is scaled-inverse-chi-squared distribution with degrees-of-freedom ([nu][sub posterior]) = 120 and
+scale (s[sub posterior]) = 49.54.
+*/
+
+ int ballsSampleSize = 100;
+ cout <<"balls sample size: " << ballsSampleSize << endl;
+ double ballsSampleVariance = 55.0;
+ cout <<"balls sample variance: " << ballsSampleVariance << endl;
+
+ double posteriorDF = priorDF + ballsSampleSize;
+ cout << "prior degrees-of-freedom: " << priorDF << endl;
+ cout << "posterior degrees-of-freedom: " << posteriorDF << endl;
+
+ double posteriorScale =
+ (priorDF * priorScale + (ballsSampleVariance * (ballsSampleSize - 1))) / posteriorDF;
+ cout << "prior scale: " << priorScale << endl;
+ cout << "posterior scale: " << posteriorScale << endl;
+
+/*`An interesting feature here is that one needs only to know a summary statistics of the sample
+to parameterize the posterior distribution: the 100 individual ball measurements are irrelevant,
+just knowledge of the sample variance and number of measurements is sufficient.
+*/
+
+//] [/inverse_chi_squared_bayes_eg_3]
+
+//[inverse_chi_squared_bayes_eg_output_3
+/*`That produces this output:
+
+
+ balls sample size: 100
+ balls sample variance: 55
+ prior degrees-of-freedom: 20
+ posterior degrees-of-freedom: 120
+ prior scale: 25
+ posterior scale: 49.5
+
+ */
+//] [/inverse_chi_squared_bayes_eg_output_3]
+
+//[inverse_chi_squared_bayes_eg_4
+/*`To compare the generic machinery performance with our suspect machine,
+we calculate again the same quantiles and probabilities as above,
+and find a distribution clearly shifted to greater values (see figure).
+
+[graph prior_posterior_plot]
+
+*/
+
+ inverse_chi_squared posterior(posteriorDF, posteriorScale);
+
+ cout << "Posterior distribution:" << endl << endl;
+ cout << " 2.5% quantile: " << boost::math::quantile(posterior, 0.025) << endl;
+ cout << " 50% quantile: " << boost::math::quantile(posterior, 0.5) << endl;
+ cout << " 97.5% quantile: " << boost::math::quantile(posterior, 0.975) << endl << endl;
+
+ cout << " probability variance <= 15: " << boost::math::cdf(posterior, 15.0) << endl;
+ cout << " probability variance <= 25: " << boost::math::cdf(posterior, 25.0) << endl;
+ cout << " probability variance > 50: "
+ << boost::math::cdf(boost::math::complement(posterior, 50.0)) << endl;
+
+//] [/inverse_chi_squared_bayes_eg_4]
+
+//[inverse_chi_squared_bayes_eg_output_4
+/*`This produces this output:
+
+ Posterior distribution:
+
+ 2.5% quantile: 39.1
+ 50% quantile: 49.8
+ 97.5% quantile: 64.9
+
+ probability variance <= 15: 2.97e-031
+ probability variance <= 25: 8.85e-010
+ probability variance > 50: 0.489
+
+*/
+//] [/inverse_chi_squared_bayes_eg_output_4]
+
+//[inverse_chi_squared_bayes_eg_5
+/*`Indeed, the probability that the machine works at a low variance (<= 15) is almost zero,
+and even the probability of working at average or better performance is negligibly small
+(less than one-millionth of a permille).
+On the other hand, with an almost near-half probability (49%), the machine operates in the
+extreme high variance range of > 50 characteristic for poorly performing machines.
+
+Based on this information the operation of the machine is taken out of use and serviced.
+
+In summary, the Bayesian analysis allowed us to make exact probabilistic statements about a
+parameter of interest, and hence provided us results with straightforward interpretation.
+
+*/
+//] [/inverse_chi_squared_bayes_eg_5]
+
+} // int main()
+
+//[inverse_chi_squared_bayes_eg_output
+/*`
+[pre
+ Inverse_chi_squared_distribution Bayes example:
+
+ Prior distribution:
+
+ 2.5% quantile: 14.6
+ 50% quantile: 25.9
+ 97.5% quantile: 52.1
+
+ probability variance <= 15: 0.031
+ probability variance <= 25: 0.458
+ probability variance > 50: 0.0318
+
+ balls sample size: 100
+ balls sample variance: 55
+ prior degrees-of-freedom: 20
+ posterior degrees-of-freedom: 120
+ prior scale: 25
+ posterior scale: 49.5
+ Posterior distribution:
+
+ 2.5% quantile: 39.1
+ 50% quantile: 49.8
+ 97.5% quantile: 64.9
+
+ probability variance <= 15: 2.97e-031
+ probability variance <= 25: 8.85e-010
+ probability variance > 50: 0.489
+
+] [/pre]
+*/
+//] [/inverse_chi_squared_bayes_eg_output]
diff --git a/src/boost/libs/math/example/inverse_chi_squared_example.cpp b/src/boost/libs/math/example/inverse_chi_squared_example.cpp
new file mode 100644
index 000000000..d21b0dc0c
--- /dev/null
+++ b/src/boost/libs/math/example/inverse_chi_squared_example.cpp
@@ -0,0 +1,171 @@
+// inverse_chi_squared_distribution_example.cpp
+
+// Copyright Paul A. Bristow 2010.
+// Copyright Thomas Mang 2010.
+
+// 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)
+
+// Example 1 of using inverse chi squared distribution
+#include <boost/math/distributions/inverse_chi_squared.hpp>
+using boost::math::inverse_chi_squared_distribution; // inverse_chi_squared_distribution.
+using boost::math::inverse_chi_squared; //typedef for nverse_chi_squared_distribution double.
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::setprecision;
+using std::setw;
+#include <cmath>
+using std::sqrt;
+
+template <class RealType>
+RealType naive_pdf1(RealType df, RealType x)
+{ // Formula from Wikipedia http://en.wikipedia.org/wiki/Inverse-chi-square_distribution
+ // definition 1 using tgamma for simplicity as a check.
+ using namespace std; // For ADL of std functions.
+ using boost::math::tgamma;
+ RealType df2 = df / 2;
+ RealType result = (pow(2., -df2) * pow(x, (-df2 -1)) * exp(-1/(2 * x) ) )
+ / tgamma(df2); //
+ return result;
+}
+
+template <class RealType>
+RealType naive_pdf2(RealType df, RealType x)
+{ // Formula from Wikipedia http://en.wikipedia.org/wiki/Inverse-chi-square_distribution
+ // Definition 2, using tgamma for simplicity as a check.
+ // Not scaled, so assumes scale = 1 and only uses nu aka df.
+ using namespace std; // For ADL of std functions.
+ using boost::math::tgamma;
+ RealType df2 = df / 2;
+ RealType result = (pow(df2, df2) * pow(x, (-df2 -1)) * exp(-df/(2*x) ) )
+ / tgamma(df2);
+ return result;
+}
+
+template <class RealType>
+RealType naive_pdf3(RealType df, RealType scale, RealType x)
+{ // Formula from Wikipedia http://en.wikipedia.org/wiki/Scaled-inverse-chi-square_distribution
+ // *Scaled* version, definition 3, df aka nu, scale aka sigma^2
+ // using tgamma for simplicity as a check.
+ using namespace std; // For ADL of std functions.
+ using boost::math::tgamma;
+ RealType df2 = df / 2;
+ RealType result = (pow(scale * df2, df2) * exp(-df2 * scale/x) )
+ / (tgamma(df2) * pow(x, 1+df2));
+ return result;
+}
+
+template <class RealType>
+RealType naive_pdf4(RealType df, RealType scale, RealType x)
+{ // Formula from http://mathworld.wolfram.com/InverseChi-SquaredDistribution.html
+ // Weisstein, Eric W. "Inverse Chi-Squared Distribution." From MathWorld--A Wolfram Web Resource.
+ // *Scaled* version, definition 3, df aka nu, scale aka sigma^2
+ // using tgamma for simplicity as a check.
+ using namespace std; // For ADL of std functions.
+ using boost::math::tgamma;
+ RealType nu = df; // Wolfram uses greek symbols nu,
+ RealType xi = scale; // and xi.
+ RealType result =
+ pow(2, -nu/2) * exp(- (nu * xi)/(2 * x)) * pow(x, -1-nu/2) * pow((nu * xi), nu/2)
+ / tgamma(nu/2);
+ return result;
+}
+
+int main()
+{
+
+ cout << "Example (basic) using Inverse chi squared distribution. " << endl;
+
+ // TODO find a more practical/useful example. Suggestions welcome?
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ int max_digits10 = 2 + (boost::math::policies::digits<double, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
+ cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined" << endl;
+#else
+ int max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+ cout << "Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = "
+ << max_digits10 << endl;
+ cout.precision(max_digits10); //
+
+ inverse_chi_squared ichsqdef; // All defaults - not very useful!
+ cout << "default df = " << ichsqdef.degrees_of_freedom()
+ << ", default scale = " << ichsqdef.scale() << endl; // default df = 1, default scale = 0.5
+
+ inverse_chi_squared ichsqdef4(4); // Unscaled version, default scale = 1 / degrees_of_freedom
+ cout << "default df = " << ichsqdef4.degrees_of_freedom()
+ << ", default scale = " << ichsqdef4.scale() << endl; // default df = 4, default scale = 2
+
+ inverse_chi_squared ichsqdef32(3, 2); // Scaled version, both degrees_of_freedom and scale specified.
+ cout << "default df = " << ichsqdef32.degrees_of_freedom()
+ << ", default scale = " << ichsqdef32.scale() << endl; // default df = 3, default scale = 2
+
+ {
+ cout.precision(3);
+ double nu = 5.;
+ //double scale1 = 1./ nu; // 1st definition sigma^2 = 1/df;
+ //double scale2 = 1.; // 2nd definition sigma^2 = 1
+ inverse_chi_squared ichsq(nu, 1/nu); // Not scaled
+ inverse_chi_squared sichsq(nu, 1/nu); // scaled
+
+ cout << "nu = " << ichsq.degrees_of_freedom() << ", scale = " << ichsq.scale() << endl;
+
+ int width = 8;
+
+ cout << " x pdf pdf1 pdf2 pdf(scaled) pdf pdf cdf cdf" << endl;
+ for (double x = 0.0; x < 1.; x += 0.1)
+ {
+ cout
+ << setw(width) << x
+ << ' ' << setw(width) << pdf(ichsq, x) // unscaled
+ << ' ' << setw(width) << naive_pdf1(nu, x) // Wiki def 1 unscaled matches graph
+ << ' ' << setw(width) << naive_pdf2(nu, x) // scale = 1 - 2nd definition.
+ << ' ' << setw(width) << naive_pdf3(nu, 1/nu, x) // scaled
+ << ' ' << setw(width) << naive_pdf4(nu, 1/nu, x) // scaled
+ << ' ' << setw(width) << pdf(sichsq, x) // scaled
+ << ' ' << setw(width) << cdf(sichsq, x) // scaled
+ << ' ' << setw(width) << cdf(ichsq, x) // unscaled
+ << endl;
+ }
+ }
+
+ cout.precision(max_digits10);
+
+ inverse_chi_squared ichisq(2., 0.5);
+ cout << "pdf(ichisq, 1.) = " << pdf(ichisq, 1.) << endl;
+ cout << "cdf(ichisq, 1.) = " << cdf(ichisq, 1.) << endl;
+
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+ Example (basic) using Inverse chi squared distribution.
+ Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = 17
+ default df = 1, default scale = 1
+ default df = 4, default scale = 0.25
+ default df = 3, default scale = 2
+ nu = 5, scale = 0.2
+ x pdf pdf1 pdf2 pdf(scaled) pdf pdf cdf cdf
+ 0 0 -1.#J -1.#J -1.#J -1.#J 0 0 0
+ 0.1 2.83 2.83 3.26e-007 2.83 2.83 2.83 0.0752 0.0752
+ 0.2 3.05 3.05 0.00774 3.05 3.05 3.05 0.416 0.416
+ 0.3 1.7 1.7 0.121 1.7 1.7 1.7 0.649 0.649
+ 0.4 0.941 0.941 0.355 0.941 0.941 0.941 0.776 0.776
+ 0.5 0.553 0.553 0.567 0.553 0.553 0.553 0.849 0.849
+ 0.6 0.345 0.345 0.689 0.345 0.345 0.345 0.893 0.893
+ 0.7 0.227 0.227 0.728 0.227 0.227 0.227 0.921 0.921
+ 0.8 0.155 0.155 0.713 0.155 0.155 0.155 0.94 0.94
+ 0.9 0.11 0.11 0.668 0.11 0.11 0.11 0.953 0.953
+ 1 0.0807 0.0807 0.61 0.0807 0.0807 0.0807 0.963 0.963
+ pdf(ichisq, 1.) = 0.30326532985631671
+ cdf(ichisq, 1.) = 0.60653065971263365
+
+
+*/
+
diff --git a/src/boost/libs/math/example/inverse_chi_squared_find_df_example.cpp b/src/boost/libs/math/example/inverse_chi_squared_find_df_example.cpp
new file mode 100644
index 000000000..ea0f932dc
--- /dev/null
+++ b/src/boost/libs/math/example/inverse_chi_squared_find_df_example.cpp
@@ -0,0 +1,186 @@
+// inverse_chi_squared_distribution_find_df_example.cpp
+
+// Copyright Paul A. Bristow 2010.
+// Copyright Thomas Mang 2010.
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//#define BOOST_MATH_INSTRUMENT
+
+// Example 1 of using inverse chi squared distribution
+#include <boost/math/distributions/inverse_chi_squared.hpp>
+using boost::math::inverse_chi_squared_distribution; // inverse_chi_squared_distribution.
+using boost::math::inverse_chi_squared; //typedef for nverse_chi_squared_distribution double.
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::setprecision;
+using std::setw;
+#include <cmath>
+using std::sqrt;
+
+int main()
+{
+ cout << "Example using Inverse chi squared distribution to find df. " << endl;
+ try
+ {
+ cout.precision(std::numeric_limits<double>::max_digits10); //
+ int i = std::numeric_limits<double>::max_digits10;
+ cout << "Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = " << i << endl;
+
+ cout.precision(3);
+ double nu = 10.;
+ double scale1 = 1./ nu; // 1st definition sigma^2 = 1/df;
+ double scale2 = 1.; // 2nd definition sigma^2 = 1
+ inverse_chi_squared sichsq(nu, 1/nu); // Explicitly scaled to default scale = 1/df.
+ inverse_chi_squared ichsq(nu); // Implicitly scaled to default scale = 1/df.
+ // Try degrees of freedom estimator
+
+ //double df = chi_squared::find_degrees_of_freedom(-diff, alpha[i], alpha[i], variance);
+
+ cout << "ichsq.degrees_of_freedom() = " << ichsq.degrees_of_freedom() << endl;
+
+ double diff = 0.5; // difference from variance to detect (delta).
+ double variance = 1.; // true variance
+ double alpha = 0.9;
+ double beta = 0.9;
+
+ cout << "diff = " << diff
+ << ", variance = " << variance << ", ratio = " << diff/variance
+ << ", alpha = " << alpha << ", beta = " << beta << endl;
+ using boost::math::detail::inverse_chi_square_df_estimator;
+ using boost::math::policies::default_policy;
+ inverse_chi_square_df_estimator<> a_df(alpha, beta, variance, diff);
+
+ cout << "df est" << endl;
+ for (double df = 1; df < 3; df += 0.1)
+ {
+ double est_df = a_df(1);
+ cout << df << " " << a_df(df) << endl;
+ }
+
+ //template <class F, class T, class Tol, class Policy>std::pair<T, T>
+ // bracket_and_solve_root(F f, const T& guess, T factor, bool rising, Tol tol, boost::uintmax_t& max_iter, const Policy& pol)
+
+
+ //double df = inverse_chi_squared_distribution<>::find_degrees_of_freedom(diff, alpha, beta, variance, 0);
+
+ double df = inverse_chi_squared::find_degrees_of_freedom(diff, alpha, beta, variance, 100);
+
+ cout << df << endl;
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+ Example using Inverse chi squared distribution to find df.
+ Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = 17
+ 10
+
+ Message from thrown exception was:
+ Error in function boost::math::inverse_chi_squared_distribution<double>::inverse_chi_squared_distribution: Degrees of freedom argument is 1.#INF, but must be > 0 !
+diff = 0.5, variance = 1, ratio = 0.5, alpha = 0.1, beta = 0.1
+ df est
+ 1 1
+ ratio+1 = 1.5, quantile(0.1) = 0.00618, cdf = 6.5e-037, result = -0.1
+ 1.1 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.00903, cdf = 1.2e-025, result = -0.1
+ 1.2 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0125, cdf = 8.25e-019, result = -0.1
+ 1.3 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0166, cdf = 2.17e-014, result = -0.1
+ 1.4 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0212, cdf = 2.2e-011, result = -0.1
+ 1.5 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0265, cdf = 3e-009, result = -0.1
+ 1.6 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0323, cdf = 1.11e-007, result = -0.1
+ 1.7 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0386, cdf = 1.7e-006, result = -0.1
+ 1.8 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0454, cdf = 1.41e-005, result = -0.1
+ 1.9 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0527, cdf = 7.55e-005, result = -0.1
+ 2 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0604, cdf = 0.000291, result = -0.1
+ 2.1 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0685, cdf = 0.00088, result = -0.1
+ 2.2 -0.1
+ ratio+1 = 1.5, quantile(0.1) = 0.0771, cdf = 0.0022, result = -0.0999
+ 2.3 -0.0999
+ ratio+1 = 1.5, quantile(0.1) = 0.0859, cdf = 0.00475, result = -0.0997
+ 2.4 -0.0997
+ ratio+1 = 1.5, quantile(0.1) = 0.0952, cdf = 0.00911, result = -0.0993
+ 2.5 -0.0993
+ ratio+1 = 1.5, quantile(0.1) = 0.105, cdf = 0.0159, result = -0.0984
+ 2.6 -0.0984
+ ratio+1 = 1.5, quantile(0.1) = 0.115, cdf = 0.0257, result = -0.0967
+ 2.7 -0.0967
+ ratio+1 = 1.5, quantile(0.1) = 0.125, cdf = 0.039, result = -0.094
+ 2.8 -0.094
+ ratio+1 = 1.5, quantile(0.1) = 0.135, cdf = 0.056, result = -0.0897
+ 2.9 -0.0897
+ ratio+1 = 1.5, quantile(0.1) = 20.6, cdf = 1, result = 0.9
+
+ ichsq.degrees_of_freedom() = 10
+ diff = 0.5, variance = 1, ratio = 0.5, alpha = 0.9, beta = 0.9
+ df est
+ 1 1
+ ratio+1 = 1.5, quantile(0.9) = 0.729, cdf = 0.269, result = -0.729
+ 1.1 -0.729
+ ratio+1 = 1.5, quantile(0.9) = 0.78, cdf = 0.314, result = -0.693
+ 1.2 -0.693
+ ratio+1 = 1.5, quantile(0.9) = 0.83, cdf = 0.36, result = -0.655
+ 1.3 -0.655
+ ratio+1 = 1.5, quantile(0.9) = 0.879, cdf = 0.405, result = -0.615
+ 1.4 -0.615
+ ratio+1 = 1.5, quantile(0.9) = 0.926, cdf = 0.449, result = -0.575
+ 1.5 -0.575
+ ratio+1 = 1.5, quantile(0.9) = 0.973, cdf = 0.492, result = -0.535
+ 1.6 -0.535
+ ratio+1 = 1.5, quantile(0.9) = 1.02, cdf = 0.534, result = -0.495
+ 1.7 -0.495
+ ratio+1 = 1.5, quantile(0.9) = 1.06, cdf = 0.574, result = -0.455
+ 1.8 -0.455
+ ratio+1 = 1.5, quantile(0.9) = 1.11, cdf = 0.612, result = -0.417
+ 1.9 -0.417
+ ratio+1 = 1.5, quantile(0.9) = 1.15, cdf = 0.648, result = -0.379
+ 2 -0.379
+ ratio+1 = 1.5, quantile(0.9) = 1.19, cdf = 0.681, result = -0.342
+ 2.1 -0.342
+ ratio+1 = 1.5, quantile(0.9) = 1.24, cdf = 0.713, result = -0.307
+ 2.2 -0.307
+ ratio+1 = 1.5, quantile(0.9) = 1.28, cdf = 0.742, result = -0.274
+ 2.3 -0.274
+ ratio+1 = 1.5, quantile(0.9) = 1.32, cdf = 0.769, result = -0.242
+ 2.4 -0.242
+ ratio+1 = 1.5, quantile(0.9) = 1.36, cdf = 0.793, result = -0.212
+ 2.5 -0.212
+ ratio+1 = 1.5, quantile(0.9) = 1.4, cdf = 0.816, result = -0.184
+ 2.6 -0.184
+ ratio+1 = 1.5, quantile(0.9) = 1.44, cdf = 0.836, result = -0.157
+ 2.7 -0.157
+ ratio+1 = 1.5, quantile(0.9) = 1.48, cdf = 0.855, result = -0.133
+ 2.8 -0.133
+ ratio+1 = 1.5, quantile(0.9) = 1.52, cdf = 0.872, result = -0.11
+ 2.9 -0.11
+ ratio+1 = 1.5, quantile(0.9) = 29.6, cdf = 1, result = 0.1
+
+
+ */
+
diff --git a/src/boost/libs/math/example/inverse_gamma_distribution_example.cpp b/src/boost/libs/math/example/inverse_gamma_distribution_example.cpp
new file mode 100644
index 000000000..53e5ccf0f
--- /dev/null
+++ b/src/boost/libs/math/example/inverse_gamma_distribution_example.cpp
@@ -0,0 +1,103 @@
+// inverse_gamma_distribution_example.cpp
+
+// Copyright Paul A. Bristow 2010.
+// Copyright Thomas Mang 2010.
+
+// 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)
+
+// Example 1 of using inverse gamma
+#include <boost/math/distributions/inverse_gamma.hpp>
+using boost::math::inverse_gamma_distribution; // inverse_gamma_distribution.
+using boost::math::inverse_gamma;
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma; // Used for naive pdf as a comparison.
+
+#include <boost/math/distributions/gamma.hpp>
+using boost::math::inverse_gamma_distribution;
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::setprecision;
+#include <cmath>
+using std::sqrt;
+
+int main()
+{
+
+ cout << "Example using Inverse Gamma distribution. " << endl;
+ // TODO - awaiting a real example using Bayesian statistics.
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ int max_digits10 = 2 + (boost::math::policies::digits<double, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
+ cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined" << endl;
+#else
+ int max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+ cout << "Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = "
+ << max_digits10 << endl;
+ cout.precision(max_digits10); //
+
+ double shape = 1.;
+ double scale = 1.;
+ double x = 0.5;
+ // Construction using default RealType double, and default shape and scale..
+ inverse_gamma_distribution<> my_inverse_gamma(shape, scale); // (alpha, beta)
+
+ cout << "my_inverse_gamma.shape() = " << my_inverse_gamma.shape()
+ << ", scale = "<< my_inverse_gamma.scale() << endl;
+ cout << "x = " << x << ", pdf = " << pdf(my_inverse_gamma, x)
+ << ", cdf = " << cdf(my_inverse_gamma, x) << endl;
+
+ // Construct using typedef and default shape and scale parameters.
+ inverse_gamma my_ig;
+
+ inverse_gamma my_ig23(2, 3);
+ cout << "my_inverse_gamma.shape() = " << my_ig23.shape()
+ << ", scale = "<< my_ig23.scale() << endl;
+ cout << "x = " << x << ", pdf = " << pdf(my_ig23, x)
+ << ", cdf = " << cdf(my_ig23, x) << endl;
+
+ // Example of providing an 'out of domain' or 'bad' parameter,
+ // here a shape < 1, for which mean is not defined.
+ // Try block is essential to catch the exception message.
+ // (Uses the default policy which is to throw on all errors).
+ try
+ {
+ inverse_gamma if051(0.5, 1);
+ //inverse_gamma if051(0.5, 1);
+ cout << "mean(if051) = " << mean(if051) << endl;
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+ Example using Inverse Gamma distribution.
+ std::numeric_limits<double>::max_digits10 = 17
+ my_inverse_gamma.shape() = 1, scale = 1
+ x = 0.5, pdf = 0.54134113294645081, cdf = 0.1353352832366127
+ my_inverse_gamma.shape() = 2, scale = 3
+ x = 0.5, pdf = 0.17847015671997774, cdf = 0.017351265236664509
+
+ Message from thrown exception was:
+ Error in function boost::math::mean(const inverse_gamma_distribution<double>&): Shape parameter is 0.5, but for a defined mean it must be > 1
+
+
+*/
+
+
diff --git a/src/boost/libs/math/example/inverse_gamma_example.cpp b/src/boost/libs/math/example/inverse_gamma_example.cpp
new file mode 100644
index 000000000..5ec496659
--- /dev/null
+++ b/src/boost/libs/math/example/inverse_gamma_example.cpp
@@ -0,0 +1,57 @@
+// inverse_gamma_example.cpp
+
+// Copyright Paul A. Bristow 2010.
+
+// 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)
+
+// Example 1 of using inverse gamma functions.
+
+#include <boost/math/special_functions/gamma.hpp>
+
+using boost::math::gamma_p_inv; // Compute x given a
+//using boost::math::gamma_q_inv;
+//using boost::math::gamma_p_inva; // Compute a given x
+//using boost::math::gamma_q_inva;
+
+#include <iostream>
+ using std::cout; using std::endl;
+#include <iomanip>
+ using std::setprecision;
+#include <cmath>
+ using std::sqrt;
+#include <limits>
+
+int main()
+{
+ cout << "Example 1 using Inverse Gamma function. " << endl;
+
+ #ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ int max_digits10 = 2 + (boost::math::policies::digits<double, boost::math::policies::policy<> >() * 30103UL) / 100000UL;
+ cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined" << endl;
+#else
+ int max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+ cout << "Show all potentially significant decimal digits std::numeric_limits<double>::max_digits10 = "
+ << max_digits10 << endl;
+ cout.precision(max_digits10); //
+
+ double x = 1.;
+ double a = 10;
+
+ double r = boost::math::gamma_q_inv(a ,x);
+
+ cout << " x = " << x << ", = gamma_q_inv(a,x)" << r << endl; //
+
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+*/
+
+
diff --git a/src/boost/libs/math/example/inverse_gaussian_example.cpp b/src/boost/libs/math/example/inverse_gaussian_example.cpp
new file mode 100644
index 000000000..4f212aa5e
--- /dev/null
+++ b/src/boost/libs/math/example/inverse_gaussian_example.cpp
@@ -0,0 +1,513 @@
+// wald_example.cpp or inverse_gaussian_example.cpp
+
+// Copyright Paul A. Bristow 2010.
+
+// 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)
+
+// Example of using the Inverse Gaussian (or Inverse Normal) distribution.
+// The Wald Distribution is
+
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[inverse_gaussian_basic1
+/*`
+First we need some includes to access the normal distribution
+(and some std output of course).
+*/
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4224)
+# pragma warning (disable : 4189)
+# pragma warning (disable : 4100)
+# pragma warning (disable : 4224)
+# pragma warning (disable : 4512)
+# pragma warning (disable : 4702)
+# pragma warning (disable : 4127)
+#endif
+
+//#define BOOST_MATH_INSTRUMENT
+
+#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
+#define BOOST_MATH_DOMAIN_ERROR_POLICY ignore_error
+
+#include <boost/math/distributions/inverse_gaussian.hpp> // for inverse_gaussian_distribution
+ using boost::math::inverse_gaussian; // typedef provides default type is double.
+ using boost::math::inverse_gaussian_distribution; // for inverse gaussian distribution.
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+using boost::math::normal; // typedef provides default type is double.
+
+#include <boost/array.hpp>
+using boost::array;
+
+#include <iostream>
+ using std::cout; using std::endl; using std::left; using std::showpoint; using std::noshowpoint;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+#include <sstream>
+ using std::string;
+#include <string>
+ using std::stringstream;
+
+// const double tol = 3 * numeric_limits<double>::epsilon();
+
+int main()
+{
+ cout << "Example: Inverse Gaussian Distribution."<< endl;
+
+ try
+ {
+
+ double tolfeweps = numeric_limits<double>::epsilon();
+ //cout << "Tolerance = " << tol << endl;
+
+ int precision = 17; // traditional tables are only computed to much lower precision.
+ cout.precision(17); // std::numeric_limits<double>::max_digits10; for 64-bit doubles.
+
+ // Traditional tables and values.
+ double step = 0.2; // in z
+ double range = 4; // min and max z = -range to +range.
+ // Construct a (standard) inverse gaussian distribution s
+ inverse_gaussian w11(1, 1);
+ // (default mean = units, and standard deviation = unity)
+ cout << "(Standard) Inverse Gaussian distribution, mean = "<< w11.mean()
+ << ", scale = " << w11.scale() << endl;
+
+/*` First the probability distribution function (pdf).
+ */
+ cout << "Probability distribution function (pdf) values" << endl;
+ cout << " z " " pdf " << endl;
+ cout.precision(5);
+ for (double z = (numeric_limits<double>::min)(); z < range + step; z += step)
+ {
+ cout << left << setprecision(3) << setw(6) << z << " "
+ << setprecision(precision) << setw(12) << pdf(w11, z) << endl;
+ }
+ cout.precision(6); // default
+ /*`And the area under the normal curve from -[infin] up to z,
+ the cumulative distribution function (cdf).
+*/
+
+ // For a (default) inverse gaussian distribution.
+ cout << "Integral (area under the curve) from 0 up to z (cdf) " << endl;
+ cout << " z " " cdf " << endl;
+ for (double z = (numeric_limits<double>::min)(); z < range + step; z += step)
+ {
+ cout << left << setprecision(3) << setw(6) << z << " "
+ << setprecision(precision) << setw(12) << cdf(w11, z) << endl;
+ }
+ /*`giving the following table:
+[pre
+ z pdf
+ 2.23e-308 -1.#IND
+ 0.2 0.90052111680384117
+ 0.4 1.0055127039453111
+ 0.6 0.75123750098955733
+ 0.8 0.54377310461643302
+ 1 0.3989422804014327
+ 1.2 0.29846949816803292
+ 1.4 0.2274579835638664
+ 1.6 0.17614566625628389
+ 1.8 0.13829083543591469
+ 2 0.10984782236693062
+ 2.2 0.088133964251182237
+ 2.4 0.071327382959107177
+ 2.6 0.058162562161661699
+ 2.8 0.047742223328567722
+ 3 0.039418357969819712
+ 3.2 0.032715223861241892
+ 3.4 0.027278388940958308
+ 3.6 0.022840312999395804
+ 3.8 0.019196657941016954
+ 4 0.016189699458236451
+ Integral (area under the curve) from 0 up to z (cdf)
+ z cdf
+ 2.23e-308 0
+ 0.2 0.063753567519976254
+ 0.4 0.2706136704424541
+ 0.6 0.44638391340412931
+ 0.8 0.57472390962590925
+ 1 0.66810200122317065
+ 1.2 0.73724578422952536
+ 1.4 0.78944214237790356
+ 1.6 0.82953458108474554
+ 1.8 0.86079282968276671
+ 2 0.88547542598600626
+ 2.2 0.90517870624273966
+ 2.4 0.92105495653509362
+ 2.6 0.93395164268166786
+ 2.8 0.94450240360053817
+ 3 0.95318792074278835
+ 3.2 0.96037753019309191
+ 3.4 0.96635823989417369
+ 3.6 0.97135533107998406
+ 3.8 0.97554722413538364
+ 4 0.97907636417888622
+]
+
+/*`We can get the inverse, the quantile, percentile, percentage point, or critical value
+for a probability for a few probability from the above table, for z = 0.4, 1.0, 2.0:
+*/
+ cout << quantile(w11, 0.27061367044245421 ) << endl; // 0.4
+ cout << quantile(w11, 0.66810200122317065) << endl; // 1.0
+ cout << quantile(w11, 0.88547542598600615) << endl; // 2.0
+/*`turning the expect values apart from some 'computational noise' in the least significant bit or two.
+
+[pre
+ 0.40000000000000008
+ 0.99999999999999967
+ 1.9999999999999973
+]
+
+*/
+
+ // cout << "pnorm01(-0.406053) " << pnorm01(-0.406053) << ", cdfn01(-0.406053) = " << cdf(n01, -0.406053) << endl;
+ //cout << "pnorm01(0.5) = " << pnorm01(0.5) << endl; // R pnorm(0.5,0,1) = 0.6914625 == 0.69146246127401312
+ // R qnorm(0.6914625,0,1) = 0.5
+
+ // formatC(SuppDists::qinvGauss(0.3649755481729598, 1, 1), digits=17) [1] "0.50000000969034875"
+
+
+
+ // formatC(SuppDists::dinvGauss(0.01, 1, 1), digits=17) [1] "2.0811768202028392e-19"
+ // formatC(SuppDists::pinvGauss(0.01, 1, 1), digits=17) [1] "4.122313403318778e-23"
+
+
+
+ //cout << " qinvgauss(0.3649755481729598, 1, 1) = " << qinvgauss(0.3649755481729598, 1, 1) << endl; // 0.5
+ // cout << quantile(s, 0.66810200122317065) << endl; // expect 1, get 0.50517388467190727
+ //cout << " qinvgauss(0.62502320258649202, 1, 1) = " << qinvgauss(0.62502320258649202, 1, 1) << endl; // 0.9
+ //cout << " qinvgauss(0.063753567519976254, 1, 1) = " << qinvgauss(0.063753567519976254, 1, 1) << endl; // 0.2
+ //cout << " qinvgauss(0.0040761113207110162, 1, 1) = " << qinvgauss(0.0040761113207110162, 1, 1) << endl; // 0.1
+
+ //double x = 1.; // SuppDists::pinvGauss(0.4, 1,1) [1] 0.2706137
+ //double c = pinvgauss(x, 1, 1); // 0.3649755481729598 == cdf(x, 1,1) 0.36497554817295974
+ //cout << " pinvgauss(x, 1, 1) = " << c << endl; // pinvgauss(x, 1, 1) = 0.27061367044245421
+ //double p = pdf(w11, x);
+ //double c = cdf(w11, x); // cdf(1, 1, 1) = 0.66810200122317065
+ //cout << "cdf(" << x << ", " << w11.mean() << ", "<< w11.scale() << ") = " << c << endl; // cdf(x, 1, 1) 0.27061367044245421
+ //cout << "pdf(" << x << ", " << w11.mean() << ", "<< w11.scale() << ") = " << p << endl;
+ //double q = quantile(w11, c);
+ //cout << "quantile(w11, " << c << ") = " << q << endl;
+
+ //cout << "quantile(w11, 4.122313403318778e-23) = "<< quantile(w11, 4.122313403318778e-23) << endl; // quantile
+ //cout << "quantile(w11, 4.8791443010851493e-219) = " << quantile(w11, 4.8791443010851493e-219) << endl; // quantile
+
+ //double c1 = 1 - cdf(w11, x); // 1 - cdf(1, 1, 1) = 0.33189799877682935
+ //cout << "1 - cdf(" << x << ", " << w11.mean() << ", " << w11.scale() << ") = " << c1 << endl; // cdf(x, 1, 1) 0.27061367044245421
+ //double cc = cdf(complement(w11, x));
+ //cout << "cdf(complement(" << x << ", " << w11.mean() << ", "<< w11.scale() << ")) = " << cc << endl; // cdf(x, 1, 1) 0.27061367044245421
+ //// 1 - cdf(1000, 1, 1) = 0
+ //// cdf(complement(1000, 1, 1)) = 4.8694344366900402e-222
+
+ //cout << "quantile(w11, " << c << ") = "<< quantile(w11, c) << endl; // quantile = 0.99999999999999978 == x = 1
+ //cout << "quantile(w11, " << c << ") = "<< quantile(w11, 1 - c) << endl; // quantile complement. quantile(w11, 0.66810200122317065) = 0.46336593652340152
+// cout << "quantile(complement(w11, " << c << ")) = " << quantile(complement(w11, c)) << endl; // quantile complement = 0.46336593652340163
+
+ // cdf(1, 1, 1) = 0.66810200122317065
+ // 1 - cdf(1, 1, 1) = 0.33189799877682935
+ // cdf(complement(1, 1, 1)) = 0.33189799877682929
+
+ // quantile(w11, 0.66810200122317065) = 0.99999999999999978
+ // 1 - quantile(w11, 0.66810200122317065) = 2.2204460492503131e-016
+ // quantile(complement(w11, 0.33189799877682929)) = 0.99999999999999989
+
+
+ // qinvgauss(c, 1, 1) = 0.3999999999999998
+ // SuppDists::qinvGauss(0.270613670442454, 1, 1) [1] 0.4
+
+
+ /*
+ double qs = pinvgaussU(c, 1, 1); //
+ cout << "qinvgaussU(c, 1, 1) = " << qs << endl; // qinvgaussU(c, 1, 1) = 0.86567442459240929
+ // > z=q - exp(c) * p [1] 0.8656744 qs 0.86567442459240929 double
+ // Is this the complement?
+ cout << "qgamma(0.2, 0.5, 1) expect 0.0320923 = " << qgamma(0.2, 0.5, 1) << endl;
+ // qgamma(0.2, 0.5, 1) expect 0.0320923 = 0.032092377333650807
+
+
+ cout << "qinvgauss(pinvgauss(x, 1, 1) = " << q
+ << ", diff = " << x - q << ", fraction = " << (x - q) /x << endl; // 0.5
+
+ */ // > SuppDists::pinvGauss(0.02, 1,1) [1] 4.139176e-12
+ // > SuppDists::qinvGauss(4.139176e-12, 1,1) [1] 0.02000000
+
+
+ // pinvGauss(1,1,1) = 0.668102 C++ == 0.66810200122317065
+ // qinvGauss(0.668102,1,1) = 1
+
+ // SuppDists::pinvGauss(0.3,1,1) = 0.1657266
+ // cout << "qinvGauss(0.0040761113207110162, 1, 1) = " << qinvgauss(0.0040761113207110162, 1, 1) << endl;
+ //cout << "quantile(s, 0.1657266) = " << quantile(s, 0.1657266) << endl; // expect 1.
+
+ //wald s12(2, 1);
+ //cout << "qinvGauss(0.3, 2, 1) = " << qinvgauss(0.3, 2, 1) << endl; // SuppDists::qinvGauss(0.3,2,1) == 0.58288065635052944
+ //// but actually get qinvGauss(0.3, 2, 1) = 0.58288064777632187
+ //cout << "cdf(s12, 0.3) = " << cdf(s12, 0.3) << endl; // cdf(s12, 0.3) = 0.10895339868447573
+
+ // using boost::math::wald;
+ //cout.precision(6);
+
+ /*
+ double m = 1;
+ double l = 1;
+ double x = 0.1;
+ //c = cdf(w, x);
+ double p = pinvgauss(x, m, l);
+ cout << "x = " << x << ", pinvgauss(x, m, l) = " << p << endl; // R 0.4 0.2706137
+ double qg = qgamma(1.- p, 0.5, 1.0, true, false);
+ cout << " qgamma(1.- p, 0.5, 1.0, true, false) = " << qg << endl; // 0.606817
+ double g = guess_whitmore(p, m, l);
+ cout << "m = " << m << ", l = " << l << ", x = " << x << ", guess = " << g
+ << ", diff = " << (x - g) << endl;
+
+ g = guess_wheeler(p, m, l);
+ cout << "m = " << m << ", l = " << l << ", x = " << x << ", guess = " << g
+ << ", diff = " << (x - g) << endl;
+
+ g = guess_bagshaw(p, m, l);
+ cout << "m = " << m << ", l = " << l << ", x = " << x << ", guess = " << g
+ << ", diff = " << (x - g) << endl;
+
+ // m = 1, l = 10, x = 0.9, guess = 0.89792, diff = 0.00231075 so a better fit.
+ // x = 0.9, guess = 0.887907
+ // x = 0.5, guess = 0.474977
+ // x = 0.4, guess = 0.369597
+ // x = 0.2, guess = 0.155196
+
+ // m = 1, l = 2, x = 0.9, guess = 1.0312, diff = -0.145778
+ // m = 1, l = 2, x = 0.1, guess = 0.122201, diff = -0.222013
+ // m = 1, l = 2, x = 0.2, guess = 0.299326, diff = -0.49663
+ // m = 1, l = 2, x = 0.5, guess = 1.00437, diff = -1.00875
+ // m = 1, l = 2, x = 0.7, guess = 1.01517, diff = -0.450247
+
+ double ls[7] = {0.1, 0.2, 0.5, 1., 2., 10, 100}; // scale values.
+ double ms[10] = {0.001, 0.02, 0.1, 0.2, 0.5, 0.9, 1., 2., 10, 100}; // mean values.
+ */
+
+ cout.precision(6); // Restore to default.
+ } // try
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+
+/*
+
+Output is:
+
+inverse_gaussian_example.cpp
+ inverse_gaussian_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Debug\inverse_gaussian_example.exe
+ Example: Inverse Gaussian Distribution.
+ (Standard) Inverse Gaussian distribution, mean = 1, scale = 1
+ Probability distribution function (pdf) values
+ z pdf
+ 2.23e-308 -1.#IND
+ 0.2 0.90052111680384117
+ 0.4 1.0055127039453111
+ 0.6 0.75123750098955733
+ 0.8 0.54377310461643302
+ 1 0.3989422804014327
+ 1.2 0.29846949816803292
+ 1.4 0.2274579835638664
+ 1.6 0.17614566625628389
+ 1.8 0.13829083543591469
+ 2 0.10984782236693062
+ 2.2 0.088133964251182237
+ 2.4 0.071327382959107177
+ 2.6 0.058162562161661699
+ 2.8 0.047742223328567722
+ 3 0.039418357969819712
+ 3.2 0.032715223861241892
+ 3.4 0.027278388940958308
+ 3.6 0.022840312999395804
+ 3.8 0.019196657941016954
+ 4 0.016189699458236451
+ Integral (area under the curve) from 0 up to z (cdf)
+ z cdf
+ 2.23e-308 0
+ 0.2 0.063753567519976254
+ 0.4 0.2706136704424541
+ 0.6 0.44638391340412931
+ 0.8 0.57472390962590925
+ 1 0.66810200122317065
+ 1.2 0.73724578422952536
+ 1.4 0.78944214237790356
+ 1.6 0.82953458108474554
+ 1.8 0.86079282968276671
+ 2 0.88547542598600626
+ 2.2 0.90517870624273966
+ 2.4 0.92105495653509362
+ 2.6 0.93395164268166786
+ 2.8 0.94450240360053817
+ 3 0.95318792074278835
+ 3.2 0.96037753019309191
+ 3.4 0.96635823989417369
+ 3.6 0.97135533107998406
+ 3.8 0.97554722413538364
+ 4 0.97907636417888622
+ 0.40000000000000008
+ 0.99999999999999967
+ 1.9999999999999973
+
+
+
+> SuppDists::dinvGauss(2, 1, 1) [1] 0.1098478
+> SuppDists::dinvGauss(0.4, 1, 1) [1] 1.005513
+> SuppDists::dinvGauss(0.5, 1, 1) [1] 0.8787826
+> SuppDists::dinvGauss(0.39, 1, 1) [1] 1.016559
+> SuppDists::dinvGauss(0.38, 1, 1) [1] 1.027006
+> SuppDists::dinvGauss(0.37, 1, 1) [1] 1.036748
+> SuppDists::dinvGauss(0.36, 1, 1) [1] 1.045661
+> SuppDists::dinvGauss(0.35, 1, 1) [1] 1.053611
+> SuppDists::dinvGauss(0.3, 1, 1) [1] 1.072888
+> SuppDists::dinvGauss(0.1, 1, 1) [1] 0.2197948
+> SuppDists::dinvGauss(0.2, 1, 1) [1] 0.9005211
+>
+x = 0.3 [1, 1] 1.0728879234594337 // R SuppDists::dinvGauss(0.3, 1, 1) [1] 1.072888
+
+x = 1 [1, 1] 0.3989422804014327
+
+
+ 0 " NA"
+ 1 "0.3989422804014327"
+ 2 "0.10984782236693059"
+ 3 "0.039418357969819733"
+ 4 "0.016189699458236468"
+ 5 "0.007204168934430732"
+ 6 "0.003379893528659049"
+ 7 "0.0016462878258114036"
+ 8 "0.00082460931140859956"
+ 9 "0.00042207355643694234"
+10 "0.00021979480031862676"
+
+
+[1] " NA" " 0.690988298942671" "0.11539974210409144"
+ [4] "0.01799698883772935" "0.0029555399206496469" "0.00050863023587406587"
+ [7] "9.0761842931362914e-05" "1.6655279133132795e-05" "3.1243174913715429e-06"
+[10] "5.96530227727434e-07" "1.1555606328299836e-07"
+
+
+matC(dinvGauss(0:10, 1, 3), digits=17) df = 3
+[1] " NA" " 0.690988298942671" "0.11539974210409144"
+ [4] "0.01799698883772935" "0.0029555399206496469" "0.00050863023587406587"
+ [7] "9.0761842931362914e-05" "1.6655279133132795e-05" "3.1243174913715429e-06"
+[10] "5.96530227727434e-07" "1.1555606328299836e-07"
+$title
+[1] "Inverse Gaussian"
+
+$nu
+[1] 1
+
+$lambda
+[1] 3
+
+$Mean
+[1] 1
+
+$Median
+[1] 0.8596309
+
+$Mode
+[1] 0.618034
+
+$Variance
+[1] 0.3333333
+
+$SD
+[1] 0.5773503
+
+$ThirdCentralMoment
+[1] 0.3333333
+
+$FourthCentralMoment
+[1] 0.8888889
+
+$PearsonsSkewness...mean.minus.mode.div.SD
+[1] 0.6615845
+
+$Skewness...sqrtB1
+[1] 1.732051
+
+$Kurtosis...B2.minus.3
+[1] 5
+
+ Example: Wald distribution.
+ (Standard) Wald distribution, mean = 1, scale = 1
+ 1 dx = 0.24890250442652451, x = 0.70924622051646713
+ 2 dx = -0.038547954953794553, x = 0.46034371608994262
+ 3 dx = -0.0011074090830291131, x = 0.49889167104373716
+ 4 dx = -9.1987259926368029e-007, x = 0.49999908012676625
+ 5 dx = -6.346513344581067e-013, x = 0.49999999999936551
+ dx = 6.3168242705156857e-017 at i = 6
+ qinvgauss(0.3649755481729598, 1, 1) = 0.50000000000000011
+ 1 dx = 0.6719944578376621, x = 1.3735318786222666
+ 2 dx = -0.16997432635769361, x = 0.70153742078460446
+ 3 dx = -0.027865119206495724, x = 0.87151174714229807
+ 4 dx = -0.00062283290009492603, x = 0.89937686634879377
+ 5 dx = -3.0075104108208687e-007, x = 0.89999969924888867
+ 6 dx = -7.0485322513588089e-014, x = 0.89999999999992975
+ 7 dx = 9.557331866250277e-016, x = 0.90000000000000024
+ dx = 0 at i = 8
+ qinvgauss(0.62502320258649202, 1, 1) = 0.89999999999999925
+ 1 dx = -0.0052296256747447678, x = 0.19483508278446249
+ 2 dx = 6.4699046853900505e-005, x = 0.20006470845920726
+ 3 dx = 9.4123530465288137e-009, x = 0.20000000941235335
+ 4 dx = 2.7739513919147025e-016, x = 0.20000000000000032
+ dx = 1.5410841066192808e-016 at i = 5
+ qinvgauss(0.063753567519976254, 1, 1) = 0.20000000000000004
+ 1 dx = -1, x = -0.46073286697416105
+ 2 dx = 0.47665501251497061, x = 0.53926713302583895
+ 3 dx = -0.171105768635964, x = 0.062612120510868341
+ 4 dx = 0.091490360797512563, x = 0.23371788914683234
+ 5 dx = 0.029410311722649803, x = 0.14222752834931979
+ 6 dx = 0.010761845493592421, x = 0.11281721662666999
+ 7 dx = 0.0019864890597643035, x = 0.10205537113307757
+ 8 dx = 6.8800383732599561e-005, x = 0.10006888207331327
+ 9 dx = 8.1689466405590418e-008, x = 0.10000008168958067
+ 10 dx = 1.133634672475146e-013, x = 0.10000000000011428
+ 11 dx = 5.9588135045224526e-016, x = 0.10000000000000091
+ 12 dx = 3.433223674791152e-016, x = 0.10000000000000031
+ dx = 9.0763384505974048e-017 at i = 13
+ qinvgauss(0.0040761113207110162, 1, 1) = 0.099999999999999964
+
+
+ wald_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Debug\wald_example.exe
+ Example: Wald distribution.
+ Tolerance = 6.66134e-016
+ (Standard) Wald distribution, mean = 1, scale = 1
+ cdf(x, 1,1) 4.1390252102096375e-012
+ qinvgauss(pinvgauss(x, 1, 1) = 0.020116801973767886, diff = -0.00011680197376788548, fraction = -0.005840098688394274
+ ____________________________________________________________
+ wald 1, 1
+ x = 0.02, diff x - qinvgauss(cdf) = -0.00011680197376788548
+ x = 0.10000000000000001, diff x - qinvgauss(cdf) = 8.7430063189231078e-016
+ x = 0.20000000000000001, diff x - qinvgauss(cdf) = -1.1102230246251565e-016
+ x = 0.29999999999999999, diff x - qinvgauss(cdf) = 0
+ x = 0.40000000000000002, diff x - qinvgauss(cdf) = 2.2204460492503131e-016
+ x = 0.5, diff x - qinvgauss(cdf) = -1.1102230246251565e-016
+ x = 0.59999999999999998, diff x - qinvgauss(cdf) = 1.1102230246251565e-016
+ x = 0.80000000000000004, diff x - qinvgauss(cdf) = 1.1102230246251565e-016
+ x = 0.90000000000000002, diff x - qinvgauss(cdf) = 0
+ x = 0.98999999999999999, diff x - qinvgauss(cdf) = -1.1102230246251565e-016
+ x = 0.999, diff x - qinvgauss(cdf) = -1.1102230246251565e-016
+
+
+*/
+
+
+
diff --git a/src/boost/libs/math/example/jacobi_zeta_example.cpp b/src/boost/libs/math/example/jacobi_zeta_example.cpp
new file mode 100644
index 000000000..062f27baa
--- /dev/null
+++ b/src/boost/libs/math/example/jacobi_zeta_example.cpp
@@ -0,0 +1,104 @@
+// Copyright Paul A. Bristow, 2019
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+/*! \title Simple example of computation of the Jacobi Zeta function using Boost.Math,
+and also using corresponding WolframAlpha commands.
+*/
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+# error "This example requires a C++ compiler that supports C++11 numeric_limits. Try C++11 or later."
+#endif
+
+#include <boost/math/special_functions/jacobi_zeta.hpp> // For jacobi_zeta function.
+#include <boost/multiprecision/cpp_bin_float.hpp> // For cpp_bin_float_50.
+
+#include <iostream>
+#include <limits>
+#include <iostream>
+#include <exception>
+
+int main()
+{
+ try
+ {
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // Show all potentially significant digits.
+ std::cout.setf(std::ios_base::showpoint); // Include any significant trailing zeros.
+
+ using boost::math::jacobi_zeta; // jacobi_zeta(T1 k, T2 phi) |k| <=1, k = sqrt(m)
+ using boost::multiprecision::cpp_bin_float_50;
+
+ // Wolfram Mathworld function JacobiZeta[phi, m] where m = k^2
+ // JacobiZeta[phi,m] gives the Jacobi zeta function Z(phi | m)
+
+ // If phi = 2, and elliptic modulus k = 0.9 so m = 0.9 * 0.9 = 0.81
+
+ // https://reference.wolfram.com/language/ref/JacobiZeta.html // Function information.
+ // A simple computation using phi = 2. and m = 0.9 * 0.9
+ // JacobiZeta[2, 0.9 * 0.9]
+ // https://www.wolframalpha.com/input/?i=JacobiZeta%5B2,+0.9+*+0.9%5D
+ // -0.248584...
+ // To get the expected 17 decimal digits precision for a 64-bit double type,
+ // we need to ask thus:
+ // N[JacobiZeta[2, 0.9 * 0.9],17]
+ // https://www.wolframalpha.com/input/?i=N%5BJacobiZeta%5B2,+0.9+*+0.9%5D,17%5D
+
+ double k = 0.9;
+ double m = k * k;
+ double phi = 2.;
+
+ std::cout << "m = k^2 = " << m << std::endl; // m = k^2 = 0.81000000000000005
+ std::cout << "jacobi_zeta(" << k << ", " << phi << " ) = " << jacobi_zeta(k, phi) << std::endl;
+ // jacobi_zeta(0.90000000000000002, 2.0000000000000000 ) =
+ // -0.24858442708494899 Boost.Math
+ // -0.24858442708494893 Wolfram
+ // that agree within the expected precision of 17 decimal digits for 64-bit type double.
+
+ // We can also easily get a higher precision too:
+ // For example, to get 50 decimal digit precision using WolframAlpha:
+ // N[JacobiZeta[2, 0.9 * 0.9],50]
+ // https://www.wolframalpha.com/input/?i=N%5BJacobiZeta%5B2,+0.9+*+0.9%5D,50%5D
+ // -0.24858442708494893408462856109734087389683955309853
+
+ // Using Boost.Multiprecision we can do them same almost as easily.
+
+ // To check that we are not losing precision, we show all the significant digits of the arguments ad result:
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::digits10); // Show all significant digits.
+
+ // We can force the computation to use 50 decimal digit precision thus:
+ cpp_bin_float_50 k50("0.9");
+ cpp_bin_float_50 phi50("2.");
+
+ std::cout << "jacobi_zeta(" << k50 << ", " << phi50 << " ) = " << jacobi_zeta(k50, phi50) << std::endl;
+ // jacobi_zeta(0.90000000000000000000000000000000000000000000000000,
+ // 2.0000000000000000000000000000000000000000000000000 )
+ // = -0.24858442708494893408462856109734087389683955309853
+
+ // and a comparison with Wolfram shows agreement to the expected precision.
+ // -0.24858442708494893408462856109734087389683955309853 Boost.Math
+ // -0.24858442708494893408462856109734087389683955309853 Wolfram
+
+ // Taking care not to fall into the awaiting pit, we ensure that ALL arguments passed are of the
+ // appropriate 50-digit precision and do NOT suffer from precision reduction to that of type double,
+ // We do NOT write:
+ std::cout << "jacobi_zeta<cpp_bin_float_50>(0.9, 2.) = " << jacobi_zeta<cpp_bin_float_50>(0.9, 2) << std::endl;
+ // jacobi_zeta(0.90000000000000000000000000000000000000000000000000,
+ // 2.0000000000000000000000000000000000000000000000000 )
+ // = -0.24858442708494895921459900494815797085727097762164 << Wrong at about 17th digit!
+ // -0.24858442708494893408462856109734087389683955309853 Wolfram
+ }
+ catch (std::exception const& ex)
+ {
+ // Lacking try&catch blocks, the program will abort after any throw, whereas the
+ // message below from the thrown exception will give some helpful clues as to the cause of the problem.
+ std::cout << "\n""Message from thrown exception was:\n " << ex.what() << std::endl;
+ // An example of message:
+ // std::cout << " = " << jacobi_zeta(2, 0.5) << std::endl;
+ // Message from thrown exception was:
+ // Error in function boost::math::ellint_k<long double>(long double) : Got k = 2, function requires |k| <= 1
+ // Shows that first parameter is k and is out of range, as the definition in docs jacobi_zeta(T1 k, T2 phi);
+ }
+} // int main()
diff --git a/src/boost/libs/math/example/lambert_w_basic_example.cpp b/src/boost/libs/math/example/lambert_w_basic_example.cpp
new file mode 100644
index 000000000..869416194
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_basic_example.cpp
@@ -0,0 +1,30 @@
+// Copyright Paul A. Bristow 2018
+
+// 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)
+
+// Example of most basic call of both lambert W functions.
+// Only requires C++03
+// (and optionally a call of max_digits10 to show precision).
+
+#include <boost/math/special_functions/lambert_w.hpp> // For lambert_w0 and wm1 functions.
+
+#include <iostream>
+#include <iomanip>
+
+int main()
+{
+ double z = 2.0;
+ double w0 = boost::math::lambert_w0(z);
+ std::cout.setf(std::ios_base::showpoint); // Include any trailing zeros.
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // Show all possibly significant digits.
+ // Avoid using max_digfigs10 so as many old compilers can run the most basic lambert_w0 test?
+ // Require to get max_digits10
+ // [ run lambert_w_basic_example.cpp : : : [ requires cxx11_numeric_limits ] ]
+ std::cout << " lambert_w0(" << z << ") = " << w0 << std::endl; // lambert_w0(2.00000) = 0.852606
+ z = -0.2;
+ double wm1 = boost::math::lambert_wm1(z);
+ std::cout << " lambert_wm1(" << z << ") = " << wm1 << std::endl; // lambert_wm1(-0.200000) = -2.54264
+ return 0;
+} // int main()
diff --git a/src/boost/libs/math/example/lambert_w_diode.cpp b/src/boost/libs/math/example/lambert_w_diode.cpp
new file mode 100644
index 000000000..79c64bd26
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_diode.cpp
@@ -0,0 +1,165 @@
+// Copyright Paul A. Bristow 2016
+// Copyright John Z. Maddock 2016
+
+// 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).
+
+/*! brief Example of using Lambert W function to compute current through a diode connected transistor with preset series resistance.
+ \details T. C. Banwell and A. Jayakumar,
+ Exact analytical solution of current flow through diode with series resistance,
+ Electron Letters, 36(4):291-2 (2000)
+ DOI: doi.org/10.1049/el:20000301
+
+ The current through a diode connected NPN bipolar junction transistor (BJT)
+ type 2N2222 (See https://en.wikipedia.org/wiki/2N2222 and
+ https://www.fairchildsemi.com/datasheets/PN/PN2222.pdf Datasheet)
+ was measured, for a voltage between 0.3 to 1 volt, see Fig 2 for a log plot,
+ showing a knee visible at about 0.6 V.
+
+ The transistor parameter isat was estimated to be 25 fA and the ideality factor = 1.0.
+ The intrinsic emitter resistance re was estimated from the rsat = 0 data to be 0.3 ohm.
+
+ The solid curves in Figure 2 are calculated using equation 5 with rsat included with re.
+
+ http://www3.imperial.ac.uk/pls/portallive/docs/1/7292572.PDF
+*/
+
+#include <boost/math/special_functions/lambert_w.hpp>
+using boost::math::lambert_w0;
+
+#include <iostream>
+// using std::cout;
+// using std::endl;
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <array>
+#include <vector>
+
+/*!
+Compute thermal voltage as a function of temperature,
+about 25 mV at room temperature.
+https://en.wikipedia.org/wiki/Boltzmann_constant#Role_in_semiconductor_physics:_the_thermal_voltage
+
+\param temperature Temperature (degrees centigrade).
+*/
+const double v_thermal(double temperature)
+{
+ constexpr const double boltzmann_k = 1.38e-23; // joules/kelvin.
+ const double charge_q = 1.6021766208e-19; // Charge of an electron (columb).
+ double temp =+ 273; // Degrees C to K.
+ return boltzmann_k * temp / charge_q;
+} // v_thermal
+
+/*!
+Banwell & Jayakumar, equation 2
+*/
+double i(double isat, double vd, double vt, double nu)
+{
+ double i = isat * (exp(vd / (nu * vt)) - 1);
+ return i;
+} //
+
+/*!
+
+Banwell & Jayakumar, Equation 4.
+i current flow = isat
+v voltage source.
+isat reverse saturation current in equation 4.
+(might implement equation 4 instead of simpler equation 5?).
+vd voltage drop = v - i* rs (equation 1).
+vt thermal voltage, 0.0257025 = 25 mV.
+nu junction ideality factor (default = unity), also known as the emission coefficient.
+re intrinsic emitter resistance, estimated to be 0.3 ohm from low current.
+rsat reverse saturation current
+
+\param v Voltage V to compute current I(V).
+\param vt Thermal voltage, for example 0.0257025 = 25 mV, computed from boltzmann_k * temp / charge_q;
+\param rsat Resistance in series with the diode.
+\param re Intrinsic emitter resistance (estimated to be 0.3 ohm from the Rs = 0 data)
+\param isat Reverse saturation current (See equation 2).
+\param nu Ideality factor (default = unity).
+
+\returns I amp as function of V volt.
+
+*/
+double iv(double v, double vt, double rsat, double re, double isat, double nu = 1.)
+{
+ // V thermal 0.0257025 = 25 mV
+ // was double i = (nu * vt/r) * lambert_w((i0 * r) / (nu * vt)); equ 5.
+
+ rsat = rsat + re;
+ double i = nu * vt / rsat;
+ std::cout << "nu * vt / rsat = " << i << std::endl; // 0.000103223
+
+ double x = isat * rsat / (nu * vt);
+ std::cout << "isat * rsat / (nu * vt) = " << x << std::endl;
+
+ double eterm = (v + isat * rsat) / (nu * vt);
+ std::cout << "(v + isat * rsat) / (nu * vt) = " << eterm << std::endl;
+
+ double e = exp(eterm);
+ std::cout << "exp(eterm) = " << e << std::endl;
+
+ double w0 = lambert_w0(x * e);
+ std::cout << "w0 = " << w0 << std::endl;
+ return i * w0 - isat;
+
+} // double iv
+
+std::array<double, 5> rss = {0., 2.18, 10., 51., 249}; // series resistance (ohm).
+std::array<double, 8> vds = { 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 }; // Diode voltage.
+
+int main()
+{
+ try
+ {
+ std::cout << "Lambert W diode current example." << std::endl;
+
+ //[lambert_w_diode_example_1
+ double x = 0.01;
+ //std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.00990147
+
+ double nu = 1.0; // Assumed ideal.
+ double vt = v_thermal(25); // v thermal, Shockley equation, expect about 25 mV at room temperature.
+ double boltzmann_k = 1.38e-23; // joules/kelvin
+ double temp = 273 + 25;
+ double charge_q = 1.6e-19; // column
+ vt = boltzmann_k * temp / charge_q;
+ std::cout << "V thermal "
+ << vt << std::endl; // V thermal 0.0257025 = 25 mV
+ double rsat = 0.;
+ double isat = 25.e-15; // 25 fA;
+ std::cout << "Isat = " << isat << std::endl;
+
+ double re = 0.3; // Estimated from slope of straight section of graph (equation 6).
+
+ double v = 0.9;
+ double icalc = iv(v, vt, 249., re, isat);
+
+ std::cout << "voltage = " << v << ", current = " << icalc << ", " << log(icalc) << std::endl; // voltage = 0.9, current = 0.00108485, -6.82631
+ //] [/lambert_w_diode_example_1]
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+} // int main()
+
+/*
+ Output:
+//[lambert_w_output_1
+ Lambert W diode current example.
+ V thermal 0.0257025
+ Isat = 2.5e-14
+ nu * vt / rsat = 0.000103099
+ isat * rsat / (nu * vt) = 2.42486e-10
+ (v + isat * rsat) / (nu * vt) = 35.016
+ exp(eterm) = 1.61167e+15
+ w0 = 10.5225
+ voltage = 0.9, current = 0.00108485, -6.82631
+
+//] [/lambert_w_output_1]
+*/
+
diff --git a/src/boost/libs/math/example/lambert_w_diode_graph.cpp b/src/boost/libs/math/example/lambert_w_diode_graph.cpp
new file mode 100644
index 000000000..d9a4bcda5
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_diode_graph.cpp
@@ -0,0 +1,280 @@
+// Copyright Paul A. Bristow 2016
+// Copyright John Z. Maddock 2016
+
+// 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).
+
+/*! \brief Graph showing use of Lambert W function to compute current
+through a diode-connected transistor with preset series resistance.
+
+\details T. C. Banwell and A. Jayakumar,
+Exact analytical solution of current flow through diode with series resistance,
+Electron Letters, 36(4):291-2 (2000).
+DOI: doi.org/10.1049/el:20000301
+
+The current through a diode connected NPN bipolar junction transistor (BJT)
+type 2N2222 (See https://en.wikipedia.org/wiki/2N2222 and
+https://www.fairchildsemi.com/datasheets/PN/PN2222.pdf Datasheet)
+was measured, for a voltage between 0.3 to 1 volt, see Fig 2 for a log plot, showing a knee visible at about 0.6 V.
+
+The transistor parameter I sat was estimated to be 25 fA and the ideality factor = 1.0.
+The intrinsic emitter resistance re was estimated from the rsat = 0 data to be 0.3 ohm.
+
+The solid curves in Figure 2 are calculated using equation 5 with rsat included with re.
+
+http://www3.imperial.ac.uk/pls/portallive/docs/1/7292572.PDF
+
+*/
+
+#include <boost/math/special_functions/lambert_w.hpp>
+using boost::math::lambert_w0;
+#include <boost/math/special_functions.hpp>
+using boost::math::isfinite;
+#include <boost/svg_plot/svg_2d_plot.hpp>
+using namespace boost::svg;
+
+#include <iostream>
+// using std::cout;
+// using std::endl;
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <array>
+#include <vector>
+#include <utility>
+using std::pair;
+#include <map>
+using std::map;
+#include <set>
+using std::multiset;
+#include <limits>
+using std::numeric_limits;
+#include <cmath> //
+
+/*!
+Compute thermal voltage as a function of temperature,
+about 25 mV at room temperature.
+https://en.wikipedia.org/wiki/Boltzmann_constant#Role_in_semiconductor_physics:_the_thermal_voltage
+
+\param temperature Temperature (degrees Celsius).
+*/
+const double v_thermal(double temperature)
+{
+ BOOST_CONSTEXPR const double boltzmann_k = 1.38e-23; // joules/kelvin.
+ BOOST_CONSTEXPR double charge_q = 1.6021766208e-19; // Charge of an electron (columb).
+ double temp = +273; // Degrees C to K.
+ return boltzmann_k * temp / charge_q;
+} // v_thermal
+
+ /*!
+ Banwell & Jayakumar, equation 2, page 291.
+ */
+double i(double isat, double vd, double vt, double nu)
+{
+ double i = isat * (exp(vd / (nu * vt)) - 1);
+ return i;
+} //
+
+ /*!
+ Banwell & Jayakumar, Equation 4, page 291.
+ i current flow = isat
+ v voltage source.
+ isat reverse saturation current in equation 4.
+ (might implement equation 4 instead of simpler equation 5?).
+ vd voltage drop = v - i* rs (equation 1).
+ vt thermal voltage, 0.0257025 = 25 mV.
+ nu junction ideality factor (default = unity), also known as the emission coefficient.
+ re intrinsic emitter resistance, estimated to be 0.3 ohm from low current.
+ rsat reverse saturation current
+
+ \param v Voltage V to compute current I(V).
+ \param vt Thermal voltage, for example 0.0257025 = 25 mV, computed from boltzmann_k * temp / charge_q;
+ \param rsat Resistance in series with the diode.
+ \param re Intrinsic emitter resistance (estimated to be 0.3 ohm from the Rs = 0 data)
+ \param isat Reverse saturation current (See equation 2).
+ \param nu Ideality factor (default = unity).
+
+ \returns I amp as function of V volt.
+ */
+
+//[lambert_w_diode_graph_2
+double iv(double v, double vt, double rsat, double re, double isat, double nu = 1.)
+{
+ // V thermal 0.0257025 = 25 mV
+ // was double i = (nu * vt/r) * lambert_w((i0 * r) / (nu * vt)); equ 5.
+
+ rsat = rsat + re;
+ double i = nu * vt / rsat;
+ // std::cout << "nu * vt / rsat = " << i << std::endl; // 0.000103223
+
+ double x = isat * rsat / (nu * vt);
+// std::cout << "isat * rsat / (nu * vt) = " << x << std::endl;
+
+ double eterm = (v + isat * rsat) / (nu * vt);
+ // std::cout << "(v + isat * rsat) / (nu * vt) = " << eterm << std::endl;
+
+ double e = exp(eterm);
+// std::cout << "exp(eterm) = " << e << std::endl;
+
+ double w0 = lambert_w0(x * e);
+// std::cout << "w0 = " << w0 << std::endl;
+ return i * w0 - isat;
+} // double iv
+
+//] [\lambert_w_diode_graph_2]
+
+
+std::array<double, 5> rss = { 0., 2.18, 10., 51., 249 }; // series resistance (ohm).
+std::array<double, 7> vds = { 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9 }; // Diode voltage.
+std::array<double, 7> lni = { -19.65, -15.75, -11.86, -7.97, -4.08, -0.0195, 3.6 }; // ln(current).
+
+int main()
+{
+ try
+ {
+ std::cout << "Lambert W diode current example." << std::endl;
+
+//[lambert_w_diode_graph_1
+ double nu = 1.0; // Assumed ideal.
+ double vt = v_thermal(25); // v thermal, Shockley equation, expect about 25 mV at room temperature.
+ double boltzmann_k = 1.38e-23; // joules/kelvin
+ double temp = 273 + 25;
+ double charge_q = 1.6e-19; // column
+ vt = boltzmann_k * temp / charge_q;
+ std::cout << "V thermal " << vt << std::endl; // V thermal 0.0257025 = 25 mV
+ double rsat = 0.;
+ double isat = 25.e-15; // 25 fA;
+ std::cout << "Isat = " << isat << std::endl;
+ double re = 0.3; // Estimated from slope of straight section of graph (equation 6).
+ double v = 0.9;
+ double icalc = iv(v, vt, 249., re, isat);
+ std::cout << "voltage = " << v << ", current = " << icalc << ", " << log(icalc) << std::endl; // voltage = 0.9, current = 0.00108485, -6.82631
+//] [/lambert_w_diode_graph_1]
+
+ // Plot a few measured data points.
+ std::map<const double, double> zero_data; // Extrapolated from slope of measurements with no external resistor.
+ zero_data[0.3] = -19.65;
+ zero_data[0.4] = -15.75;
+ zero_data[0.5] = -11.86;
+ zero_data[0.6] = -7.97;
+ zero_data[0.7] = -4.08;
+ zero_data[0.8] = -0.0195;
+ zero_data[0.9] = 3.9;
+
+ std::map<const double, double> measured_zero_data; // No external series resistor.
+ measured_zero_data[0.3] = -19.65;
+ measured_zero_data[0.4] = -15.75;
+ measured_zero_data[0.5] = -11.86;
+ measured_zero_data[0.6] = -7.97;
+ measured_zero_data[0.7] = -4.2;
+ measured_zero_data[0.72] = -3.5;
+ measured_zero_data[0.74] = -2.8;
+ measured_zero_data[0.76] = -2.3;
+ measured_zero_data[0.78] = -2.0;
+ // Measured from Fig 2 as raw data not available.
+
+ double step = 0.1;
+ for (int i = 0; i < vds.size(); i++)
+ {
+ zero_data[vds[i]] = lni[i];
+ std::cout << lni[i] << " " << vds[i] << std::endl;
+ }
+ step = 0.01;
+
+ std::map<const double, double> data_2;
+ for (double v = 0.3; v < 1.; v += step)
+ {
+ double current = iv(v, vt, 2., re, isat);
+ data_2[v] = log(current);
+ // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
+ }
+ std::map<const double, double> data_10;
+ for (double v = 0.3; v < 1.; v += step)
+ {
+ double current = iv(v, vt, 10., re, isat);
+ data_10[v] = log(current);
+ // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
+ }
+ std::map<const double, double> data_51;
+ for (double v = 0.3; v < 1.; v += step)
+ {
+ double current = iv(v, vt, 51., re, isat);
+ data_51[v] = log(current);
+ // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
+ }
+ std::map<const double, double> data_249;
+ for (double v = 0.3; v < 1.; v += step)
+ {
+ double current = iv(v, vt, 249., re, isat);
+ data_249[v] = log(current);
+ // std::cout << "v " << v << ", current = " << current << " log current = " << log(current) << std::endl;
+ }
+
+ svg_2d_plot data_plot;
+
+ data_plot.title("Diode current versus voltage")
+ .x_size(400)
+ .y_size(300)
+ .legend_on(true)
+ .legend_lines(true)
+ .x_label("voltage (V)")
+ .y_label("log(current) (A)")
+ //.x_label_on(true)
+ //.y_label_on(true)
+ //.xy_values_on(false)
+ .x_range(0.25, 1.)
+ .y_range(-20., +4.)
+ .x_major_interval(0.1)
+ .y_major_interval(4)
+ .x_major_grid_on(true)
+ .y_major_grid_on(true)
+ //.x_values_on(true)
+ //.y_values_on(true)
+ .y_values_rotation(horizontal)
+ //.plot_window_on(true)
+ .x_values_precision(3)
+ .y_values_precision(3)
+ .coord_precision(4) // Needed to avoid stepping on curves.
+ .copyright_holder("Paul A. Bristow")
+ .copyright_date("2016")
+ //.background_border_color(black);
+ ;
+
+ // &#x2080; = subscript zero.
+ data_plot.plot(zero_data, "I&#x2080;(V)").fill_color(lightgray).shape(none).size(3).line_on(true).line_width(0.5);
+ data_plot.plot(measured_zero_data, "Rs=0 &#x3A9;").fill_color(lightgray).shape(square).size(3).line_on(true).line_width(0.5);
+ data_plot.plot(data_2, "Rs=2 &#x3A9;").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
+ data_plot.plot(data_10, "Rs=10 &#x3A9;").line_color(purple).shape(none).line_on(true).bezier_on(false).line_width(1);
+ data_plot.plot(data_51, "Rs=51 &#x3A9;").line_color(green).shape(none).line_on(true).line_width(1);
+ data_plot.plot(data_249, "Rs=249 &#x3A9;").line_color(red).shape(none).line_on(true).line_width(1);
+ data_plot.write("./diode_iv_plot");
+
+ // bezier_on(true);
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+
+
+} // int main()
+
+ /*
+
+ //[lambert_w_output_1
+ Output:
+ Lambert W diode current example.
+ V thermal 0.0257025
+ Isat = 2.5e-14
+ voltage = 0.9, current = 0.00108485, -6.82631
+ -19.65 0.3
+ -15.75 0.4
+ -11.86 0.5
+ -7.97 0.6
+ -4.08 0.7
+ -0.0195 0.8
+ 3.6 0.9
+
+ //] [/lambert_w_output_1]
+ */
diff --git a/src/boost/libs/math/example/lambert_w_example.cpp b/src/boost/libs/math/example/lambert_w_example.cpp
new file mode 100644
index 000000000..28dbdf8a3
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_example.cpp
@@ -0,0 +1,239 @@
+// Copyright Paul A. Bristow 2016.
+
+// 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).
+
+// Test that can build and run a simple example of Lambert W function,
+// using algorithm of Thomas Luu.
+// https://svn.boost.org/trac/boost/ticket/11027
+
+#include <boost/config.hpp> // for BOOST_PLATFORM, BOOST_COMPILER, BOOST_STDLIB ...
+#include <boost/version.hpp> // for BOOST_MSVC versions.
+#include <boost/cstdint.hpp>
+#include <boost/exception/exception.hpp> // boost::exception
+#include <boost/math/constants/constants.hpp> // For exp_minus_one == 3.67879441171442321595523770161460867e-01.
+
+#define BOOST_MATH_INSTRUMENT_LAMBERT_W // #define only for diagnostic output.
+
+// For lambert_w function.
+#include <boost/math/special_functions/lambert_w.hpp>
+
+#include <iostream>
+// using std::cout;
+// using std::endl;
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <limits> // For std::numeric_limits.
+
+//! Show information about build, architecture, address model, platform, ...
+std::string show_versions()
+{
+ std::ostringstream message;
+
+ message << "Program: " << __FILE__ << "\n";
+#ifdef __TIMESTAMP__
+ message << __TIMESTAMP__;
+#endif
+ message << "\nBuildInfo:\n" " Platform " << BOOST_PLATFORM;
+ // http://stackoverflow.com/questions/1505582/determining-32-vs-64-bit-in-c
+#if defined(__LP64__) || defined(_WIN64) || (defined(__x86_64__) && !defined(__ILP32__) ) || defined(_M_X64) || defined(__ia64) || defined (_M_IA64) || defined(__aarch64__) || defined(__powerpc64__)
+#define IS64BIT 1
+ message << ", 64-bit.";
+#else
+#define IS32BIT 1
+ message << ", 32-bit.";
+#endif
+
+ message << "\n Compiler " BOOST_COMPILER;
+#ifdef BOOST_MSC_VER
+#ifdef _MSC_FULL_VER
+ message << "\n MSVC version " << BOOST_STRINGIZE(_MSC_FULL_VER) << ".";
+#endif
+#ifdef __WIN64
+ mess age << "\n WIN64" << std::endl;
+#endif // __WIN64
+#ifdef _WIN32
+ message << "\n WIN32" << std::endl;
+#endif // __WIN32
+#endif
+#ifdef __GNUC__
+ //PRINT_MACRO(__GNUC__);
+ //PRINT_MACRO(__GNUC_MINOR__);
+ //PRINT_MACRO(__GNUC_PATCH__);
+ std::cout << "GCC " << __VERSION__ << std::endl;
+ //PRINT_MACRO(LONG_MAX);
+#endif // __GNUC__
+
+ message << "\n STL " << BOOST_STDLIB;
+
+ message << "\n Boost version " << BOOST_VERSION / 100000 << "." << BOOST_VERSION / 100 % 1000 << "." << BOOST_VERSION % 100;
+
+#ifdef BOOST_HAS_FLOAT128
+ message << ", BOOST_HAS_FLOAT128" << std::endl;
+#endif
+ message << std::endl;
+ return message.str();
+} // std::string versions()
+
+int main()
+{
+ try
+ {
+ //std::cout << "Lambert W example basic!" << std::endl;
+ //std::cout << show_versions() << std::endl;
+
+ //std::cout << exp(1) << std::endl; // 2.71828
+ //std::cout << exp(-1) << std::endl; // 0.367879
+ //std::cout << std::numeric_limits<double>::epsilon() / 2 << std::endl; // 1.11022e-16
+
+ using namespace boost::math;
+ using boost::math::constants::exp_minus_one;
+ double x = 1.;
+
+ double W1 = lambert_w(1.);
+ // Note, NOT integer X, for example: lambert_w(1); or will get message like
+ // error C2338: Must be floating-point, not integer type, for example W(1.), not W(1)!
+ //
+
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.567143
+ // This 'golden ratio' for exponentials is http://mathworld.wolfram.com/OmegaConstant.html
+ // since exp[-W(1)] = W(1)
+ // A030178 Decimal expansion of LambertW(1): the solution to x*exp(x)
+ // = 0.5671432904097838729999686622103555497538157871865125081351310792230457930866
+ // http://oeis.org/A030178
+
+ double expplogone = exp(-lambert_w(1.));
+ if (expplogone != W1)
+ {
+ std::cout << expplogone << " " << W1 << std::endl; //
+ }
+
+
+//[lambert_w_example_1
+
+ x = 0.01;
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.00990147
+//] [/lambert_w_example_1]
+ x = -0.01;
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // -0.0101015
+ x = -0.1;
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; //
+ /**/
+
+ for (double xd = 1.; xd < 1e20; xd *= 10)
+ {
+
+ // 1. 0.56714329040978387
+ // 0.56714329040978384
+
+ // 10 1.7455280027406994
+ // 1.7455280027406994
+
+ // 100 3.3856301402900502
+ // 3.3856301402900502
+ // 1000 5.2496028524015959
+ // 5.249602852401596227126056319697306282521472386059592844451465483991362228320942832739693150854347718
+
+ // 1e19 40.058769161984308
+ // 40.05876916198431163898797971203180915622644925765346546858291325452428038208071849105889199253335063
+ std::cout << "Lambert W (" << xd << ") = " << lambert_w(xd) << std::endl; //
+ }
+ //
+ // Test near singularity.
+
+ // http://www.wolframalpha.com/input/?i=N%5Blambert_w%5B-0.367879%5D,17%5D test value N[lambert_w[-0.367879],17]
+ // -0.367879441171442321595523770161460867445811131031767834
+ x = -0.367879; // < -exp(1) = -0.367879
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // Lambert W (-0.36787900000000001) = -0.99845210378080340
+ // -0.99845210378080340
+ // -0.99845210378072726 N[lambert_w[-0.367879],17] wolfram so very close.
+
+ x = -0.3678794; // expect -0.99952696660756813
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+ x = -0.36787944; // expect -0.99992019848408340
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+ x = -0.367879441; // -0.99996947070054883
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+ x = -0.36787944117; // -0.99999719977527159
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+ x = -0.367879441171; // -0.99999844928821992
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+
+ x = -exp_minus_one<double>() + std::numeric_limits<double>::epsilon();
+ // Lambert W (-0.36787944117144211) = -0.99999996349975895
+ // N[lambert_w[-0.36787944117144211],17] == -0.99999996608315303
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+ std::cout << " 1 - sqrt(eps) = " << static_cast<double>(1) - sqrt(std::numeric_limits<double>::epsilon()) << std::endl;
+ x = -exp_minus_one<double>();
+ // N[lambert_w[-0.36787944117144233],17] == -1.000000000000000 + 6.7595465843924897*10^-9i
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // 0.0
+ // At Singularity - 0.36787944117144233 == -0.36787944117144233 returned - 1.0000000000000000
+ // Lambert W(-0.36787944117144233) = -1.0000000000000000
+
+
+ x = (std::numeric_limits<double>::max)()/4;
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; // OK 702.023799146706
+ x = (std::numeric_limits<double>::max)()/2;
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; //
+ x = (std::numeric_limits<double>::max)();
+ std::cout << "Lambert W (" << x << ") = " << lambert_w(x) << std::endl; //
+ // Error in function boost::math::log1p<double>(double): numeric overflow
+ /* */
+
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+
+
+} // int main()
+
+ /*
+
+//[lambert_w_output_1
+ Output:
+
+ 1> example_basic.cpp
+1> Generating code
+1> All 237 functions were compiled because no usable IPDB/IOBJ from previous compilation was found.
+1> Finished generating code
+1> LambertW.vcxproj -> J:\Cpp\Misc\x64\Release\LambertW.exe
+1> LambertW.vcxproj -> J:\Cpp\Misc\x64\Release\LambertW.pdb (Full PDB)
+1> Lambert W example basic!
+1> Platform: Win32
+1> Compiler: Microsoft Visual C++ version 14.0
+1> STL : Dinkumware standard library version 650
+1> Boost : 1.63.0
+1> _MSC_FULL_VER = 190024123
+1> Win32
+1> x64
+1> (x64)
+1> Iteration #0, w0 0.577547206058041, w1 = 0.567143616915443, difference = 0.0289944962755619, relative 0.018343835374856
+1> Iteration #1, w0 0.567143616915443, w1 = 0.567143290409784, difference = 9.02208135089566e-07, relative 5.75702234328901e-07
+1> Final 0.567143290409784 after 2 iterations, difference = 0
+1> Iteration #0, w0 0.577547206058041, w1 = 0.567143616915443, difference = 0.0289944962755619, relative 0.018343835374856
+1> Iteration #1, w0 0.567143616915443, w1 = 0.567143290409784, difference = 9.02208135089566e-07, relative 5.75702234328901e-07
+1> Final 0.567143290409784 after 2 iterations, difference = 0
+1> Lambert W (1) = 0.567143290409784
+1> Iteration #0, w0 0.577547206058041, w1 = 0.567143616915443, difference = 0.0289944962755619, relative 0.018343835374856
+1> Iteration #1, w0 0.567143616915443, w1 = 0.567143290409784, difference = 9.02208135089566e-07, relative 5.75702234328901e-07
+1> Final 0.567143290409784 after 2 iterations, difference = 0
+1> Iteration #0, w0 0.0099072820916067, w1 = 0.00990147384359511, difference = 5.92416060777624e-06, relative 0.000586604388734591
+1> Final 0.00990147384359511 after 1 iterations, difference = 0
+1> Lambert W (0.01) = 0.00990147384359511
+1> Iteration #0, w0 -0.0101016472705154, w1 = -0.0101015271985388, difference = -1.17664437923951e-07, relative 1.18865171889748e-05
+1> Final -0.0101015271985388 after 1 iterations, difference = 0
+1> Lambert W (-0.01) = -0.0101015271985388
+1> Iteration #0, w0 -0.111843322610692, w1 = -0.111832559158964, difference = -8.54817065376601e-06, relative 9.62461362694622e-05
+1> Iteration #1, w0 -0.111832559158964, w1 = -0.111832559158963, difference = -5.68989300120393e-16, relative 6.43929354282591e-15
+1> Final -0.111832559158963 after 2 iterations, difference = 0
+1> Lambert W (-0.1) = -0.111832559158963
+1> Iteration #0, w0 -0.998452103785573, w1 = -0.998452103780803, difference = -2.72004641033163e-15, relative 4.77662354114727e-12
+1> Final -0.998452103780803 after 1 iterations, difference = 0
+1> Lambert W (-0.367879) = -0.998452103780803
+
+//] [/lambert_w_output_1]
+ */
diff --git a/src/boost/libs/math/example/lambert_w_graph.cpp b/src/boost/libs/math/example/lambert_w_graph.cpp
new file mode 100644
index 000000000..3eb43f75a
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_graph.cpp
@@ -0,0 +1,286 @@
+// Copyright Paul A. Bristow 2017
+// Copyright John Z. Maddock 2017
+
+// 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).
+
+/*! \brief Graph showing use of Lambert W function.
+
+\details
+
+Both Lambert W0 and W-1 branches can be shown on one graph.
+But useful to have another graph for larger values of argument z.
+Need two separate graphs for Lambert W0 and -1 prime because
+the sensible ranges and axes are too different.
+
+One would get too small LambertW0 in top right and W-1 in bottom left.
+
+*/
+
+#include <boost/math/special_functions/lambert_w.hpp>
+using boost::math::lambert_w0;
+using boost::math::lambert_wm1;
+using boost::math::lambert_w0_prime;
+using boost::math::lambert_wm1_prime;
+
+#include <boost/math/special_functions.hpp>
+using boost::math::isfinite;
+#include <boost/svg_plot/svg_2d_plot.hpp>
+using namespace boost::svg;
+#include <boost/svg_plot/show_2d_settings.hpp>
+using boost::svg::show_2d_plot_settings;
+
+#include <iostream>
+// using std::cout;
+// using std::endl;
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <array>
+#include <vector>
+#include <utility>
+using std::pair;
+#include <map>
+using std::map;
+#include <set>
+using std::multiset;
+#include <limits>
+using std::numeric_limits;
+#include <cmath> //
+
+ /*!
+ */
+int main()
+{
+ try
+ {
+ std::cout << "Lambert W graph example." << std::endl;
+
+//[lambert_w_graph_1
+//] [/lambert_w_graph_1]
+ {
+ std::map<const double, double> wm1s; // Lambert W-1 branch values.
+ std::map<const double, double> w0s; // Lambert W0 branch values.
+
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+
+ int count = 0;
+ for (double z = -0.36787944117144232159552377016146086744581113103176804; z < 2.8; z += 0.001)
+ {
+ double w0 = lambert_w0(z);
+ w0s[z] = w0;
+ // std::cout << "z " << z << ", w = " << w0 << std::endl;
+ count++;
+ }
+ std::cout << "points " << count << std::endl;
+
+ count = 0;
+ for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001)
+ {
+ double wm1 = lambert_wm1(z);
+ wm1s[z] = wm1;
+ count++;
+ }
+ std::cout << "points " << count << std::endl;
+
+ svg_2d_plot data_plot;
+ data_plot.title("Lambert W function.")
+ .x_size(400)
+ .y_size(300)
+ .legend_on(true)
+ .legend_lines(true)
+ .x_label("z")
+ .y_label("W")
+ .x_range(-1, 3.)
+ .y_range(-4., +1.)
+ .x_major_interval(1.)
+ .y_major_interval(1.)
+ .x_major_grid_on(true)
+ .y_major_grid_on(true)
+ //.x_values_on(true)
+ //.y_values_on(true)
+ .y_values_rotation(horizontal)
+ //.plot_window_on(true)
+ .x_values_precision(3)
+ .y_values_precision(3)
+ .coord_precision(4) // Needed to avoid stepping on curves.
+ .copyright_holder("Paul A. Bristow")
+ .copyright_date("2018")
+ //.background_border_color(black);
+ ;
+ data_plot.plot(w0s, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1);
+ data_plot.plot(wm1s, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
+ data_plot.write("./lambert_w_graph");
+
+ show_2d_plot_settings(data_plot); // For plot diagnosis only.
+
+ } // small z Lambert W
+
+ { // bigger argument z Lambert W
+
+ std::map<const double, double> w0s_big; // Lambert W0 branch values for large z and W.
+ std::map<const double, double> wm1s_big; // Lambert W-1 branch values for small z and large -W.
+ int count = 0;
+ for (double z = -0.3678794411714423215955237701614608727; z < 10000.; z += 50.)
+ {
+ double w0 = lambert_w0(z);
+ w0s_big[z] = w0;
+ count++;
+ }
+ std::cout << "points " << count << std::endl;
+
+ count = 0;
+ for (double z = -0.3678794411714423215955237701614608727; z < -0.001; z += 0.001)
+ {
+ double wm1 = lambert_wm1(z);
+ wm1s_big[z] = wm1;
+ count++;
+ }
+ std::cout << "Lambert W0 large z argument points = " << count << std::endl;
+
+ svg_2d_plot data_plot2;
+ data_plot2.title("Lambert W0 function for larger z.")
+ .x_size(400)
+ .y_size(300)
+ .legend_on(false)
+ .x_label("z")
+ .y_label("W")
+ //.x_label_on(true)
+ //.y_label_on(true)
+ //.xy_values_on(false)
+ .x_range(-1, 10000.)
+ .y_range(-1., +8.)
+ .x_major_interval(2000.)
+ .y_major_interval(1.)
+ .x_major_grid_on(true)
+ .y_major_grid_on(true)
+ //.x_values_on(true)
+ //.y_values_on(true)
+ .y_values_rotation(horizontal)
+ //.plot_window_on(true)
+ .x_values_precision(3)
+ .y_values_precision(3)
+ .coord_precision(4) // Needed to avoid stepping on curves.
+ .copyright_holder("Paul A. Bristow")
+ .copyright_date("2018")
+ //.background_border_color(black);
+ ;
+
+ data_plot2.plot(w0s_big, "W0 branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1);
+ // data_plot2.plot(wm1s_big, "W-1 branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
+ // This wouldn't show anything useful.
+ data_plot2.write("./lambert_w_graph_big_w");
+ } // Big argument z Lambert W
+
+ { // Lambert W0 Derivative plots
+
+ // std::map<const double, double> wm1ps; // Lambert W-1 prime branch values.
+ std::map<const double, double> w0ps; // Lambert W0 prime branch values.
+
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+
+ int count = 0;
+ for (double z = -0.36; z < 3.; z += 0.001)
+ {
+ double w0p = lambert_w0_prime(z);
+ w0ps[z] = w0p;
+ // std::cout << "z " << z << ", w0 = " << w0 << std::endl;
+ count++;
+ }
+ std::cout << "points " << count << std::endl;
+
+ //count = 0;
+ //for (double z = -0.36; z < -0.1; z += 0.001)
+ //{
+ // double wm1p = lambert_wm1_prime(z);
+ // std::cout << "z " << z << ", w-1 = " << wm1p << std::endl;
+ // wm1ps[z] = wm1p;
+ // count++;
+ //}
+ //std::cout << "points " << count << std::endl;
+
+ svg_2d_plot data_plotp;
+ data_plotp.title("Lambert W0 prime function.")
+ .x_size(400)
+ .y_size(300)
+ .legend_on(false)
+ .x_label("z")
+ .y_label("W0'")
+ .x_range(-0.3, +1.)
+ .y_range(0., +5.)
+ .x_major_interval(0.2)
+ .y_major_interval(2.)
+ .x_major_grid_on(true)
+ .y_major_grid_on(true)
+ .y_values_rotation(horizontal)
+ .x_values_precision(3)
+ .y_values_precision(3)
+ .coord_precision(4) // Needed to avoid stepping on curves.
+ .copyright_holder("Paul A. Bristow")
+ .copyright_date("2018")
+ ;
+
+ // derivative of N[productlog(0, x), 55] at x=0 to 10
+ // Plot[D[N[ProductLog[0, x], 55], x], {x, 0, 10}]
+ // Plot[ProductLog[x]/(x + x ProductLog[x]), {x, 0, 10}]
+ data_plotp.plot(w0ps, "W0 prime branch").line_color(red).shape(none).line_on(true).bezier_on(false).line_width(1);
+ data_plotp.write("./lambert_w0_prime_graph");
+ } // Lambert W0 Derivative plots
+
+ { // Lambert Wm1 Derivative plots
+
+ std::map<const double, double> wm1ps; // Lambert W-1 prime branch values.
+
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+
+ int count = 0;
+ for (double z = -0.3678; z < -0.00001; z += 0.001)
+ {
+ double wm1p = lambert_wm1_prime(z);
+ // std::cout << "z " << z << ", w-1 = " << wm1p << std::endl;
+ wm1ps[z] = wm1p;
+ count++;
+ }
+ std::cout << "Lambert W-1 prime points = " << count << std::endl;
+
+ svg_2d_plot data_plotp;
+ data_plotp.title("Lambert W-1 prime function.")
+ .x_size(400)
+ .y_size(300)
+ .legend_on(false)
+ .x_label("z")
+ .y_label("W-1'")
+ .x_range(-0.4, +0.01)
+ .x_major_interval(0.1)
+ .y_range(-20., -5.)
+ .y_major_interval(5.)
+ .x_major_grid_on(true)
+ .y_major_grid_on(true)
+ .y_values_rotation(horizontal)
+ .x_values_precision(3)
+ .y_values_precision(3)
+ .coord_precision(4) // Needed to avoid stepping on curves.
+ .copyright_holder("Paul A. Bristow")
+ .copyright_date("2018")
+ ;
+
+ // derivative of N[productlog(0, x), 55] at x=0 to 10
+ // Plot[D[N[ProductLog[0, x], 55], x], {x, 0, 10}]
+ // Plot[ProductLog[x]/(x + x ProductLog[x]), {x, 0, 10}]
+ data_plotp.plot(wm1ps, "W-1 prime branch").line_color(blue).shape(none).line_on(true).bezier_on(false).line_width(1);
+ data_plotp.write("./lambert_wm1_prime_graph");
+ } // Lambert W-1 prime graph
+ } // try
+ catch (std::exception& ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+} // int main()
+
+ /*
+
+ //[lambert_w_graph_1_output
+
+ //] [/lambert_w_graph_1_output]
+ */
diff --git a/src/boost/libs/math/example/lambert_w_precision_example.cpp b/src/boost/libs/math/example/lambert_w_precision_example.cpp
new file mode 100644
index 000000000..e95f3b193
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_precision_example.cpp
@@ -0,0 +1,263 @@
+// Copyright Paul A. Bristow 2016, 2018.
+
+// 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).
+
+//! Lambert W examples of controlling precision
+
+// #define BOOST_MATH_INSTRUMENT_LAMBERT_W // #define only for (much) diagnostic output.
+
+#include <boost/config.hpp> // for BOOST_PLATFORM, BOOST_COMPILER, BOOST_STDLIB ...
+#include <boost/version.hpp> // for BOOST_MSVC versions.
+#include <boost/cstdint.hpp>
+#include <boost/exception/exception.hpp> // boost::exception
+#include <boost/math/constants/constants.hpp> // For exp_minus_one == 3.67879441171442321595523770161460867e-01.
+#include <boost/math/policies/policy.hpp>
+#include <boost/math/special_functions/next.hpp> // for float_distance.
+#include <boost/math/special_functions/relative_difference.hpp> // for relative and epsilon difference.
+
+// Built-in/fundamental GCC float128 or Intel Quad 128-bit type, if available.
+#ifdef BOOST_HAS_FLOAT128
+#include <boost/multiprecision/float128.hpp> // Not available for MSVC.
+// sets BOOST_MP_USE_FLOAT128 for GCC
+using boost::multiprecision::float128;
+#endif //# NOT _MSC_VER
+
+#include <boost/multiprecision/cpp_dec_float.hpp> // boost::multiprecision::cpp_dec_float_50
+using boost::multiprecision::cpp_dec_float_50; // 50 decimal digits type.
+using boost::multiprecision::cpp_dec_float_100; // 100 decimal digits type.
+
+#include <boost/multiprecision/cpp_bin_float.hpp>
+using boost::multiprecision::cpp_bin_float_double_extended;
+using boost::multiprecision::cpp_bin_float_double;
+using boost::multiprecision::cpp_bin_float_quad;
+// For lambert_w function.
+#include <boost/math/special_functions/lambert_w.hpp>
+// using boost::math::lambert_w0;
+// using boost::math::lambert_wm1;
+
+#include <iostream>
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <limits> // For std::numeric_limits.
+
+int main()
+{
+ try
+ {
+ std::cout << "Lambert W examples of precision control." << std::endl;
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+ std::cout << std::showpoint << std::endl; // Show any trailing zeros.
+
+ using boost::math::constants::exp_minus_one;
+
+ using boost::math::lambert_w0;
+ using boost::math::lambert_wm1;
+
+ // Error handling policy examples.
+ using namespace boost::math::policies;
+ using boost::math::policies::make_policy;
+ using boost::math::policies::policy;
+ using boost::math::policies::evaluation_error;
+ using boost::math::policies::domain_error;
+ using boost::math::policies::overflow_error;
+ using boost::math::policies::throw_on_error;
+
+//[lambert_w_precision_reference_w
+
+ using boost::multiprecision::cpp_bin_float_50;
+ using boost::math::float_distance;
+
+ cpp_bin_float_50 z("10."); // Note use a decimal digit string, not a double 10.
+ cpp_bin_float_50 r;
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::digits10);
+
+ r = lambert_w0(z); // Default policy.
+ std::cout << "lambert_w0(z) cpp_bin_float_50 = " << r << std::endl;
+ //lambert_w0(z) cpp_bin_float_50 = 1.7455280027406993830743012648753899115352881290809
+ // [N[productlog[10], 50]] == 1.7455280027406993830743012648753899115352881290809
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+ std::cout << "lambert_w0(z) static_cast from cpp_bin_float_50 = "
+ << static_cast<double>(r) << std::endl;
+ // double lambert_w0(z) static_cast from cpp_bin_float_50 = 1.7455280027406994
+ // [N[productlog[10], 17]] == 1.7455280027406994
+ std::cout << "bits different from Wolfram = "
+ << static_cast<int>(float_distance(static_cast<double>(r), 1.7455280027406994))
+ << std::endl; // 0
+
+
+//] [/lambert_w_precision_reference_w]
+
+//[lambert_w_precision_0
+ std::cout.precision(std::numeric_limits<float>::max_digits10); // Show all potentially significant decimal digits,
+ std::cout << std::showpoint << std::endl; // and show any significant trailing zeros too.
+
+ float x = 10.;
+ std::cout << "Lambert W (" << x << ") = " << lambert_w0(x) << std::endl;
+//] [/lambert_w_precision_0]
+
+/*
+//[lambert_w_precision_output_0
+Lambert W (10.0000000) = 1.74552800
+//] [/lambert_w_precision_output_0]
+*/
+ { // Lambert W0 Halley step example
+//[lambert_w_precision_1
+ using boost::math::lambert_w_detail::lambert_w_halley_step;
+ using boost::math::epsilon_difference;
+ using boost::math::relative_difference;
+
+ std::cout << std::showpoint << std::endl; // and show any significant trailing zeros too.
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // 17 decimal digits for double.
+
+ cpp_bin_float_50 z50("1.23"); // Note: use a decimal digit string, not a double 1.23!
+ double z = static_cast<double>(z50);
+ cpp_bin_float_50 w50;
+ w50 = lambert_w0(z50);
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::max_digits10); // 50 decimal digits.
+ std::cout << "Reference Lambert W (" << z << ") =\n "
+ << w50 << std::endl;
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // 17 decimal digits for double.
+ double wr = static_cast<double>(w50);
+ std::cout << "Reference Lambert W (" << z << ") = " << wr << std::endl;
+
+ double w = lambert_w0(z);
+ std::cout << "Rat/poly Lambert W (" << z << ") = " << lambert_w0(z) << std::endl;
+ // Add a Halley step to the value obtained from rational polynomial approximation.
+ double ww = lambert_w_halley_step(lambert_w0(z), z);
+ std::cout << "Halley Step Lambert W (" << z << ") = " << lambert_w_halley_step(lambert_w0(z), z) << std::endl;
+
+ std::cout << "absolute difference from Halley step = " << w - ww << std::endl;
+ std::cout << "relative difference from Halley step = " << relative_difference(w, ww) << std::endl;
+ std::cout << "epsilon difference from Halley step = " << epsilon_difference(w, ww) << std::endl;
+ std::cout << "epsilon for float = " << std::numeric_limits<double>::epsilon() << std::endl;
+ std::cout << "bits different from Halley step = " << static_cast<int>(float_distance(w, ww)) << std::endl;
+//] [/lambert_w_precision_1]
+
+
+/*
+//[lambert_w_precision_output_1
+ Reference Lambert W (1.2299999999999999822364316059974953532218933105468750) =
+ 0.64520356959320237759035605255334853830173300262666480
+ Reference Lambert W (1.2300000000000000) = 0.64520356959320235
+ Rat/poly Lambert W (1.2300000000000000) = 0.64520356959320224
+ Halley Step Lambert W (1.2300000000000000) = 0.64520356959320235
+ absolute difference from Halley step = -1.1102230246251565e-16
+ relative difference from Halley step = 1.7207329236029286e-16
+ epsilon difference from Halley step = 0.77494921535422934
+ epsilon for float = 2.2204460492503131e-16
+ bits different from Halley step = 1
+//] [/lambert_w_precision_output_1]
+*/
+
+ } // Lambert W0 Halley step example
+
+ { // Lambert W-1 Halley step example
+ //[lambert_w_precision_2
+ using boost::math::lambert_w_detail::lambert_w_halley_step;
+ using boost::math::epsilon_difference;
+ using boost::math::relative_difference;
+
+ std::cout << std::showpoint << std::endl; // and show any significant trailing zeros too.
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // 17 decimal digits for double.
+
+ cpp_bin_float_50 z50("-0.123"); // Note: use a decimal digit string, not a double -1.234!
+ double z = static_cast<double>(z50);
+ cpp_bin_float_50 wm1_50;
+ wm1_50 = lambert_wm1(z50);
+ std::cout.precision(std::numeric_limits<cpp_bin_float_50>::max_digits10); // 50 decimal digits.
+ std::cout << "Reference Lambert W-1 (" << z << ") =\n "
+ << wm1_50 << std::endl;
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // 17 decimal digits for double.
+ double wr = static_cast<double>(wm1_50);
+ std::cout << "Reference Lambert W-1 (" << z << ") = " << wr << std::endl;
+
+ double w = lambert_wm1(z);
+ std::cout << "Rat/poly Lambert W-1 (" << z << ") = " << lambert_wm1(z) << std::endl;
+ // Add a Halley step to the value obtained from rational polynomial approximation.
+ double ww = lambert_w_halley_step(lambert_wm1(z), z);
+ std::cout << "Halley Step Lambert W (" << z << ") = " << lambert_w_halley_step(lambert_wm1(z), z) << std::endl;
+
+ std::cout << "absolute difference from Halley step = " << w - ww << std::endl;
+ std::cout << "relative difference from Halley step = " << relative_difference(w, ww) << std::endl;
+ std::cout << "epsilon difference from Halley step = " << epsilon_difference(w, ww) << std::endl;
+ std::cout << "epsilon for float = " << std::numeric_limits<double>::epsilon() << std::endl;
+ std::cout << "bits different from Halley step = " << static_cast<int>(float_distance(w, ww)) << std::endl;
+ //] [/lambert_w_precision_2]
+ }
+ /*
+ //[lambert_w_precision_output_2
+ Reference Lambert W-1 (-0.12299999999999999822364316059974953532218933105468750) =
+ -3.2849102557740360179084675531714935199110302996513384
+ Reference Lambert W-1 (-0.12300000000000000) = -3.2849102557740362
+ Rat/poly Lambert W-1 (-0.12300000000000000) = -3.2849102557740357
+ Halley Step Lambert W (-0.12300000000000000) = -3.2849102557740362
+ absolute difference from Halley step = 4.4408920985006262e-16
+ relative difference from Halley step = 1.3519066740696092e-16
+ epsilon difference from Halley step = 0.60884463935795785
+ epsilon for float = 2.2204460492503131e-16
+ bits different from Halley step = -1
+ //] [/lambert_w_precision_output_2]
+ */
+
+
+
+ // Similar example using cpp_bin_float_quad (128-bit floating-point types).
+
+ cpp_bin_float_quad zq = 10.;
+ std::cout << "\nTest evaluation of cpp_bin_float_quad Lambert W(" << zq << ")"
+ << std::endl;
+ std::cout << std::setprecision(3) << "std::numeric_limits<cpp_bin_float_quad>::digits = " << std::numeric_limits<cpp_bin_float_quad>::digits << std::endl;
+ std::cout << std::setprecision(3) << "std::numeric_limits<cpp_bin_float_quad>::epsilon() = " << std::numeric_limits<cpp_bin_float_quad>::epsilon() << std::endl;
+ std::cout << std::setprecision(3) << "std::numeric_limits<cpp_bin_float_quad>::max_digits10 = " << std::numeric_limits<cpp_bin_float_quad>::max_digits10 << std::endl;
+ std::cout << std::setprecision(3) << "std::numeric_limits<cpp_bin_float_quad>::digits10 = " << std::numeric_limits<cpp_bin_float_quad>::digits10 << std::endl;
+ std::cout.precision(std::numeric_limits<cpp_bin_float_quad>::max_digits10);
+ // All are same precision because double precision first approximation used before Halley.
+
+ /*
+
+ */
+
+ { // Reference value for lambert_w0(10)
+ cpp_dec_float_50 z("10");
+ cpp_dec_float_50 r;
+ std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10);
+
+ r = lambert_w0(z); // Default policy.
+ std::cout << "lambert_w0(z) cpp_dec_float_50 = " << r << std::endl; // 0.56714329040978387299996866221035554975381578718651
+ std::cout.precision(std::numeric_limits<cpp_bin_float_quad>::max_digits10);
+
+ std::cout << "lambert_w0(z) cpp_dec_float_50 cast to quad (max_digits10(" << std::numeric_limits<cpp_bin_float_quad>::max_digits10 <<
+ " ) = " << static_cast<cpp_bin_float_quad>(r) << std::endl; // 1.7455280027406993830743012648753899115352881290809
+ std::cout.precision(std::numeric_limits<cpp_bin_float_quad>::digits10); // 1.745528002740699383074301264875389837
+ std::cout << "lambert_w0(z) cpp_dec_float_50 cast to quad (digits10(" << std::numeric_limits<cpp_bin_float_quad>::digits10 <<
+ " ) = " << static_cast<cpp_bin_float_quad>(r) << std::endl; // 1.74552800274069938307430126487539
+ std::cout.precision(std::numeric_limits<cpp_bin_float_quad>::digits10 + 1); //
+
+ std::cout << "lambert_w0(z) cpp_dec_float_50 cast to quad (digits10(" << std::numeric_limits<cpp_bin_float_quad>::digits10 <<
+ " ) = " << static_cast<cpp_bin_float_quad>(r) << std::endl; // 1.74552800274069938307430126487539
+
+ // [N[productlog[10], 50]] == 1.7455280027406993830743012648753899115352881290809
+
+ // [N[productlog[10], 37]] == 1.745528002740699383074301264875389912
+ // [N[productlog[10], 34]] == 1.745528002740699383074301264875390
+ // [N[productlog[10], 33]] == 1.74552800274069938307430126487539
+
+ // lambert_w0(z) cpp_dec_float_50 cast to quad = 1.745528002740699383074301264875389837
+
+ // lambert_w0(z) cpp_dec_float_50 = 1.7455280027406993830743012648753899115352881290809
+ // lambert_w0(z) cpp_dec_float_50 cast to quad = 1.745528002740699383074301264875389837
+ // lambert_w0(z) cpp_dec_float_50 cast to quad = 1.74552800274069938307430126487539
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+} // int main()
+
+
+
+
diff --git a/src/boost/libs/math/example/lambert_w_simple_examples.cpp b/src/boost/libs/math/example/lambert_w_simple_examples.cpp
new file mode 100644
index 000000000..3c422e062
--- /dev/null
+++ b/src/boost/libs/math/example/lambert_w_simple_examples.cpp
@@ -0,0 +1,251 @@
+// Copyright Paul A. Bristow 2016, 2017.
+
+// 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).
+
+// Build and run a simple examples of Lambert W function.
+
+// Some macros that will show some(or much) diagnostic values if #defined.
+//#define-able macros
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W0 // W0 branch diagnostics.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_Wm1 // W1 branch diagnostics.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W_HALLEY // Halley refinement diagnostics.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W_SCHROEDER // Schroeder refinement diagnostics.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W_TERMS // Number of terms used for near-singularity series.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W0_NOT_BUILTIN // higher than built-in precision types approximation and refinement.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W_SINGULARITY_SERIES // Show evaluation of series near branch singularity.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W_SMALL_Z_SERIES_ITERATIONS // Show evaluation of series for small z.
+//#define BOOST_MATH_INSTRUMENT_LAMBERT_W0_LOOKUP // Show results from lookup table.
+
+#include <boost/config.hpp> // for BOOST_PLATFORM, BOOST_COMPILER, BOOST_STDLIB ...
+#include <boost/version.hpp> // for BOOST_MSVC versions.
+#include <boost/cstdint.hpp>
+#include <boost/exception/exception.hpp> // boost::exception
+#include <boost/math/constants/constants.hpp> // For exp_minus_one == 3.67879441171442321595523770161460867e-01.
+#include <boost/math/policies/policy.hpp>
+
+#include <boost/multiprecision/cpp_dec_float.hpp> // boost::multiprecision::cpp_dec_float_50
+using boost::multiprecision::cpp_dec_float_50; // 50 decimal digits type.
+using boost::multiprecision::cpp_dec_float_100; // 100 decimal digits type.
+using boost::multiprecision::backends::cpp_dec_float;
+using boost::multiprecision::number;
+typedef number<cpp_dec_float<1000> > cpp_dec_float_1000; // 1000 decimal digit types
+
+#include <boost/multiprecision/cpp_bin_float.hpp>
+using boost::multiprecision::cpp_bin_float_double; // == double
+using boost::multiprecision::cpp_bin_float_double_extended; // 80-bit long double emulation.
+using boost::multiprecision::cpp_bin_float_quad; // 128-bit quad precision.
+
+//[lambert_w_simple_examples_includes
+#include <boost/math/special_functions/lambert_w.hpp> // For lambert_w function.
+
+using boost::math::lambert_w0;
+using boost::math::lambert_wm1;
+//] //[/lambert_w_simple_examples_includes]
+
+#include <iostream>
+// using std::cout;
+// using std::endl;
+#include <exception>
+#include <stdexcept>
+#include <string>
+#include <limits> // For std::numeric_limits.
+
+//! Show value of z to the full possibly-significant max_digits10 precision of type T.
+template<typename T>
+void show_value(T z)
+{
+ std::streamsize precision = std::cout.precision(std::numeric_limits<T>::max_digits10); // Save.
+ std::cout.precision(std::numeric_limits<T>::max_digits10); // Show all possibly significant digits.
+ std::ios::fmtflags flags(std::cout.flags());
+ std::cout.setf(std::ios_base::showpoint); // Include any trailing zeros.
+ std::cout << z;
+ // Restore:
+ std::cout.precision(precision);
+ std::cout.flags(flags);
+} // template<typename T> void show_value(T z)
+
+int main()
+{
+ try
+ {
+ std::cout << "Lambert W simple examples." << std::endl;
+
+ using boost::math::constants::exp_minus_one; //-1/e, the branch point, a singularity ~= -0.367879.
+
+ // using statements needed for changing error handling policy.
+ using boost::math::policies::policy;
+ using boost::math::policies::make_policy;
+ using boost::math::policies::evaluation_error;
+ using boost::math::policies::domain_error;
+ using boost::math::policies::overflow_error;
+ using boost::math::policies::ignore_error;
+ using boost::math::policies::throw_on_error;
+
+ {
+//[lambert_w_simple_examples_0
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+ // Show all potentially significant decimal digits,
+ std::cout << std::showpoint << std::endl;
+ // and show significant trailing zeros too.
+
+ double z = 10.;
+ double r = lambert_w0(z); // Default policy for double.
+ std::cout << "lambert_w0(z) = " << r << std::endl;
+ // lambert_w0(z) = 1.7455280027406994
+//] [/lambert_w_simple_examples_0]
+ }
+ {
+ // Other floating-point types can be used too, here float.
+ // It is convenient to use a function like `show_value`
+ // to display all potentially significant decimal digits
+ // for the type, including any significant trailing zeros.
+ //[lambert_w_simple_examples_1
+ float z = 10.F;
+ float r;
+ r = lambert_w0(z); // Default policy digits10 = 7, digits2 = 24
+ std::cout << "lambert_w0(";
+ show_value(z);
+ std::cout << ") = ";
+ show_value(r);
+ std::cout << std::endl; // lambert_w0(10.0000000) = 1.74552798
+ //] //[/lambert_w_simple_examples_1]
+ }
+ {
+ // Example of an integer argument to lambert_w,
+ // showing that an integer is correctly promoted to a double.
+//[lambert_w_simple_examples_2
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+ double r = lambert_w0(10); // Pass an int argument "10" that should be promoted to double argument.
+ std::cout << "lambert_w0(10) = " << r << std::endl; // lambert_w0(10) = 1.7455280027406994
+ double rp = lambert_w0(10);
+ std::cout << "lambert_w0(10) = " << rp << std::endl;
+ // lambert_w0(10) = 1.7455280027406994
+ auto rr = lambert_w0(10); // C++11 needed.
+ std::cout << "lambert_w0(10) = " << rr << std::endl;
+ // lambert_w0(10) = 1.7455280027406994 too, showing that rr has been promoted to double.
+//] //[/lambert_w_simple_examples_2]
+ }
+ {
+ // Using multiprecision types to get much higher precision is painless.
+ //[lambert_w_simple_examples_3
+ cpp_dec_float_50 z("10");
+ // Note construction using a decimal digit string "10",
+ // NOT a floating-point double literal 10.
+ cpp_dec_float_50 r;
+ r = lambert_w0(z);
+ std::cout << "lambert_w0("; show_value(z); std::cout << ") = ";
+ show_value(r);
+ std::cout << std::endl;
+ // lambert_w0(10.000000000000000000000000000000000000000000000000000000000000000000000000000000) =
+ // 1.7455280027406993830743012648753899115352881290809413313533156980404446940000000
+ //] //[/lambert_w_simple_examples_3]
+ }
+ // Using multiprecision types to get multiprecision precision wrong!
+ {
+ //[lambert_w_simple_examples_4
+ cpp_dec_float_50 z(0.7777777777777777777777777777777777777777777777777777777777777777777777777);
+ // Compiler evaluates the nearest double-precision binary representation,
+ // from the max_digits10 of the floating_point literal double 0.7777777777777777777777777777...,
+ // so any extra digits in the multiprecision type
+ // beyond max_digits10 (usually 17) are random and meaningless.
+ cpp_dec_float_50 r;
+ r = lambert_w0(z);
+ std::cout << "lambert_w0(";
+ show_value(z);
+ std::cout << ") = "; show_value(r);
+ std::cout << std::endl;
+ // lambert_w0(0.77777777777777779011358916250173933804035186767578125000000000000000000000000000)
+ // = 0.48086152073210493501934682309060873341910109230469724725005039758139532631901386
+ //] //[/lambert_w_simple_examples_4]
+ }
+ {
+ //[lambert_w_simple_examples_4a
+ cpp_dec_float_50 z(0.9); // Construct from floating_point literal double 0.9.
+ cpp_dec_float_50 r;
+ r = lambert_w0(0.9);
+ std::cout << "lambert_w0(";
+ show_value(z);
+ std::cout << ") = "; show_value(r);
+ std::cout << std::endl;
+ // lambert_w0(0.90000000000000002220446049250313080847263336181640625000000000000000000000000000)
+ // = 0.52983296563343440510607251781038939952850341796875000000000000000000000000000000
+ std::cout << "lambert_w0(0.9) = " << lambert_w0(static_cast<double>(0.9))
+ // lambert_w0(0.9)
+ // = 0.52983296563343441
+ << std::endl;
+ //] //[/lambert_w_simple_examples_4a]
+ }
+ {
+ // Using multiprecision types to get multiprecision precision right!
+ //[lambert_w_simple_examples_4b
+ cpp_dec_float_50 z("0.9"); // Construct from decimal digit string.
+ cpp_dec_float_50 r;
+ r = lambert_w0(z);
+ std::cout << "lambert_w0(";
+ show_value(z);
+ std::cout << ") = "; show_value(r);
+ std::cout << std::endl;
+ // 0.90000000000000000000000000000000000000000000000000000000000000000000000000000000)
+ // = 0.52983296563343441213336643954546304857788132269804249284012528304239956413801252
+ //] //[/lambert_w_simple_examples_4b]
+ }
+ // Getting extreme precision (1000 decimal digits) Lambert W values.
+ {
+ std::cout.precision(std::numeric_limits<cpp_dec_float_1000>::digits10);
+ cpp_dec_float_1000 z("2.0");
+ cpp_dec_float_1000 r;
+ r = lambert_w0(z);
+ std::cout << "lambert_w0(z) = " << r << std::endl;
+ // 0.8526055020137254913464724146953174668984533001514035087721073946525150656742630448965773783502494847334503972691804119834761668851953598826198984364998343940330324849743119327028383008883133161249045727544669202220292076639777316648311871183719040610274221013237163543451621208284315007250267190731048119566857455987975973474411544571619699938899354169616378479326962044241495398851839432070255805880208619490399218130868317114428351234208216131218024303904457925834743326836272959669122797896855064630871955955318383064292191644322931561534814178034773896739684452724587331245831001449498844495771266728242975586931792421997636537572767708722190588748148949667744956650966402600446780664924889043543203483210769017254907808218556111831854276511280553252641907484685164978750601216344998778097446525021666473925144772131644151718261199915247932015387685261438125313159125475113124470774926288823525823567568542843625471594347837868505309329628014463491611881381186810879712667681285740515197493390563
+ // Wolfram alpha command N[productlog[0, 2.0],1000] gives the identical result:
+ // 0.8526055020137254913464724146953174668984533001514035087721073946525150656742630448965773783502494847334503972691804119834761668851953598826198984364998343940330324849743119327028383008883133161249045727544669202220292076639777316648311871183719040610274221013237163543451621208284315007250267190731048119566857455987975973474411544571619699938899354169616378479326962044241495398851839432070255805880208619490399218130868317114428351234208216131218024303904457925834743326836272959669122797896855064630871955955318383064292191644322931561534814178034773896739684452724587331245831001449498844495771266728242975586931792421997636537572767708722190588748148949667744956650966402600446780664924889043543203483210769017254907808218556111831854276511280553252641907484685164978750601216344998778097446525021666473925144772131644151718261199915247932015387685261438125313159125475113124470774926288823525823567568542843625471594347837868505309329628014463491611881381186810879712667681285740515197493390563
+ }
+ {
+//[lambert_w_simple_examples_error_policies
+ // Define an error handling policy:
+ typedef policy<
+ domain_error<throw_on_error>,
+ overflow_error<ignore_error> // possibly unwise?
+ > my_throw_policy;
+
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+ // Show all potentially significant decimal digits,
+ std::cout << std::showpoint << std::endl;
+ // and show significant trailing zeros too.
+ double z = +1;
+ std::cout << "Lambert W (" << z << ") = " << lambert_w0(z) << std::endl;
+ // Lambert W (1.0000000000000000) = 0.56714329040978384
+ std::cout << "\nLambert W (" << z << ", my_throw_policy()) = "
+ << lambert_w0(z, my_throw_policy()) << std::endl;
+ // Lambert W (1.0000000000000000, my_throw_policy()) = 0.56714329040978384
+ //] //[/lambert_w_simple_example_error_policies]
+ }
+ {
+ // Show error reporting from passing a value to lambert_wm1 that is out of range,
+ // (and probably was meant to be passed to lambert_0 instead).
+//[lambert_w_simple_examples_out_of_range
+ double z = +1.;
+ double r = lambert_wm1(z);
+ std::cout << "lambert_wm1(+1.) = " << r << std::endl;
+ //] [/lambert_w_simple_examples_out_of_range]
+ // Error in function boost::math::lambert_wm1<RealType>(<RealType>):
+ // Argument z = 1 is out of range (z <= 0) for Lambert W-1 branch! (Try Lambert W0 branch?)
+ }
+ }
+ catch (std::exception& ex)
+ {
+ std::cout << ex.what() << std::endl;
+ }
+} // int main()
+
+ /*
+
+ Output:
+//[lambert_w_simple_examples_error_message_1
+Error in function boost::math::lambert_wm1<RealType>(<RealType>):
+Argument z = 1 is out of range (z <= 0) for Lambert W-1 branch! (Try Lambert W0 branch?)
+//] [/lambert_w_simple_examples_error_message_1]
+
+ */
diff --git a/src/boost/libs/math/example/laplace_example.cpp b/src/boost/libs/math/example/laplace_example.cpp
new file mode 100644
index 000000000..ed99dba21
--- /dev/null
+++ b/src/boost/libs/math/example/laplace_example.cpp
@@ -0,0 +1,169 @@
+// laplace_example.cpp
+
+// Copyright Paul A. Bristow 2008, 2010.
+
+// 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)
+
+// Example of using laplace (& comparing with normal) distribution.
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[laplace_example1
+/*`
+First we need some includes to access the laplace & normal distributions
+(and some std output of course).
+*/
+
+#include <boost/math/distributions/laplace.hpp> // for laplace_distribution
+ using boost::math::laplace; // typedef provides default type is double.
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+ using boost::math::normal; // typedef provides default type is double.
+
+#include <iostream>
+ using std::cout; using std::endl; using std::left; using std::showpoint; using std::noshowpoint;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+
+int main()
+{
+ cout << "Example: Laplace distribution." << endl;
+
+ try
+ {
+ { // Traditional tables and values.
+/*`Let's start by printing some traditional tables.
+*/
+ double step = 1.; // in z
+ double range = 4; // min and max z = -range to +range.
+ //int precision = 17; // traditional tables are only computed to much lower precision.
+ int precision = 4; // traditional table at much lower precision.
+ int width = 10; // for use with setw.
+
+ // Construct standard laplace & normal distributions l & s
+ normal s; // (default location or mean = zero, and scale or standard deviation = unity)
+ cout << "Standard normal distribution, mean or location = "<< s.location()
+ << ", standard deviation or scale = " << s.scale() << endl;
+ laplace l; // (default mean = zero, and standard deviation = unity)
+ cout << "Laplace normal distribution, location = "<< l.location()
+ << ", scale = " << l.scale() << endl;
+
+/*` First the probability distribution function (pdf).
+*/
+ cout << "Probability distribution function values" << endl;
+ cout << " z PDF normal laplace (difference)" << endl;
+ cout.precision(5);
+ for (double z = -range; z < range + step; z += step)
+ {
+ cout << left << setprecision(3) << setw(6) << z << " "
+ << setprecision(precision) << setw(width) << pdf(s, z) << " "
+ << setprecision(precision) << setw(width) << pdf(l, z)<< " ("
+ << setprecision(precision) << setw(width) << pdf(l, z) - pdf(s, z) // difference.
+ << ")" << endl;
+ }
+ cout.precision(6); // default
+/*`Notice how the laplace is less at z = 1 , but has 'fatter' tails at 2 and 3.
+
+ And the area under the normal curve from -[infin] up to z,
+ the cumulative distribution function (cdf).
+*/
+ // For a standard distribution
+ cout << "Standard location = "<< s.location()
+ << ", scale = " << s.scale() << endl;
+ cout << "Integral (area under the curve) from - infinity up to z " << endl;
+ cout << " z CDF normal laplace (difference)" << endl;
+ for (double z = -range; z < range + step; z += step)
+ {
+ cout << left << setprecision(3) << setw(6) << z << " "
+ << setprecision(precision) << setw(width) << cdf(s, z) << " "
+ << setprecision(precision) << setw(width) << cdf(l, z) << " ("
+ << setprecision(precision) << setw(width) << cdf(l, z) - cdf(s, z) // difference.
+ << ")" << endl;
+ }
+ cout.precision(6); // default
+
+/*`
+Pretty-printing a traditional 2-dimensional table is left as an exercise for the student,
+but why bother now that the Boost Math Toolkit lets you write
+*/
+ double z = 2.;
+ cout << "Area for gaussian z = " << z << " is " << cdf(s, z) << endl; // to get the area for z.
+ cout << "Area for laplace z = " << z << " is " << cdf(l, z) << endl; //
+/*`
+Correspondingly, we can obtain the traditional 'critical' values for significance levels.
+For the 95% confidence level, the significance level usually called alpha,
+is 0.05 = 1 - 0.95 (for a one-sided test), so we can write
+*/
+ cout << "95% of gaussian area has a z below " << quantile(s, 0.95) << endl;
+ cout << "95% of laplace area has a z below " << quantile(l, 0.95) << endl;
+ // 95% of area has a z below 1.64485
+ // 95% of laplace area has a z below 2.30259
+/*`and a two-sided test (a comparison between two levels, rather than a one-sided test)
+
+*/
+ cout << "95% of gaussian area has a z between " << quantile(s, 0.975)
+ << " and " << -quantile(s, 0.975) << endl;
+ cout << "95% of laplace area has a z between " << quantile(l, 0.975)
+ << " and " << -quantile(l, 0.975) << endl;
+ // 95% of area has a z between 1.95996 and -1.95996
+ // 95% of laplace area has a z between 2.99573 and -2.99573
+/*`Notice how much wider z has to be to enclose 95% of the area.
+*/
+ }
+//] [/[laplace_example1]
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+Example: Laplace distribution.
+Standard normal distribution, mean or location = 0, standard deviation or scale = 1
+Laplace normal distribution, location = 0, scale = 1
+Probability distribution function values
+ z PDF normal laplace (difference)
+-4 0.0001338 0.009158 (0.009024 )
+-3 0.004432 0.02489 (0.02046 )
+-2 0.05399 0.06767 (0.01368 )
+-1 0.242 0.1839 (-0.05803 )
+0 0.3989 0.5 (0.1011 )
+1 0.242 0.1839 (-0.05803 )
+2 0.05399 0.06767 (0.01368 )
+3 0.004432 0.02489 (0.02046 )
+4 0.0001338 0.009158 (0.009024 )
+Standard location = 0, scale = 1
+Integral (area under the curve) from - infinity up to z
+ z CDF normal laplace (difference)
+-4 3.167e-005 0.009158 (0.009126 )
+-3 0.00135 0.02489 (0.02354 )
+-2 0.02275 0.06767 (0.04492 )
+-1 0.1587 0.1839 (0.02528 )
+0 0.5 0.5 (0 )
+1 0.8413 0.8161 (-0.02528 )
+2 0.9772 0.9323 (-0.04492 )
+3 0.9987 0.9751 (-0.02354 )
+4 1 0.9908 (-0.009126 )
+Area for gaussian z = 2 is 0.97725
+Area for laplace z = 2 is 0.932332
+95% of gaussian area has a z below 1.64485
+95% of laplace area has a z below 2.30259
+95% of gaussian area has a z between 1.95996 and -1.95996
+95% of laplace area has a z between 2.99573 and -2.99573
+
+*/
+
diff --git a/src/boost/libs/math/example/legendre_stieltjes_example.cpp b/src/boost/libs/math/example/legendre_stieltjes_example.cpp
new file mode 100644
index 000000000..00ceba277
--- /dev/null
+++ b/src/boost/libs/math/example/legendre_stieltjes_example.cpp
@@ -0,0 +1,110 @@
+// Copyright Nick Thompson 2017.
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#include <iostream>
+#include <string>
+#include <boost/math/constants/constants.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp>
+#include <boost/multiprecision/cpp_dec_float.hpp>
+#include <boost/math/special_functions/legendre_stieltjes.hpp>
+
+using boost::math::legendre_p;
+using boost::math::legendre_p_zeros;
+using boost::math::legendre_p_prime;
+using boost::math::legendre_stieltjes;
+using boost::multiprecision::cpp_bin_float_quad;
+using boost::multiprecision::cpp_bin_float_100;
+using boost::multiprecision::cpp_dec_float_100;
+
+template<class Real>
+void gauss_kronrod_rule(size_t order)
+{
+ std::cout << std::setprecision(std::numeric_limits<Real>::digits10);
+ std::cout << std::fixed;
+ auto gauss_nodes = boost::math::legendre_p_zeros<Real>(order);
+ auto E = legendre_stieltjes<Real>(order + 1);
+ std::vector<Real> gauss_weights(gauss_nodes.size(), std::numeric_limits<Real>::quiet_NaN());
+ std::vector<Real> gauss_kronrod_weights(gauss_nodes.size(), std::numeric_limits<Real>::quiet_NaN());
+ for (size_t i = 0; i < gauss_nodes.size(); ++i)
+ {
+ Real node = gauss_nodes[i];
+ Real lp = legendre_p_prime<Real>(order, node);
+ gauss_weights[i] = 2/( (1-node*node)*lp*lp);
+ // P_n(x) = (2n)!/(2^n (n!)^2) pi_n(x), where pi_n is the monic Legendre polynomial.
+ gauss_kronrod_weights[i] = gauss_weights[i] + static_cast<Real>(2)/(static_cast<Real>(order+1)*legendre_p_prime(order, node)*E(node));
+ }
+
+ std::cout << "static const std::vector<Real> gauss_nodes {\n";
+ for (auto const & node : gauss_nodes)
+ {
+ std::cout << " boost::lexical_cast<Real>(\"" << node << "\"),\n";
+ }
+ std::cout << "};\n\n";
+
+ std::cout << "static const std::vector<Real> gauss_weights {\n";
+ for (auto const & weight : gauss_weights)
+ {
+ std::cout << " boost::lexical_cast<Real>(\"" << weight << "\"),\n";
+ }
+ std::cout << "};\n\n";
+
+ std::cout << "static const std::vector<Real> gauss_kronrod_weights {\n";
+ for (auto const & weight : gauss_kronrod_weights)
+ {
+ std::cout << " boost::lexical_cast<Real>(\"" << weight << "\"),\n";
+ }
+ std::cout << "};\n\n";
+
+ auto kronrod_nodes = E.zeros();
+ std::vector<Real> kronrod_weights(kronrod_nodes.size());
+ for (size_t i = 0; i < kronrod_weights.size(); ++i)
+ {
+ Real node = kronrod_nodes[i];
+ kronrod_weights[i] = static_cast<Real>(2)/(static_cast<Real>(order+1)*legendre_p(order, node)*E.prime(node));
+ }
+
+ std::cout << "static const std::vector<Real> kronrod_nodes {\n";
+ for (auto node : kronrod_nodes)
+ {
+ std::cout << " boost::lexical_cast<Real>(\"" << node << "\"),\n";
+ }
+ std::cout << "};\n\n";
+
+ std::cout << "static const std::vector<Real> kronrod_weights {\n";
+ for (auto const & weight : kronrod_weights)
+ {
+ std::cout << " boost::lexical_cast<Real>(\"" << weight << "\"),\n";
+ }
+ std::cout << "};\n\n";
+
+}
+
+int main()
+{
+ //std::cout << "Gauss-Kronrod 7-15 Rule:\n";
+ //gauss_kronrod_rule<cpp_dec_float_100>(7);
+
+ //std::cout << "\n\nGauss-Kronrod 10-21 Rule:\n";
+ //gauss_kronrod_rule<cpp_dec_float_100>(10);
+
+ std::cout << "\n\nGauss-Kronrod 15-31 Rule:\n";
+ gauss_kronrod_rule<cpp_dec_float_100>(15);
+ /*
+ std::cout << "\n\nGauss-Kronrod 20-41 Rule:\n";
+ gauss_kronrod_rule<cpp_dec_float_100>(20);
+
+ std::cout << "\n\nGauss-Kronrod 25-51 Rule:\n";
+ gauss_kronrod_rule<cpp_dec_float_100>(25);
+
+ std::cout << "\n\nGauss-Kronrod 30-61 Rule:\n";
+ gauss_kronrod_rule<cpp_dec_float_100>(30);
+
+ std::cout << "\n\nGauss-Kronrod 35-71 Rule:\n";
+ gauss_kronrod_rule<cpp_dec_float_100>(35);
+
+ std::cout << "\n\nGauss-Kronrod 40-81 Rule:\n";
+ gauss_kronrod_rule<cpp_dec_float_100>(40);*/
+}
diff --git a/src/boost/libs/math/example/lexical_cast_native.cpp b/src/boost/libs/math/example/lexical_cast_native.cpp
new file mode 100644
index 000000000..508b35fda
--- /dev/null
+++ b/src/boost/libs/math/example/lexical_cast_native.cpp
@@ -0,0 +1,133 @@
+/** lexical_cast_nonfinite_facets.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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)
+*
+* This very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' with lexical cast
+* to obtain C99 representation of infinity and NaN.
+* This example is from the original Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A very simple example of using lexical cast with
+non_finite_num facet for C99 standard output of infinity and NaN.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allows lexical_cast output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <boost/lexical_cast.hpp>
+using boost::lexical_cast;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+#include <boost/assert.hpp>
+
+int main ()
+{
+ std::cout << "lexical_cast example (NOT using finite_num_facet)." << std::endl;
+
+ if((std::numeric_limits<double>::has_infinity == false) || (std::numeric_limits<double>::infinity() == 0))
+ {
+ std::cout << "Infinity not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ if((std::numeric_limits<double>::has_quiet_NaN == false) || (std::numeric_limits<double>::quiet_NaN() == 0))
+ {
+ std::cout << "NaN not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ // Some tests that are expected to fail on some platforms.
+ // (But these tests are expected to pass using non_finite num_put and num_get facets).
+
+ // Use the current 'native' default locale.
+ std::locale default_locale (std::locale::classic ()); // Note the current (default C) locale.
+
+ // Create plus and minus infinity.
+ double plus_infinity = +std::numeric_limits<double>::infinity();
+ double minus_infinity = -std::numeric_limits<double>::infinity();
+
+ // and create a NaN (NotANumber).
+ double NaN = +std::numeric_limits<double>::quiet_NaN ();
+
+ // Output the nonfinite values using the current (default C) locale.
+ // The default representations differ from system to system,
+ // for example, using Microsoft compilers, 1.#INF, -1.#INF, and 1.#QNAN.
+ cout << "Using default locale" << endl;
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+ // Checks below are expected to fail on some platforms!
+
+ // Now try some 'round-tripping', 'reading' "inf"
+ double x = boost::lexical_cast<double>("inf");
+ // and check we get a floating-point infinity.
+ BOOST_ASSERT(x == std::numeric_limits<double>::infinity());
+
+ // Check we can convert the other way from floating-point infinity,
+ string s = boost::lexical_cast<string>(numeric_limits<double>::infinity());
+ // to a C99 string representation as "inf".
+ BOOST_ASSERT(s == "inf");
+
+ // Finally try full 'round-tripping' (in both directions):
+ BOOST_ASSERT(lexical_cast<double>(lexical_cast<string>(numeric_limits<double>::infinity()))
+ == numeric_limits<double>::infinity());
+ BOOST_ASSERT(lexical_cast<string>(lexical_cast<double>("inf")) == "inf");
+
+ return 0;
+} // int main()
+
+/*
+
+Output:
+
+from MSVC 10, fails (as expected)
+
+ lexical_cast_native.vcxproj -> J:\Cpp\fp_facet\fp_facet\Debug\lexical_cast_native.exe
+ lexical_cast example (NOT using finite_num_facet).
+ Using default locale
+ +std::numeric_limits<double>::infinity() = 1.#INF
+ -std::numeric_limits<double>::infinity() = -1.#INF
+ +std::numeric_limits<double>::quiet_NaN () = 1.#QNAN
+C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(183,5): error MSB3073: The command ""J:\Cpp\fp_facet\fp_facet\Debug\lexical_cast_native.exe"
+C:\Program Files\MSBuild\Microsoft.Cpp\v4.0\Microsoft.CppCommon.targets(183,5): error MSB3073: :VCEnd" exited with code 3.
+
+
+*/
diff --git a/src/boost/libs/math/example/lexical_cast_nonfinite_facets.cpp b/src/boost/libs/math/example/lexical_cast_nonfinite_facets.cpp
new file mode 100644
index 000000000..ecbda89ae
--- /dev/null
+++ b/src/boost/libs/math/example/lexical_cast_nonfinite_facets.cpp
@@ -0,0 +1,133 @@
+/** lexical_cast_nonfinite_facets.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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)
+*
+* This very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' with lexical cast
+* to obtain C99 representation of infinity and NaN.
+* This example is from the original Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A very simple example of using lexical cast with
+non_finite_num facet for C99 standard output of infinity and NaN.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allows lexical_cast output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+
+See also lexical_cast_native.cpp which is expected to fail on many systems,
+but might succeed if the default locale num_put and num_get facets
+comply with C99 nonfinite input and output specification.
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <boost/lexical_cast.hpp>
+using boost::lexical_cast;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+#include <boost/assert.hpp>
+
+int main ()
+{
+ std::cout << "finite_num_facet with lexical_cast example." << std::endl;
+
+ // Example of using non_finite num_put and num_get facets with lexical_cast.
+ //locale old_locale;
+ //locale tmp_locale(old_locale, new nonfinite_num_put<char>);
+ //// Create a new temporary output locale, and add the output nonfinite_num_put facet.
+
+ //locale new_locale(tmp_locale, new nonfinite_num_get<char>);
+ // Create a new output locale (from the tmp locale), and add the input nonfinite_num_get facet.
+
+ // Note that you can only add facets one at a time,
+ // unless you chain thus:
+
+ std::locale new_locale(std::locale(std::locale(),
+ new boost::math::nonfinite_num_put<char>),
+ new boost::math::nonfinite_num_get<char>);
+
+ locale::global(new_locale); // Newly constructed streams
+ // (including those streams inside lexical_cast)
+ // now use new_locale with nonfinite facets.
+
+ // Output using the new locale.
+ cout << "Using C99_out_locale " << endl;
+ cout.imbue(new_locale);
+ // Necessary because cout already constructed using default C locale,
+ // and default facets for nonfinites.
+
+ // Create plus and minus infinity.
+ double plus_infinity = +std::numeric_limits<double>::infinity();
+ double minus_infinity = -std::numeric_limits<double>::infinity();
+
+ // and create a NaN (NotANumber)
+ double NaN = +std::numeric_limits<double>::quiet_NaN ();
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+ // Now try some 'round-tripping', 'reading' "inf".
+ double x = boost::lexical_cast<double>("inf");
+ // and check we get a floating-point infinity.
+ BOOST_ASSERT(x == std::numeric_limits<double>::infinity());
+ cout << "boost::lexical_cast<double>(\"inf\") = " << x << endl;
+
+ // Check we can convert the other way from floating-point infinity,
+ string s = boost::lexical_cast<string>(numeric_limits<double>::infinity());
+ // to a C99 string representation as "inf".
+ BOOST_ASSERT(s == "inf");
+
+ // Finally try full 'round-tripping' (in both directions):
+ BOOST_ASSERT(lexical_cast<double>(lexical_cast<string>(numeric_limits<double>::infinity()))
+ == numeric_limits<double>::infinity());
+ BOOST_ASSERT(lexical_cast<string>(lexical_cast<double>("inf")) == "inf");
+
+ return 0;
+} // int main()
+
+/*
+
+Output:
+ finite_num_facet with lexical_cast example.
+ Using C99_out_locale
+ +std::numeric_limits<double>::infinity() = inf
+ -std::numeric_limits<double>::infinity() = -inf
+ +std::numeric_limits<double>::quiet_NaN () = nan
+ boost::lexical_cast<double>("inf") = inf
+
+
+*/
diff --git a/src/boost/libs/math/example/naive_monte_carlo_example.cpp b/src/boost/libs/math/example/naive_monte_carlo_example.cpp
new file mode 100644
index 000000000..800eb6794
--- /dev/null
+++ b/src/boost/libs/math/example/naive_monte_carlo_example.cpp
@@ -0,0 +1,136 @@
+/*
+ * Copyright Nick Thompson, 2017
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ */
+
+#include <boost/math/quadrature/naive_monte_carlo.hpp>
+#include <iostream>
+#include <iomanip>
+#include <limits>
+#include <cmath>
+#include <thread>
+#include <future>
+#include <string>
+#include <chrono>
+#include <boost/math/special_functions/pow.hpp>
+#include <boost/math/constants/constants.hpp>
+
+using std::vector;
+using std::pair;
+using boost::math::quadrature::naive_monte_carlo;
+
+void display_progress(double progress,
+ double error_estimate,
+ double current_estimate,
+ std::chrono::duration<double> estimated_time_to_completion)
+{
+ int barWidth = 70;
+
+ std::cout << "[";
+ int pos = barWidth * progress;
+ for (int i = 0; i < barWidth; ++i) {
+ if (i < pos) std::cout << "=";
+ else if (i == pos) std::cout << ">";
+ else std::cout << " ";
+ }
+ std::cout << "] "
+ << int(progress * 100.0)
+ << "%, E = "
+ << std::setprecision(3)
+ << error_estimate
+ << ", time to completion: "
+ << estimated_time_to_completion.count()
+ << " seconds, estimate: "
+ << std::setprecision(5)
+ << current_estimate
+ << " \r";
+
+ std::cout.flush();
+}
+
+int main()
+{
+ double exact = 1.3932039296856768591842462603255;
+ double A = 1.0 / boost::math::pow<3>(boost::math::constants::pi<double>());
+ auto g = [&](std::vector<double> const & x)
+ {
+ return A / (1.0 - cos(x[0])*cos(x[1])*cos(x[2]));
+ };
+ vector<pair<double, double>> bounds{{0, boost::math::constants::pi<double>() }, {0, boost::math::constants::pi<double>() }, {0, boost::math::constants::pi<double>() }};
+ naive_monte_carlo<double, decltype(g)> mc(g, bounds, 0.001);
+
+ auto task = mc.integrate();
+
+ int s = 0;
+ std::cout << "Hit ctrl-c to cancel.\n";
+ while (task.wait_for(std::chrono::seconds(1)) != std::future_status::ready)
+ {
+ display_progress(mc.progress(),
+ mc.current_error_estimate(),
+ mc.current_estimate(),
+ mc.estimated_time_to_completion());
+ // TODO: The following shows that cancellation works,
+ // but it would be nice to show how it works with a ctrl-c signal handler.
+ if (s++ > 25){
+ mc.cancel();
+ std::cout << "\nCancelling because this is too slow!\n";
+ }
+ }
+ double y = task.get();
+ display_progress(mc.progress(),
+ mc.current_error_estimate(),
+ mc.current_estimate(),
+ mc.estimated_time_to_completion());
+ std::cout << std::setprecision(std::numeric_limits<double>::digits10) << std::fixed;
+ std::cout << "\nFinal value: " << y << std::endl;
+ std::cout << "Exact : " << exact << std::endl;
+ std::cout << "Final error estimate: " << mc.current_error_estimate() << std::endl;
+ std::cout << "Actual error : " << abs(y - exact) << std::endl;
+ std::cout << "Function calls: " << mc.calls() << std::endl;
+ std::cout << "Is this good enough? [y/N] ";
+ bool goodenough = true;
+ std::string line;
+ std::getline(std::cin, line);
+ if (line[0] != 'y')
+ {
+ goodenough = false;
+ }
+ double new_error = -1;
+ if (!goodenough)
+ {
+ std::cout << "What is the new target error? ";
+ std::getline(std::cin, line);
+ new_error = atof(line.c_str());
+ if (new_error >= mc.current_error_estimate())
+ {
+ std::cout << "That error bound is already satisfied.\n";
+ return 0;
+ }
+ }
+ if (new_error > 0)
+ {
+ mc.update_target_error(new_error);
+ auto task = mc.integrate();
+ std::cout << "Hit ctrl-c to cancel.\n";
+ while (task.wait_for(std::chrono::seconds(1)) != std::future_status::ready)
+ {
+ display_progress(mc.progress(),
+ mc.current_error_estimate(),
+ mc.current_estimate(),
+ mc.estimated_time_to_completion());
+ }
+ double y = task.get();
+ display_progress(mc.progress(),
+ mc.current_error_estimate(),
+ mc.current_estimate(),
+ mc.estimated_time_to_completion());
+ std::cout << std::setprecision(std::numeric_limits<double>::digits10) << std::fixed;
+ std::cout << "\nFinal value: " << y << std::endl;
+ std::cout << "Exact : " << exact << std::endl;
+ std::cout << "Final error estimate: " << mc.current_error_estimate() << std::endl;
+ std::cout << "Actual error : " << abs(y - exact) << std::endl;
+ std::cout << "Function calls: " << mc.calls() << std::endl;
+ }
+}
diff --git a/src/boost/libs/math/example/nc_chi_sq_example.cpp b/src/boost/libs/math/example/nc_chi_sq_example.cpp
new file mode 100644
index 000000000..75bfa9443
--- /dev/null
+++ b/src/boost/libs/math/example/nc_chi_sq_example.cpp
@@ -0,0 +1,115 @@
+// Copyright John Maddock 2008
+// Copyright Paul A. Bristow 2010, 2013
+// 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)
+
+// Caution: this file contains Quickbook markup as well as code
+// and comments, don't change any of the special comment markups!
+
+//[nccs_eg
+
+/*`
+
+This example computes a table of the power of the [chi][super 2]
+test at the 5% significance level, for various degrees of freedom
+and non-centrality parameters. The table is deliberately the same
+as Table 6 from "The Non-Central [chi][super 2] and F-Distributions and
+their applications.", P. B. Patnaik, Biometrika, Vol. 36, No. 1/2 (June 1949),
+202-232.
+
+First we need some includes to access the non-central chi squared distribution
+(and some basic std output of course).
+
+*/
+
+#include <boost/math/distributions/non_central_chi_squared.hpp>
+using boost::math::chi_squared;
+using boost::math::non_central_chi_squared;
+
+#include <iostream>
+using std::cout; using std::endl;
+using std::setprecision;
+
+int main()
+{
+ /*`
+ Create a table of the power of the [chi][super 2] test at
+ 5% significance level, start with a table header:
+ */
+ cout << "[table\n[[[nu]]";
+ for(int lam = 2; lam <= 20; lam += 2)
+ {
+ cout << "[[lambda]=" << lam << "]";
+ }
+ cout << "]\n";
+
+ /*`
+ (Note: the enclosing [] brackets are to format as a table in Boost.Quickbook).
+
+ Enumerate the rows and columns and print the power of the test
+ for each table cell:
+ */
+
+ for(int n = 2; n <= 20; ++n)
+ {
+ cout << "[[" << n << "]";
+ for(int lam = 2; lam <= 20; lam += 2)
+ {
+ /*`
+ Calculate the [chi][super 2] statistic for a 5% significance:
+ */
+ double cs = quantile(complement(chi_squared(n), 0.05));
+ /*`
+ The power of the test is given by the complement of the CDF
+ of the non-central [chi][super 2] distribution:
+ */
+ double beta = cdf(complement(non_central_chi_squared(n, lam), cs));
+ /*`
+ Then output the cell value:
+ */
+ cout << "[" << setprecision(3) << beta << "]";
+ }
+ cout << "]" << endl;
+ }
+ cout << "]" << endl;
+}
+
+/*`
+The output from this program is a table in Boost.Quickbook format as shown below.
+
+We can interpret this as follows - for example if [nu]=10 and [lambda]=10
+then the power of the test is 0.542 - so we have only a 54% chance of
+correctly detecting that our null hypothesis is false, and a 46% chance
+of incurring a type II error (failing to reject the null hypothesis when
+it is in fact false):
+
+[table
+[[[nu]][[lambda]=2][[lambda]=4][[lambda]=6][[lambda]=8][[lambda]=10][[lambda]=12][[lambda]=14][[lambda]=16][[lambda]=18][[lambda]=20]]
+[[2][0.226][0.415][0.584][0.718][0.815][0.883][0.928][0.957][0.974][0.985]]
+[[3][0.192][0.359][0.518][0.654][0.761][0.84][0.896][0.934][0.959][0.975]]
+[[4][0.171][0.32][0.47][0.605][0.716][0.802][0.866][0.912][0.943][0.964]]
+[[5][0.157][0.292][0.433][0.564][0.677][0.769][0.839][0.89][0.927][0.952]]
+[[6][0.146][0.27][0.403][0.531][0.644][0.738][0.813][0.869][0.911][0.94]]
+[[7][0.138][0.252][0.378][0.502][0.614][0.71][0.788][0.849][0.895][0.928]]
+[[8][0.131][0.238][0.357][0.477][0.588][0.685][0.765][0.829][0.879][0.915]]
+[[9][0.125][0.225][0.339][0.454][0.564][0.661][0.744][0.811][0.863][0.903]]
+[[10][0.121][0.215][0.323][0.435][0.542][0.64][0.723][0.793][0.848][0.891]]
+[[11][0.117][0.206][0.309][0.417][0.523][0.62][0.704][0.775][0.833][0.878]]
+[[12][0.113][0.198][0.297][0.402][0.505][0.601][0.686][0.759][0.818][0.866]]
+[[13][0.11][0.191][0.286][0.387][0.488][0.584][0.669][0.743][0.804][0.854]]
+[[14][0.108][0.185][0.276][0.374][0.473][0.567][0.653][0.728][0.791][0.842]]
+[[15][0.105][0.179][0.267][0.362][0.459][0.552][0.638][0.713][0.777][0.83]]
+[[16][0.103][0.174][0.259][0.351][0.446][0.538][0.623][0.699][0.764][0.819]]
+[[17][0.101][0.169][0.251][0.341][0.434][0.525][0.609][0.686][0.752][0.807]]
+[[18][0.0992][0.165][0.244][0.332][0.423][0.512][0.596][0.673][0.74][0.796]]
+[[19][0.0976][0.161][0.238][0.323][0.412][0.5][0.584][0.66][0.728][0.786]]
+[[20][0.0961][0.158][0.232][0.315][0.402][0.489][0.572][0.648][0.716][0.775]]
+]
+
+See [@../../example/nc_chi_sq_example.cpp nc_chi_sq_example.cpp] for the full C++ source code.
+
+*/
+
+//]
diff --git a/src/boost/libs/math/example/neg_binom_confidence_limits.cpp b/src/boost/libs/math/example/neg_binom_confidence_limits.cpp
new file mode 100644
index 000000000..6cca70cb6
--- /dev/null
+++ b/src/boost/libs/math/example/neg_binom_confidence_limits.cpp
@@ -0,0 +1,178 @@
+// neg_binomial_confidence_limits.cpp
+
+// Copyright John Maddock 2006
+// Copyright Paul A. Bristow 2007, 2010
+// 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)
+
+// Caution: this file contains quickbook markup as well as code
+// and comments, don't change any of the special comment markups!
+
+//[neg_binomial_confidence_limits
+
+/*`
+
+First we need some includes to access the negative binomial distribution
+(and some basic std output of course).
+
+*/
+
+#include <boost/math/distributions/negative_binomial.hpp>
+using boost::math::negative_binomial;
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::setprecision;
+using std::setw; using std::left; using std::fixed; using std::right;
+
+/*`
+First define a table of significance levels: these are the
+probabilities that the true occurrence frequency lies outside the calculated
+interval:
+*/
+
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+
+/*`
+Confidence value as % is (1 - alpha) * 100, so alpha 0.05 == 95% confidence
+that the true occurrence frequency lies *inside* the calculated interval.
+
+We need a function to calculate and print confidence limits
+for an observed frequency of occurrence
+that follows a negative binomial distribution.
+
+*/
+
+void confidence_limits_on_frequency(unsigned trials, unsigned successes)
+{
+ // trials = Total number of trials.
+ // successes = Total number of observed successes.
+ // failures = trials - successes.
+ // success_fraction = successes /trials.
+ // Print out general info:
+ cout <<
+ "______________________________________________\n"
+ "2-Sided Confidence Limits For Success Fraction\n"
+ "______________________________________________\n\n";
+ cout << setprecision(7);
+ cout << setw(40) << left << "Number of trials" << " = " << trials << "\n";
+ cout << setw(40) << left << "Number of successes" << " = " << successes << "\n";
+ cout << setw(40) << left << "Number of failures" << " = " << trials - successes << "\n";
+ cout << setw(40) << left << "Observed frequency of occurrence" << " = " << double(successes) / trials << "\n";
+
+ // Print table header:
+ cout << "\n\n"
+ "___________________________________________\n"
+ "Confidence Lower Upper\n"
+ " Value (%) Limit Limit\n"
+ "___________________________________________\n";
+
+
+/*`
+And now for the important part - the bounds themselves.
+For each value of /alpha/, we call `find_lower_bound_on_p` and
+`find_upper_bound_on_p` to obtain lower and upper bounds respectively.
+Note that since we are calculating a two-sided interval,
+we must divide the value of alpha in two. Had we been calculating a
+single-sided interval, for example: ['"Calculate a lower bound so that we are P%
+sure that the true occurrence frequency is greater than some value"]
+then we would *not* have divided by two.
+*/
+
+ // Now print out the upper and lower limits for the alpha table values.
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // Calculate bounds:
+ double lower = negative_binomial::find_lower_bound_on_p(trials, successes, alpha[i]/2);
+ double upper = negative_binomial::find_upper_bound_on_p(trials, successes, alpha[i]/2);
+ // Print limits:
+ cout << fixed << setprecision(5) << setw(15) << right << lower;
+ cout << fixed << setprecision(5) << setw(15) << right << upper << endl;
+ }
+ cout << endl;
+} // void confidence_limits_on_frequency(unsigned trials, unsigned successes)
+
+/*`
+
+And then call confidence_limits_on_frequency with increasing numbers of trials,
+but always the same success fraction 0.1, or 1 in 10.
+
+*/
+
+int main()
+{
+ confidence_limits_on_frequency(20, 2); // 20 trials, 2 successes, 2 in 20, = 1 in 10 = 0.1 success fraction.
+ confidence_limits_on_frequency(200, 20); // More trials, but same 0.1 success fraction.
+ confidence_limits_on_frequency(2000, 200); // Many more trials, but same 0.1 success fraction.
+
+ return 0;
+} // int main()
+
+//] [/negative_binomial_confidence_limits_eg end of Quickbook in C++ markup]
+
+/*
+
+______________________________________________
+2-Sided Confidence Limits For Success Fraction
+______________________________________________
+Number of trials = 20
+Number of successes = 2
+Number of failures = 18
+Observed frequency of occurrence = 0.1
+___________________________________________
+Confidence Lower Upper
+ Value (%) Limit Limit
+___________________________________________
+ 50.000 0.04812 0.13554
+ 75.000 0.03078 0.17727
+ 90.000 0.01807 0.22637
+ 95.000 0.01235 0.26028
+ 99.000 0.00530 0.33111
+ 99.900 0.00164 0.41802
+ 99.990 0.00051 0.49202
+ 99.999 0.00016 0.55574
+______________________________________________
+2-Sided Confidence Limits For Success Fraction
+______________________________________________
+Number of trials = 200
+Number of successes = 20
+Number of failures = 180
+Observed frequency of occurrence = 0.1000000
+___________________________________________
+Confidence Lower Upper
+ Value (%) Limit Limit
+___________________________________________
+ 50.000 0.08462 0.11350
+ 75.000 0.07580 0.12469
+ 90.000 0.06726 0.13695
+ 95.000 0.06216 0.14508
+ 99.000 0.05293 0.16170
+ 99.900 0.04343 0.18212
+ 99.990 0.03641 0.20017
+ 99.999 0.03095 0.21664
+______________________________________________
+2-Sided Confidence Limits For Success Fraction
+______________________________________________
+Number of trials = 2000
+Number of successes = 200
+Number of failures = 1800
+Observed frequency of occurrence = 0.1000000
+___________________________________________
+Confidence Lower Upper
+ Value (%) Limit Limit
+___________________________________________
+ 50.000 0.09536 0.10445
+ 75.000 0.09228 0.10776
+ 90.000 0.08916 0.11125
+ 95.000 0.08720 0.11352
+ 99.000 0.08344 0.11802
+ 99.900 0.07921 0.12336
+ 99.990 0.07577 0.12795
+ 99.999 0.07282 0.13206
+*/
+
diff --git a/src/boost/libs/math/example/neg_binomial_sample_sizes.cpp b/src/boost/libs/math/example/neg_binomial_sample_sizes.cpp
new file mode 100644
index 000000000..d01089e9d
--- /dev/null
+++ b/src/boost/libs/math/example/neg_binomial_sample_sizes.cpp
@@ -0,0 +1,209 @@
+// neg_binomial_sample_sizes.cpp
+
+// Copyright John Maddock 2006
+// Copyright Paul A. Bristow 2007, 2010
+
+// 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)
+
+#include <boost/math/distributions/negative_binomial.hpp>
+using boost::math::negative_binomial;
+
+// Default RealType is double so this permits use of:
+double find_minimum_number_of_trials(
+double k, // number of failures (events), k >= 0.
+double p, // fraction of trails for which event occurs, 0 <= p <= 1.
+double probability); // probability threshold, 0 <= probability <= 1.
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::fixed;
+using std::right;
+#include <iomanip>
+using std::setprecision;
+using std::setw;
+
+//[neg_binomial_sample_sizes
+
+/*`
+It centres around a routine that prints out a table of
+minimum sample sizes (number of trials) for various probability thresholds:
+*/
+ void find_number_of_trials(double failures, double p);
+/*`
+First define a table of significance levels: these are the maximum
+acceptable probability that /failure/ or fewer events will be observed.
+*/
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+/*`
+Confidence value as % is (1 - alpha) * 100, so alpha 0.05 == 95% confidence
+that the desired number of failures will be observed.
+The values range from a very low 0.5 or 50% confidence up to an extremely high
+confidence of 99.999.
+
+Much of the rest of the program is pretty-printing, the important part
+is in the calculation of minimum number of trials required for each
+value of alpha using:
+
+ (int)ceil(negative_binomial::find_minimum_number_of_trials(failures, p, alpha[i]);
+
+find_minimum_number_of_trials returns a double,
+so `ceil` rounds this up to ensure we have an integral minimum number of trials.
+*/
+
+void find_number_of_trials(double failures, double p)
+{
+ // trials = number of trials
+ // failures = number of failures before achieving required success(es).
+ // p = success fraction (0 <= p <= 1.).
+ //
+ // Calculate how many trials we need to ensure the
+ // required number of failures DOES exceed "failures".
+
+ cout << "\n""Target number of failures = " << (int)failures;
+ cout << ", Success fraction = " << fixed << setprecision(1) << 100 * p << "%" << endl;
+ // Print table header:
+ cout << "____________________________\n"
+ "Confidence Min Number\n"
+ " Value (%) Of Trials \n"
+ "____________________________\n";
+ // Now print out the data for the alpha table values.
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ { // Confidence values %:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]) << " "
+ // find_minimum_number_of_trials
+ << setw(6) << right
+ << (int)ceil(negative_binomial::find_minimum_number_of_trials(failures, p, alpha[i]))
+ << endl;
+ }
+ cout << endl;
+} // void find_number_of_trials(double failures, double p)
+
+/*` finally we can produce some tables of minimum trials for the chosen confidence levels:
+*/
+
+int main()
+{
+ find_number_of_trials(5, 0.5);
+ find_number_of_trials(50, 0.5);
+ find_number_of_trials(500, 0.5);
+ find_number_of_trials(50, 0.1);
+ find_number_of_trials(500, 0.1);
+ find_number_of_trials(5, 0.9);
+
+ return 0;
+} // int main()
+
+//] [/neg_binomial_sample_sizes.cpp end of Quickbook in C++ markup]
+
+/*
+
+Output is:
+Target number of failures = 5, Success fraction = 50.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 11
+ 75.000 14
+ 90.000 17
+ 95.000 18
+ 99.000 22
+ 99.900 27
+ 99.990 31
+ 99.999 36
+
+
+ Target number of failures = 50, Success fraction = 50.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 101
+ 75.000 109
+ 90.000 115
+ 95.000 119
+ 99.000 128
+ 99.900 137
+ 99.990 146
+ 99.999 154
+
+
+ Target number of failures = 500, Success fraction = 50.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 1001
+ 75.000 1023
+ 90.000 1043
+ 95.000 1055
+ 99.000 1078
+ 99.900 1104
+ 99.990 1126
+ 99.999 1146
+
+
+ Target number of failures = 50, Success fraction = 10.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 56
+ 75.000 58
+ 90.000 60
+ 95.000 61
+ 99.000 63
+ 99.900 66
+ 99.990 68
+ 99.999 71
+
+
+ Target number of failures = 500, Success fraction = 10.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 556
+ 75.000 562
+ 90.000 567
+ 95.000 570
+ 99.000 576
+ 99.900 583
+ 99.990 588
+ 99.999 594
+
+
+ Target number of failures = 5, Success fraction = 90.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 57
+ 75.000 73
+ 90.000 91
+ 95.000 103
+ 99.000 127
+ 99.900 159
+ 99.990 189
+ 99.999 217
+
+
+ Target number of failures = 5, Success fraction = 95.0%
+ ____________________________
+ Confidence Min Number
+ Value (%) Of Trials
+ ____________________________
+ 50.000 114
+ 75.000 148
+ 90.000 184
+ 95.000 208
+ 99.000 259
+ 99.900 324
+ 99.990 384
+ 99.999 442
+
+*/
diff --git a/src/boost/libs/math/example/negative_binomial_example1.cpp b/src/boost/libs/math/example/negative_binomial_example1.cpp
new file mode 100644
index 000000000..92fe48ce2
--- /dev/null
+++ b/src/boost/libs/math/example/negative_binomial_example1.cpp
@@ -0,0 +1,513 @@
+// negative_binomial_example1.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+// Example 1 of using negative_binomial distribution.
+
+//[negative_binomial_eg1_1
+
+/*`
+Based on [@http://en.wikipedia.org/wiki/Negative_binomial_distribution
+a problem by Dr. Diane Evans,
+Professor of Mathematics at Rose-Hulman Institute of Technology].
+
+Pat is required to sell candy bars to raise money for the 6th grade field trip.
+There are thirty houses in the neighborhood,
+and Pat is not supposed to return home until five candy bars have been sold.
+So the child goes door to door, selling candy bars.
+At each house, there is a 0.4 probability (40%) of selling one candy bar
+and a 0.6 probability (60%) of selling nothing.
+
+What is the probability mass (density) function (pdf) for selling the last (fifth)
+candy bar at the nth house?
+
+The Negative Binomial(r, p) distribution describes the probability of k failures
+and r successes in k+r Bernoulli(p) trials with success on the last trial.
+(A [@http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli trial]
+is one with only two possible outcomes, success of failure,
+and p is the probability of success).
+See also [@ http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli distribution]
+and [@http://www.math.uah.edu/stat/bernoulli/Introduction.xhtml Bernoulli applications].
+
+In this example, we will deliberately produce a variety of calculations
+and outputs to demonstrate the ways that the negative binomial distribution
+can be implemented with this library: it is also deliberately over-commented.
+
+First we need to #define macros to control the error and discrete handling policies.
+For this simple example, we want to avoid throwing
+an exception (the default policy) and just return infinity.
+We want to treat the distribution as if it was continuous,
+so we choose a discrete_quantile policy of real,
+rather than the default policy integer_round_outwards.
+*/
+#define BOOST_MATH_OVERFLOW_ERROR_POLICY ignore_error
+#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real
+/*`
+After that we need some includes to provide easy access to the negative binomial distribution,
+[caution It is vital to #include distributions etc *after* the above #defines]
+and we need some std library iostream, of course.
+*/
+#include <boost/math/distributions/negative_binomial.hpp>
+ // for negative_binomial_distribution
+ using boost::math::negative_binomial; // typedef provides default type is double.
+ using ::boost::math::pdf; // Probability mass function.
+ using ::boost::math::cdf; // Cumulative density function.
+ using ::boost::math::quantile;
+
+#include <iostream>
+ using std::cout; using std::endl;
+ using std::noshowpoint; using std::fixed; using std::right; using std::left;
+#include <iomanip>
+ using std::setprecision; using std::setw;
+
+#include <limits>
+ using std::numeric_limits;
+//] [negative_binomial_eg1_1]
+
+int main()
+{
+ cout <<"Selling candy bars - using the negative binomial distribution."
+ << "\nby Dr. Diane Evans,"
+ "\nProfessor of Mathematics at Rose-Hulman Institute of Technology,"
+ << "\nsee http://en.wikipedia.org/wiki/Negative_binomial_distribution\n"
+ << endl;
+ cout << endl;
+ cout.precision(5);
+ // None of the values calculated have a useful accuracy as great this, but
+ // INF shows wrongly with < 5 !
+ // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=240227
+//[negative_binomial_eg1_2
+/*`
+It is always sensible to use try and catch blocks because defaults policies are to
+throw an exception if anything goes wrong.
+
+A simple catch block (see below) will ensure that you get a
+helpful error message instead of an abrupt program abort.
+*/
+ try
+ {
+/*`
+Selling five candy bars means getting five successes, so successes r = 5.
+The total number of trials (n, in this case, houses visited) this takes is therefore
+ = successes + failures or k + r = k + 5.
+*/
+ double sales_quota = 5; // Pat's sales quota - successes (r).
+/*`
+At each house, there is a 0.4 probability (40%) of selling one candy bar
+and a 0.6 probability (60%) of selling nothing.
+*/
+ double success_fraction = 0.4; // success_fraction (p) - so failure_fraction is 0.6.
+/*`
+The Negative Binomial(r, p) distribution describes the probability of k failures
+and r successes in k+r Bernoulli(p) trials with success on the last trial.
+(A [@http://en.wikipedia.org/wiki/Bernoulli_distribution Bernoulli trial]
+is one with only two possible outcomes, success of failure,
+and p is the probability of success).
+
+We therefore start by constructing a negative binomial distribution
+with parameters sales_quota (required successes) and probability of success.
+*/
+ negative_binomial nb(sales_quota, success_fraction); // type double by default.
+/*`
+To confirm, display the success_fraction & successes parameters of the distribution.
+*/
+ cout << "Pat has a sales per house success rate of " << success_fraction
+ << ".\nTherefore he would, on average, sell " << nb.success_fraction() * 100
+ << " bars after trying 100 houses." << endl;
+
+ int all_houses = 30; // The number of houses on the estate.
+
+ cout << "With a success rate of " << nb.success_fraction()
+ << ", he might expect, on average,\n"
+ "to need to visit about " << success_fraction * all_houses
+ << " houses in order to sell all " << nb.successes() << " bars. " << endl;
+/*`
+[pre
+Pat has a sales per house success rate of 0.4.
+Therefore he would, on average, sell 40 bars after trying 100 houses.
+With a success rate of 0.4, he might expect, on average,
+to need to visit about 12 houses in order to sell all 5 bars.
+]
+
+The random variable of interest is the number of houses
+that must be visited to sell five candy bars,
+so we substitute k = n - 5 into a negative_binomial(5, 0.4)
+and obtain the __pdf of the distribution of houses visited.
+Obviously, the best possible case is that Pat makes sales on all the first five houses.
+
+We calculate this using the pdf function:
+*/
+ cout << "Probability that Pat finishes on the " << sales_quota << "th house is "
+ << pdf(nb, 5 - sales_quota) << endl; // == pdf(nb, 0)
+/*`
+Of course, he could not finish on fewer than 5 houses because he must sell 5 candy bars.
+So the 5th house is the first that he could possibly finish on.
+
+To finish on or before the 8th house, Pat must finish at the 5th, 6th, 7th or 8th house.
+The probability that he will finish on *exactly* ( == ) on any house
+is the Probability Density Function (pdf).
+*/
+ cout << "Probability that Pat finishes on the 6th house is "
+ << pdf(nb, 6 - sales_quota) << endl;
+ cout << "Probability that Pat finishes on the 7th house is "
+ << pdf(nb, 7 - sales_quota) << endl;
+ cout << "Probability that Pat finishes on the 8th house is "
+ << pdf(nb, 8 - sales_quota) << endl;
+/*`
+[pre
+Probability that Pat finishes on the 6th house is 0.03072
+Probability that Pat finishes on the 7th house is 0.055296
+Probability that Pat finishes on the 8th house is 0.077414
+]
+
+The sum of the probabilities for these houses is the Cumulative Distribution Function (cdf).
+We can calculate it by adding the individual probabilities.
+*/
+ cout << "Probability that Pat finishes on or before the 8th house is sum "
+ "\n" << "pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = "
+ // Sum each of the mass/density probabilities for houses sales_quota = 5, 6, 7, & 8.
+ << pdf(nb, 5 - sales_quota) // 0 failures.
+ + pdf(nb, 6 - sales_quota) // 1 failure.
+ + pdf(nb, 7 - sales_quota) // 2 failures.
+ + pdf(nb, 8 - sales_quota) // 3 failures.
+ << endl;
+/*`[pre
+pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = 0.17367
+]
+
+Or, usually better, by using the negative binomial *cumulative* distribution function.
+*/
+ cout << "\nProbability of selling his quota of " << sales_quota
+ << " bars\non or before the " << 8 << "th house is "
+ << cdf(nb, 8 - sales_quota) << endl;
+/*`[pre
+Probability of selling his quota of 5 bars on or before the 8th house is 0.17367
+]*/
+ cout << "\nProbability that Pat finishes exactly on the 10th house is "
+ << pdf(nb, 10 - sales_quota) << endl;
+ cout << "\nProbability of selling his quota of " << sales_quota
+ << " bars\non or before the " << 10 << "th house is "
+ << cdf(nb, 10 - sales_quota) << endl;
+/*`
+[pre
+Probability that Pat finishes exactly on the 10th house is 0.10033
+Probability of selling his quota of 5 bars on or before the 10th house is 0.3669
+]*/
+ cout << "Probability that Pat finishes exactly on the 11th house is "
+ << pdf(nb, 11 - sales_quota) << endl;
+ cout << "\nProbability of selling his quota of " << sales_quota
+ << " bars\non or before the " << 11 << "th house is "
+ << cdf(nb, 11 - sales_quota) << endl;
+/*`[pre
+Probability that Pat finishes on the 11th house is 0.10033
+Probability of selling his quota of 5 candy bars
+on or before the 11th house is 0.46723
+]*/
+ cout << "Probability that Pat finishes exactly on the 12th house is "
+ << pdf(nb, 12 - sales_quota) << endl;
+
+ cout << "\nProbability of selling his quota of " << sales_quota
+ << " bars\non or before the " << 12 << "th house is "
+ << cdf(nb, 12 - sales_quota) << endl;
+/*`[pre
+Probability that Pat finishes on the 12th house is 0.094596
+Probability of selling his quota of 5 candy bars
+on or before the 12th house is 0.56182
+]
+Finally consider the risk of Pat not selling his quota of 5 bars
+even after visiting all the houses.
+Calculate the probability that he /will/ sell on
+or before the last house:
+Calculate the probability that he would sell all his quota on the very last house.
+*/
+ cout << "Probability that Pat finishes on the " << all_houses
+ << " house is " << pdf(nb, all_houses - sales_quota) << endl;
+/*`
+Probability of selling his quota of 5 bars on the 30th house is
+[pre
+Probability that Pat finishes on the 30 house is 0.00069145
+]
+when he'd be very unlucky indeed!
+
+What is the probability that Pat exhausts all 30 houses in the neighborhood,
+and *still* doesn't sell the required 5 candy bars?
+*/
+ cout << "\nProbability of selling his quota of " << sales_quota
+ << " bars\non or before the " << all_houses << "th house is "
+ << cdf(nb, all_houses - sales_quota) << endl;
+/*`
+[pre
+Probability of selling his quota of 5 bars
+on or before the 30th house is 0.99849
+]
+
+So the risk of failing even after visiting all the houses is 1 - this probability,
+ ``1 - cdf(nb, all_houses - sales_quota``
+But using this expression may cause serious inaccuracy,
+so it would be much better to use the complement of the cdf:
+So the risk of failing even at, or after, the 31th (non-existent) houses is 1 - this probability,
+ ``1 - cdf(nb, all_houses - sales_quota)``
+But using this expression may cause serious inaccuracy.
+So it would be much better to use the __complement of the cdf (see __why_complements).
+*/
+ cout << "\nProbability of failing to sell his quota of " << sales_quota
+ << " bars\neven after visiting all " << all_houses << " houses is "
+ << cdf(complement(nb, all_houses - sales_quota)) << endl;
+/*`
+[pre
+Probability of failing to sell his quota of 5 bars
+even after visiting all 30 houses is 0.0015101
+]
+We can also use the quantile (percentile), the inverse of the cdf, to
+predict which house Pat will finish on. So for the 8th house:
+*/
+ double p = cdf(nb, (8 - sales_quota));
+ cout << "Probability of meeting sales quota on or before 8th house is "<< p << endl;
+/*`
+[pre
+Probability of meeting sales quota on or before 8th house is 0.174
+]
+*/
+ cout << "If the confidence of meeting sales quota is " << p
+ << ", then the finishing house is " << quantile(nb, p) + sales_quota << endl;
+
+ cout<< " quantile(nb, p) = " << quantile(nb, p) << endl;
+/*`
+[pre
+If the confidence of meeting sales quota is 0.17367, then the finishing house is 8
+]
+Demanding absolute certainty that all 5 will be sold,
+implies an infinite number of trials.
+(Of course, there are only 30 houses on the estate,
+so he can't ever be *certain* of selling his quota).
+*/
+ cout << "If the confidence of meeting sales quota is " << 1.
+ << ", then the finishing house is " << quantile(nb, 1) + sales_quota << endl;
+ // 1.#INF == infinity.
+/*`[pre
+If the confidence of meeting sales quota is 1, then the finishing house is 1.#INF
+]
+And similarly for a few other probabilities:
+*/
+ cout << "If the confidence of meeting sales quota is " << 0.
+ << ", then the finishing house is " << quantile(nb, 0.) + sales_quota << endl;
+
+ cout << "If the confidence of meeting sales quota is " << 0.5
+ << ", then the finishing house is " << quantile(nb, 0.5) + sales_quota << endl;
+
+ cout << "If the confidence of meeting sales quota is " << 1 - 0.00151 // 30 th
+ << ", then the finishing house is " << quantile(nb, 1 - 0.00151) + sales_quota << endl;
+/*`
+[pre
+If the confidence of meeting sales quota is 0, then the finishing house is 5
+If the confidence of meeting sales quota is 0.5, then the finishing house is 11.337
+If the confidence of meeting sales quota is 0.99849, then the finishing house is 30
+]
+
+Notice that because we chose a discrete quantile policy of real,
+the result can be an 'unreal' fractional house.
+
+If the opposite is true, we don't want to assume any confidence, then this is tantamount
+to assuming that all the first sales_quota trials will be successful sales.
+*/
+ cout << "If confidence of meeting quota is zero\n(we assume all houses are successful sales)"
+ ", then finishing house is " << sales_quota << endl;
+/*`
+[pre
+If confidence of meeting quota is zero (we assume all houses are successful sales), then finishing house is 5
+If confidence of meeting quota is 0, then finishing house is 5
+]
+We can list quantiles for a few probabilities:
+*/
+
+ double ps[] = {0., 0.001, 0.01, 0.05, 0.1, 0.5, 0.9, 0.95, 0.99, 0.999, 1.};
+ // Confidence as fraction = 1-alpha, as percent = 100 * (1-alpha[i]) %
+ cout.precision(3);
+ for (unsigned i = 0; i < sizeof(ps)/sizeof(ps[0]); i++)
+ {
+ cout << "If confidence of meeting quota is " << ps[i]
+ << ", then finishing house is " << quantile(nb, ps[i]) + sales_quota
+ << endl;
+ }
+
+/*`
+[pre
+If confidence of meeting quota is 0, then finishing house is 5
+If confidence of meeting quota is 0.001, then finishing house is 5
+If confidence of meeting quota is 0.01, then finishing house is 5
+If confidence of meeting quota is 0.05, then finishing house is 6.2
+If confidence of meeting quota is 0.1, then finishing house is 7.06
+If confidence of meeting quota is 0.5, then finishing house is 11.3
+If confidence of meeting quota is 0.9, then finishing house is 17.8
+If confidence of meeting quota is 0.95, then finishing house is 20.1
+If confidence of meeting quota is 0.99, then finishing house is 24.8
+If confidence of meeting quota is 0.999, then finishing house is 31.1
+If confidence of meeting quota is 1, then finishing house is 1.#INF
+]
+
+We could have applied a ceil function to obtain a 'worst case' integer value for house.
+``ceil(quantile(nb, ps[i]))``
+
+Or, if we had used the default discrete quantile policy, integer_outside, by omitting
+``#define BOOST_MATH_DISCRETE_QUANTILE_POLICY real``
+we would have achieved the same effect.
+
+The real result gives some suggestion which house is most likely.
+For example, compare the real and integer_outside for 95% confidence.
+
+[pre
+If confidence of meeting quota is 0.95, then finishing house is 20.1
+If confidence of meeting quota is 0.95, then finishing house is 21
+]
+The real value 20.1 is much closer to 20 than 21, so integer_outside is pessimistic.
+We could also use integer_round_nearest policy to suggest that 20 is more likely.
+
+Finally, we can tabulate the probability for the last sale being exactly on each house.
+*/
+ cout << "\nHouse for " << sales_quota << "th (last) sale. Probability (%)" << endl;
+ cout.precision(5);
+ for (int i = (int)sales_quota; i < all_houses+1; i++)
+ {
+ cout << left << setw(3) << i << " " << setw(8) << cdf(nb, i - sales_quota) << endl;
+ }
+ cout << endl;
+/*`
+[pre
+House for 5 th (last) sale. Probability (%)
+5 0.01024
+6 0.04096
+7 0.096256
+8 0.17367
+9 0.26657
+10 0.3669
+11 0.46723
+12 0.56182
+13 0.64696
+14 0.72074
+15 0.78272
+16 0.83343
+17 0.874
+18 0.90583
+19 0.93039
+20 0.94905
+21 0.96304
+22 0.97342
+23 0.98103
+24 0.98655
+25 0.99053
+26 0.99337
+27 0.99539
+28 0.99681
+29 0.9978
+30 0.99849
+]
+
+As noted above, using a catch block is always a good idea, even if you do not expect to use it.
+*/
+ }
+ catch(const std::exception& e)
+ { // Since we have set an overflow policy of ignore_error,
+ // an overflow exception should never be thrown.
+ std::cout << "\nMessage from thrown exception was:\n " << e.what() << std::endl;
+/*`
+For example, without a ignore domain error policy, if we asked for ``pdf(nb, -1)`` for example, we would get:
+[pre
+Message from thrown exception was:
+ Error in function boost::math::pdf(const negative_binomial_distribution<double>&, double):
+ Number of failures argument is -1, but must be >= 0 !
+]
+*/
+//] [/ negative_binomial_eg1_2]
+ }
+ return 0;
+} // int main()
+
+
+/*
+
+Output is:
+
+Selling candy bars - using the negative binomial distribution.
+by Dr. Diane Evans,
+Professor of Mathematics at Rose-Hulman Institute of Technology,
+see http://en.wikipedia.org/wiki/Negative_binomial_distribution
+Pat has a sales per house success rate of 0.4.
+Therefore he would, on average, sell 40 bars after trying 100 houses.
+With a success rate of 0.4, he might expect, on average,
+to need to visit about 12 houses in order to sell all 5 bars.
+Probability that Pat finishes on the 5th house is 0.01024
+Probability that Pat finishes on the 6th house is 0.03072
+Probability that Pat finishes on the 7th house is 0.055296
+Probability that Pat finishes on the 8th house is 0.077414
+Probability that Pat finishes on or before the 8th house is sum
+pdf(sales_quota) + pdf(6) + pdf(7) + pdf(8) = 0.17367
+Probability of selling his quota of 5 bars
+on or before the 8th house is 0.17367
+Probability that Pat finishes exactly on the 10th house is 0.10033
+Probability of selling his quota of 5 bars
+on or before the 10th house is 0.3669
+Probability that Pat finishes exactly on the 11th house is 0.10033
+Probability of selling his quota of 5 bars
+on or before the 11th house is 0.46723
+Probability that Pat finishes exactly on the 12th house is 0.094596
+Probability of selling his quota of 5 bars
+on or before the 12th house is 0.56182
+Probability that Pat finishes on the 30 house is 0.00069145
+Probability of selling his quota of 5 bars
+on or before the 30th house is 0.99849
+Probability of failing to sell his quota of 5 bars
+even after visiting all 30 houses is 0.0015101
+Probability of meeting sales quota on or before 8th house is 0.17367
+If the confidence of meeting sales quota is 0.17367, then the finishing house is 8
+ quantile(nb, p) = 3
+If the confidence of meeting sales quota is 1, then the finishing house is 1.#INF
+If the confidence of meeting sales quota is 0, then the finishing house is 5
+If the confidence of meeting sales quota is 0.5, then the finishing house is 11.337
+If the confidence of meeting sales quota is 0.99849, then the finishing house is 30
+If confidence of meeting quota is zero
+(we assume all houses are successful sales), then finishing house is 5
+If confidence of meeting quota is 0, then finishing house is 5
+If confidence of meeting quota is 0.001, then finishing house is 5
+If confidence of meeting quota is 0.01, then finishing house is 5
+If confidence of meeting quota is 0.05, then finishing house is 6.2
+If confidence of meeting quota is 0.1, then finishing house is 7.06
+If confidence of meeting quota is 0.5, then finishing house is 11.3
+If confidence of meeting quota is 0.9, then finishing house is 17.8
+If confidence of meeting quota is 0.95, then finishing house is 20.1
+If confidence of meeting quota is 0.99, then finishing house is 24.8
+If confidence of meeting quota is 0.999, then finishing house is 31.1
+If confidence of meeting quota is 1, then finishing house is 1.#J
+House for 5th (last) sale. Probability (%)
+5 0.01024
+6 0.04096
+7 0.096256
+8 0.17367
+9 0.26657
+10 0.3669
+11 0.46723
+12 0.56182
+13 0.64696
+14 0.72074
+15 0.78272
+16 0.83343
+17 0.874
+18 0.90583
+19 0.93039
+20 0.94905
+21 0.96304
+22 0.97342
+23 0.98103
+24 0.98655
+25 0.99053
+26 0.99337
+27 0.99539
+28 0.99681
+29 0.9978
+30 0.99849
+
+*/
diff --git a/src/boost/libs/math/example/negative_binomial_example2.cpp b/src/boost/libs/math/example/negative_binomial_example2.cpp
new file mode 100644
index 000000000..c1c90916a
--- /dev/null
+++ b/src/boost/libs/math/example/negative_binomial_example2.cpp
@@ -0,0 +1,182 @@
+// negative_binomial_example2.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+// Simple example demonstrating use of the Negative Binomial Distribution.
+
+#include <boost/math/distributions/negative_binomial.hpp>
+ using boost::math::negative_binomial_distribution;
+ using boost::math::negative_binomial; // typedef
+
+// In a sequence of trials or events
+// (Bernoulli, independent, yes or no, succeed or fail)
+// with success_fraction probability p,
+// negative_binomial is the probability that k or fewer failures
+// precede the r th trial's success.
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::setprecision;
+using std::showpoint;
+using std::setw;
+using std::left;
+using std::right;
+#include <limits>
+using std::numeric_limits;
+
+int main()
+{
+ cout << "Negative_binomial distribution - simple example 2" << endl;
+ // Construct a negative binomial distribution with:
+ // 8 successes (r), success fraction (p) 0.25 = 25% or 1 in 4 successes.
+ negative_binomial mynbdist(8, 0.25); // Shorter method using typedef.
+
+ // Display (to check) properties of the distribution just constructed.
+ cout << "mean(mynbdist) = " << mean(mynbdist) << endl; // 24
+ cout << "mynbdist.successes() = " << mynbdist.successes() << endl; // 8
+ // r th successful trial, after k failures, is r + k th trial.
+ cout << "mynbdist.success_fraction() = " << mynbdist.success_fraction() << endl;
+ // success_fraction = failures/successes or k/r = 0.25 or 25%.
+ cout << "mynbdist.percent success = " << mynbdist.success_fraction() * 100 << "%" << endl;
+ // Show as % too.
+ // Show some cumulative distribution function values for failures k = 2 and 8
+ cout << "cdf(mynbdist, 2.) = " << cdf(mynbdist, 2.) << endl; // 0.000415802001953125
+ cout << "cdf(mynbdist, 8.) = " << cdf(mynbdist, 8.) << endl; // 0.027129956288263202
+ cout << "cdf(complement(mynbdist, 8.)) = " << cdf(complement(mynbdist, 8.)) << endl; // 0.9728700437117368
+ // Check that cdf plus its complement is unity.
+ cout << "cdf + complement = " << cdf(mynbdist, 8.) + cdf(complement(mynbdist, 8.)) << endl; // 1
+ // Note: No complement for pdf!
+
+ // Compare cdf with sum of pdfs.
+ double sum = 0.; // Calculate the sum of all the pdfs,
+ int k = 20; // for 20 failures
+ for(signed i = 0; i <= k; ++i)
+ {
+ sum += pdf(mynbdist, double(i));
+ }
+ // Compare with the cdf
+ double cdf8 = cdf(mynbdist, static_cast<double>(k));
+ double diff = sum - cdf8; // Expect the difference to be very small.
+ cout << setprecision(17) << "Sum pdfs = " << sum << ' ' // sum = 0.40025683281803698
+ << ", cdf = " << cdf(mynbdist, static_cast<double>(k)) // cdf = 0.40025683281803687
+ << ", difference = " // difference = 0.50000000000000000
+ << setprecision(1) << diff/ (std::numeric_limits<double>::epsilon() * sum)
+ << " in epsilon units." << endl;
+
+ // Note: Use boost::math::tools::epsilon rather than std::numeric_limits
+ // to cover RealTypes that do not specialize numeric_limits.
+
+//[neg_binomial_example2
+
+ // Print a table of values that can be used to plot
+ // using Excel, or some other superior graphical display tool.
+
+ cout.precision(17); // Use max_digits10 precision, the maximum available for a reference table.
+ cout << showpoint << endl; // include trailing zeros.
+ // This is a maximum possible precision for the type (here double) to suit a reference table.
+ int maxk = static_cast<int>(2. * mynbdist.successes() / mynbdist.success_fraction());
+ // This maxk shows most of the range of interest, probability about 0.0001 to 0.999.
+ cout << "\n"" k pdf cdf""\n" << endl;
+ for (int k = 0; k < maxk; k++)
+ {
+ cout << right << setprecision(17) << showpoint
+ << right << setw(3) << k << ", "
+ << left << setw(25) << pdf(mynbdist, static_cast<double>(k))
+ << left << setw(25) << cdf(mynbdist, static_cast<double>(k))
+ << endl;
+ }
+ cout << endl;
+//] [/ neg_binomial_example2]
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+negative_binomial distribution - simple example 2
+mean(mynbdist) = 24
+mynbdist.successes() = 8
+mynbdist.success_fraction() = 0.25
+mynbdist.percent success = 25%
+cdf(mynbdist, 2.) = 0.000415802001953125
+cdf(mynbdist, 8.) = 0.027129956288263202
+cdf(complement(mynbdist, 8.)) = 0.9728700437117368
+cdf + complement = 1
+Sum pdfs = 0.40025683281803692 , cdf = 0.40025683281803687, difference = 0.25 in epsilon units.
+
+//[neg_binomial_example2_1
+ k pdf cdf
+ 0, 1.5258789062500000e-005 1.5258789062500003e-005
+ 1, 9.1552734375000000e-005 0.00010681152343750000
+ 2, 0.00030899047851562522 0.00041580200195312500
+ 3, 0.00077247619628906272 0.0011882781982421875
+ 4, 0.0015932321548461918 0.0027815103530883789
+ 5, 0.0028678178787231476 0.0056493282318115234
+ 6, 0.0046602040529251142 0.010309532284736633
+ 7, 0.0069903060793876605 0.017299838364124298
+ 8, 0.0098301179241389001 0.027129956288263202
+ 9, 0.013106823898851871 0.040236780187115073
+ 10, 0.016711200471036140 0.056947980658151209
+ 11, 0.020509200578089786 0.077457181236241013
+ 12, 0.024354675686481652 0.10181185692272265
+ 13, 0.028101548869017230 0.12991340579173993
+ 14, 0.031614242477644432 0.16152764826938440
+ 15, 0.034775666725408917 0.19630331499479325
+ 16, 0.037492515688331451 0.23379583068312471
+ 17, 0.039697957787645101 0.27349378847076977
+ 18, 0.041352039362130305 0.31484582783290005
+ 19, 0.042440250924291580 0.35728607875719176
+ 20, 0.042970754060845245 0.40025683281803687
+ 21, 0.042970754060845225 0.44322758687888220
+ 22, 0.042482450037426581 0.48571003691630876
+ 23, 0.041558918514873783 0.52726895543118257
+ 24, 0.040260202311284021 0.56752915774246648
+ 25, 0.038649794218832620 0.60617895196129912
+ 26, 0.036791631035234917 0.64297058299653398
+ 27, 0.034747651533277427 0.67771823452981139
+ 28, 0.032575923312447595 0.71029415784225891
+ 29, 0.030329307911589130 0.74062346575384819
+ 30, 0.028054609818219924 0.76867807557206813
+ 31, 0.025792141284492545 0.79447021685656061
+ 32, 0.023575629142856460 0.81804584599941710
+ 33, 0.021432390129869489 0.83947823612928651
+ 34, 0.019383705779220189 0.85886194190850684
+ 35, 0.017445335201298231 0.87630727710980494
+ 36, 0.015628112784496322 0.89193538989430121
+ 37, 0.013938587078064250 0.90587397697236549
+ 38, 0.012379666154859701 0.91825364312722524
+ 39, 0.010951243136991251 0.92920488626421649
+ 40, 0.0096507830144735539 0.93885566927869002
+ 41, 0.0084738582566109364 0.94732952753530097
+ 42, 0.0074146259745345548 0.95474415350983555
+ 43, 0.0064662435824429246 0.96121039709227851
+ 44, 0.0056212231142827853 0.96683162020656122
+ 45, 0.0048717266990450708 0.97170334690560634
+ 46, 0.0042098073105878630 0.97591315421619418
+ 47, 0.0036275999165703964 0.97954075413276465
+ 48, 0.0031174686783026818 0.98265822281106729
+ 49, 0.0026721160099737302 0.98533033882104104
+ 50, 0.0022846591885275322 0.98761499800956853
+ 51, 0.0019486798960970148 0.98956367790566557
+ 52, 0.0016582516423517923 0.99122192954801736
+ 53, 0.0014079495076571762 0.99262987905567457
+ 54, 0.0011928461106539983 0.99382272516632852
+ 55, 0.0010084971662802015 0.99483122233260868
+ 56, 0.00085091948404891532 0.99568214181665760
+ 57, 0.00071656377604119542 0.99639870559269883
+ 58, 0.00060228420831048650 0.99700098980100937
+ 59, 0.00050530624256557675 0.99750629604357488
+ 60, 0.00042319397814867202 0.99792949002172360
+ 61, 0.00035381791615708398 0.99828330793788067
+ 62, 0.00029532382517950324 0.99857863176306016
+ 63, 0.00024610318764958566 0.99882473495070978
+//] [neg_binomial_example2_1 end of Quickbook]
+
+*/
diff --git a/src/boost/libs/math/example/neumann_zeros_example_1.cpp b/src/boost/libs/math/example/neumann_zeros_example_1.cpp
new file mode 100644
index 000000000..b8042d96a
--- /dev/null
+++ b/src/boost/libs/math/example/neumann_zeros_example_1.cpp
@@ -0,0 +1,85 @@
+
+// Copyright Christopher Kormanyos 2013.
+// Copyright Paul A. Bristow 2013.
+// Copyright John Maddock 2013.
+
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated.
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+#include <iostream>
+#include <limits>
+#include <vector>
+#include <algorithm>
+#include <iomanip>
+#include <iterator>
+
+//[neumann_zeros_example_1
+
+/*`[h5 Calculating zeros of the Neumann function.]
+This example also shows how Boost.Math and Boost.Multiprecision can be combined to provide
+a many decimal digit precision. For 50 decimal digit precision we need to include
+*/
+
+ #include <boost/multiprecision/cpp_dec_float.hpp>
+
+/*`and a `typedef` for `float_type` may be convenient
+(allowing a quick switch to re-compute at built-in `double` or other precision)
+*/
+ typedef boost::multiprecision::cpp_dec_float_50 float_type;
+
+//`To use the functions for finding zeros of the `cyl_neumann` function we need:
+
+ #include <boost/math/special_functions/bessel.hpp>
+//] [/neumann_zerso_example_1]
+
+int main()
+{
+ try
+ {
+ {
+//[neumann_zeros_example_2
+/*`The Neumann (Bessel Y) function zeros are evaluated very similarly:
+*/
+ using boost::math::cyl_neumann_zero;
+ double zn = cyl_neumann_zero(2., 1);
+ std::cout << "cyl_neumann_zero(2., 1) = " << zn << std::endl;
+
+ std::vector<float> nzeros(3); // Space for 3 zeros.
+ cyl_neumann_zero<float>(2.F, 1, nzeros.size(), nzeros.begin());
+
+ std::cout << "cyl_neumann_zero<float>(2.F, 1, ";
+ // Print the zeros to the output stream.
+ std::copy(nzeros.begin(), nzeros.end(),
+ std::ostream_iterator<float>(std::cout, ", "));
+
+ std::cout << "\n""cyl_neumann_zero(static_cast<float_type>(220)/100, 1) = "
+ << cyl_neumann_zero(static_cast<float_type>(220)/100, 1) << std::endl;
+ // 3.6154383428745996706772556069431792744372398748422
+
+//] //[/neumann_zeros_example_2]
+ }
+ }
+ catch (std::exception const& ex)
+ {
+ std::cout << "Thrown exception " << ex.what() << std::endl;
+ }
+} // int main()
+
+/*
+ Output:
+
+cyl_neumann_zero(2., 1) = 3.38424
+cyl_neumann_zero<float>(2.F, 1,
+3.38424
+6.79381
+10.0235
+3.61544
+*/
+
+
diff --git a/src/boost/libs/math/example/nonfinite_facet_simple.cpp b/src/boost/libs/math/example/nonfinite_facet_simple.cpp
new file mode 100644
index 000000000..730228161
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_facet_simple.cpp
@@ -0,0 +1,269 @@
+/** nonfinite_num_facet.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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)
+*
+* This very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' to obtain C99
+* representation of infinity and NaN.
+* (from the original
+* Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A very simple example of using non_finite_num facet for
+C99 standard output of infinity and NaN.
+
+\detail Provided infinity and nan are supported,
+this example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allow output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+This is particularly useful when used with Boost.Serialization so that non-finite NaNs and infinity
+values in text and xml archives can be handled correctly and portably.
+
+*/
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4127) // conditional expression is constant.
+#endif
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+// from Johan Rade Floating Point Utilities.
+
+int main ()
+{
+ std::cout << "Nonfinite_num_facet very simple example." << std::endl;
+
+ if((std::numeric_limits<double>::has_infinity == 0) || (std::numeric_limits<double>::infinity() == 0))
+ {
+ std::cout << "Infinity not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ if((std::numeric_limits<double>::has_quiet_NaN == 0) || (std::numeric_limits<double>::quiet_NaN() == 0))
+ {
+ std::cout << "NaN not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ std::locale default_locale (std::locale::classic ()); // Note the current (default C) locale.
+
+ // Create plus and minus infinity.
+ double plus_infinity = +std::numeric_limits<double>::infinity();
+ double minus_infinity = -std::numeric_limits<double>::infinity();
+
+ // and create a NaN (NotANumber)
+ double NaN = +std::numeric_limits<double>::quiet_NaN ();
+
+ double negated_NaN = (boost::math::changesign)(std::numeric_limits<double>::quiet_NaN ());
+
+
+ // Output the nonfinite values using the current (default C) locale.
+ // The default representations differ from system to system,
+ // for example, using Microsoft compilers, 1.#INF, -1.#INF, and 1.#QNAN,
+ // Linux "inf", "-inf", "nan"
+ cout << "Using C locale" << endl;
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+
+ // Display negated NaN.
+ cout << "negated NaN " << negated_NaN << endl; // "-1.IND" or "-nan".
+
+ // Create a new output locale, and add the nonfinite_num_put facet
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>);
+ // and imbue the cout stream with the new locale.
+ cout.imbue (C99_out_locale);
+
+ // Or for the same effect more concisely:
+ cout.imbue (locale(locale(), new boost::math::nonfinite_num_put<char>));
+
+ // Output using the new locale:
+ cout << "Using C99_out_locale " << endl;
+ cout << "+std::numeric_limits<double>::infinity() = " << plus_infinity << endl;
+ cout << "-std::numeric_limits<double>::infinity() = " << minus_infinity << endl;
+ cout << "+std::numeric_limits<double>::quiet_NaN () = " << NaN << endl;
+ // Expect "inf", "-inf", "nan".
+
+ // Display negated NaN.
+ cout << "negated NaN " << negated_NaN << endl; // Expect "-nan".
+
+ // Create a string with the expected C99 representation of plus infinity.
+ std::string inf = "inf";
+ { // Try to read an infinity value using the default C locale.
+ // Create an input stream which will provide "inf"
+ std::istringstream iss (inf);
+
+ // Create a double ready to take the input,
+ double infinity;
+ // and read "inf" from the stringstream:
+ iss >> infinity;
+
+ // This will not work on all platforms! (Intel-Linux-13.0.1 fails EXIT STATUS: 139)
+ if (! iss)
+ { // Reading infinity went wrong!
+ std::cerr << "C locale input format error!" << std::endl;
+ }
+ } // Using default C locale.
+
+ { // Now retry using C99 facets.
+ // Create a new input locale and add the nonfinite_num_get facet.
+ std::locale C99_in_locale (default_locale, new boost::math::nonfinite_num_get<char>);
+
+ // Create an input stream which will provide "inf".
+ std::istringstream iss (inf);
+ // Imbue the stream with the C99 input locale.
+ iss.imbue (C99_in_locale);
+
+ // Create a double ready to take the input,
+ double infinity;
+ // and read from the stringstream:
+ iss >> infinity;
+
+ if (! iss)
+ { // Reading infinity went wrong!
+ std::cout << "C99 input format error!" << std::endl;
+ }
+ // Expect to get an infinity, which will display still using the C99 locale as "inf"
+ cout << "infinity in C99 representation is " << infinity << endl;
+
+ // To check, we can switch back to the default C locale.
+ cout.imbue (default_locale);
+ cout << "infinity in default C representation is " << infinity << endl;
+ } // using C99 locale.
+
+ {
+ // A 'loop-back example, output to a stringstream, and reading it back in.
+ // Create C99 input and output locales.
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>);
+ std::locale C99_in_locale (default_locale, new boost::math::nonfinite_num_get<char>);
+
+ std::ostringstream oss;
+ oss.imbue(C99_out_locale);
+ oss << plus_infinity;
+
+ std::istringstream iss(oss.str()); // So stream contains "inf".
+ iss.imbue (C99_in_locale);
+
+ std::string s;
+
+ iss >> s;
+
+ cout.imbue(C99_out_locale);
+ if (oss.str() != s)
+ {
+ cout << plus_infinity << " != " << s << " loopback failed!" << endl;
+ }
+ else
+ {
+ cout << plus_infinity << " == " << s << " as expected." << endl;
+ }
+ }
+
+
+ // Example varying the width and position of the nonfinite representations.
+ // With the nonfinite_num_put and _get facets, the width of the output is constant.
+
+ #ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined, so no max_digits10 available." << endl;
+ std::streamsize max_digits10 = 2 + std::numeric_limits<double>::digits * 30103UL / 100000UL;
+#else
+ // Can use new C++0X max_digits10 (the maximum potentially significant digits).
+ std::streamsize max_digits10 = std::numeric_limits<double>::max_digits10;
+#endif
+ cout << "std::numeric_limits<double>::max_digits10 is " << max_digits10 << endl;
+ cout.precision(max_digits10);
+
+ double pi = 3.141592653589793238462643383279502884197169399375105820974944;
+ // Expect 17 (probably) decimal digits (regardless of locale).
+ // cout has the default locale.
+ cout << "pi = " << pi << endl; // pi = 3.1415926535897931
+ cout.imbue (C99_out_locale); // Use cout with the C99 locale
+ // (expect the same output for a double).
+ cout << "pi = " << pi << endl; // pi = 3.1415926535897931
+
+ cout << "infinity in C99 representation is " << plus_infinity << endl;
+
+ //int width = 2; // Check effect if width too small is OK.
+ // (There was a disturbed layout on older MSVC?).
+ int width = 20;
+
+ // Similarly if we can switch back to the default C locale.
+ cout.imbue (default_locale);
+ cout << "infinity in default C representation is " << plus_infinity << endl;
+ cout << "infinity in default C representation (setw(" << width << ") is |" << setw(width) << plus_infinity <<'|' << endl;
+ cout << "infinity in default C representation (setw(" << width << ") is |" << left << setw(width) << plus_infinity <<'|' << endl;
+ cout << "infinity in default C representation (setw(" << width << ") is |" << internal << setw(width) << plus_infinity <<'|' << endl;
+
+ cout.imbue (C99_out_locale);
+ cout << "infinity in C99 representation (setw(" << width << ") is |" << right << setw(width) << plus_infinity <<'|'<< endl;
+ cout << "infinity in C99 representation (setw(" << width << ") is |" << left << setw(width) << plus_infinity <<'|'<< endl;
+ cout << "infinity in C99 representation (setw(" << width << ") is |" << internal << setw(width) << plus_infinity <<'|'<< endl;
+
+ return 0;
+} // int main()
+
+// end of test_nonfinite_num_facets.cpp
+
+/*
+
+Output:
+
+simple_nonfinite_facet.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\nonfinite_facet_simple.exe
+ Nonfinite_num_facet very simple example.
+ Using C locale
+ +std::numeric_limits<double>::infinity() = 1.#INF
+ -std::numeric_limits<double>::infinity() = -1.#INF
+ +std::numeric_limits<double>::quiet_NaN () = 1.#QNAN
+ Using C99_out_locale
+ +std::numeric_limits<double>::infinity() = inf
+ -std::numeric_limits<double>::infinity() = -inf
+ +std::numeric_limits<double>::quiet_NaN () = nan
+ infinity in C99 representation is inf
+ infinity in default C representation is 1.#INF
+ 3
+ 3
+ inf == inf as expected.
+ std::numeric_limits<double>::max_digits10 is 17
+ pi = 3.1415926535897931
+ C locale input format error!
+ pi = 3.1415926535897931
+ infinity in C99 representation is inf
+ infinity in default C representation is 1.#INF
+ infinity in default C representation (setw(20) is 1.#INF|
+ infinity in default C representation (setw(20) is 1.#INF |
+ infinity in default C representation (setw(20) is 1.#INF|
+ infinity in C99 representation (setw(20) is inf|
+ infinity in C99 representation (setw(20) is inf |
+ infinity in C99 representation (setw(20) is inf|
+
+*/
diff --git a/src/boost/libs/math/example/nonfinite_facet_sstream.cpp b/src/boost/libs/math/example/nonfinite_facet_sstream.cpp
new file mode 100644
index 000000000..4408e4d4a
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_facet_sstream.cpp
@@ -0,0 +1,132 @@
+// nonfinite_facet_sstream.cpp
+
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Examples of nonfinite with output and input facets and stringstreams.
+
+\detail Construct a new locale with the nonfinite_num_put and nonfinite_num_get
+facets and imbue istringstream, ostringstream and stringstreams,
+showing output and input (and loopback for the stringstream).
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_put;
+using boost::math::nonfinite_num_get;
+
+using boost::math::legacy;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+#include <locale>
+using std::locale;
+
+#include <sstream>
+using std::stringstream;
+using std::istringstream;
+using std::ostringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <assert.h>
+
+int main()
+{
+ //[nonfinite_facets_sstream_1
+ locale old_locale;
+ locale tmp_locale(old_locale, new nonfinite_num_put<char>);
+ locale new_locale(tmp_locale, new nonfinite_num_get<char>);
+ //] [/nonfinite_facets_sstream_1]
+
+ // Note that to add two facets, nonfinite_num_put and nonfinite_num_get,
+ // you have to add one at a time, using a temporary locale.
+
+ {
+ ostringstream oss;
+ oss.imbue(new_locale);
+ double inf = numeric_limits<double>::infinity();
+ oss << inf; // Write out.
+ cout << "infinity output was " << oss.str() << endl;
+ BOOST_ASSERT(oss.str() == "inf");
+ }
+ {
+ istringstream iss;
+ iss.str("inf");
+ iss.imbue(new_locale);
+ double inf;
+ iss >> inf; // Read from "inf"
+ cout << "Infinity input was " << iss.str() << endl;
+ BOOST_ASSERT(inf == numeric_limits<double>::infinity());
+ }
+
+ {
+ //[nonfinite_facets_sstream_2
+ stringstream ss;
+ ss.imbue(new_locale);
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Write out.
+ BOOST_ASSERT(ss.str() == "inf");
+ double r;
+ ss >> r; // Read back in.
+ BOOST_ASSERT(inf == r); // Confirms that the double values really are identical.
+
+ cout << "infinity output was " << ss.str() << endl;
+ cout << "infinity input was " << r << endl;
+ // But the string representation of r displayed will be the native type
+ // because, when it was constructed, cout had NOT been imbued
+ // with the new locale containing the nonfinite_numput facet.
+ // So the cout output will be "1.#INF on MS platforms
+ // and may be "inf" or other string representation on other platforms.
+
+ //] [/nonfinite_facets_sstream_2]
+ }
+
+ {
+ stringstream ss;
+ ss.imbue(new_locale);
+
+ double nan = numeric_limits<double>::quiet_NaN();
+ ss << nan; // Write out.
+ BOOST_ASSERT(ss.str() == "nan");
+
+ double v;
+ ss >> v; // Read back in.
+
+ cout << "NaN output was " << ss.str() << endl;
+ cout << "NaN input was " << v << endl;
+
+ // assert(nan == v); // Always fails because NaN == NaN fails!
+ // assert(nan == numeric_limits<double>::quiet_NaN()); asserts!
+
+ // And the string representation will be the native type
+ // because cout has NOT been imbued with a locale containing
+ // the nonfinite_numput facet.
+ // So the output will be "1.#QNAN on MS platforms
+ // and may be "nan" or other string representation on other platforms.
+ }
+
+} // int main()
+
+
+/*
+//[nonfinite_facet_sstream_output
+
+infinity output was inf
+Infinity input was inf
+infinity output was inf
+infinity input was 1.#INF
+NaN output was nan
+NaN input was 1.#QNAN
+
+//] [nonfinite_facet_sstream_output]
+*/
+
diff --git a/src/boost/libs/math/example/nonfinite_legacy.cpp b/src/boost/libs/math/example/nonfinite_legacy.cpp
new file mode 100644
index 000000000..2e73fc2fc
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_legacy.cpp
@@ -0,0 +1,94 @@
+// nonfinite_legacy.cpp
+
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Basic tests of nonfinite loopback with output and input facet.
+
+\detail Basic loopback test outputs using the so-called 'legacy' facets,
+"1.#INF" and "1.#QNAN".
+
+and reads back in using nonfinite input 'legacy' facet, and
+(if possible) checks if loopback OK.
+
+*/
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_put;
+using boost::math::nonfinite_num_get;
+
+using boost::math::legacy;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include <iomanip>
+using std::setfill;
+using std::setw;
+
+#include <locale>
+using std::locale;
+
+#include <sstream>
+using std::stringstream;
+#include <limits>
+using std::numeric_limits;
+
+#include <assert.h>
+
+int main()
+{
+ // Create a new locale with both the nonfinite facets.
+ std::locale new_locale(std::locale(std::locale(),
+ new boost::math::nonfinite_num_put<char>),
+ new boost::math::nonfinite_num_get<char>);
+
+ {
+ stringstream ss;
+ ss.imbue(new_locale);
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Write out.
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "infinity output was " << inf << endl;
+ cout << "infinity input was " << r << endl;
+
+ BOOST_ASSERT(inf == r);
+ }
+ {
+ stringstream ss;
+ ss.imbue(new_locale);
+
+ double nan = numeric_limits<double>::quiet_NaN();
+ ss << nan; // Write out.
+ double v;
+ ss >> v; // Read back in.
+
+ cout << "NaN output was " << nan << endl;
+ cout << "NaN input was " << v << endl;
+
+ // BOOST_ASSERT(nan == v); // Always fails because NaN == NaN fails!
+ // BOOST_ASSERT(nan == numeric_limits<double>::quiet_NaN()); asserts!
+ }
+
+} // int main()
+
+/*
+
+Output:
+
+infinity output was 1.#INF
+infinity input was 1.#INF
+NaN output was 1.#QNAN
+NaN input was 1.#QNAN
+
+*/
+
diff --git a/src/boost/libs/math/example/nonfinite_loopback_ok.cpp b/src/boost/libs/math/example/nonfinite_loopback_ok.cpp
new file mode 100644
index 000000000..70ccd24b9
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_loopback_ok.cpp
@@ -0,0 +1,89 @@
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Basic tests of nonfinite loopback.
+
+\detail Basic loopback test outputs using nonfinite facets
+(output and input) and reads back in, and checks if loopback OK.
+
+Expected to work portably on all platforms.
+
+*/
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4702)
+# pragma warning(disable : 4127) // conditional expression is constant.
+#endif
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include <locale>
+using std::locale;
+
+#include <sstream>
+using std::stringstream;
+#include <limits>
+using std::numeric_limits;
+
+#include <assert.h>
+
+int main()
+{
+
+ if((std::numeric_limits<double>::has_infinity == false) || (std::numeric_limits<double>::infinity() == 0))
+ {
+ std::cout << "Infinity not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ if((std::numeric_limits<double>::has_quiet_NaN == false) || (std::numeric_limits<double>::quiet_NaN() == 0))
+ {
+ std::cout << "NaN not supported on this platform." << std::endl;
+ return 0;
+ }
+ //locale old_locale; // Current global locale.
+ // Create tmp_locale and store the output nonfinite_num_put facet in it.
+ //locale tmp_locale(old_locale, new nonfinite_num_put<char>);
+ // Create new_locale and store the input nonfinite_num_get facet in it.
+ //locale new_locale(tmp_locale, new nonfinite_num_get<char>);
+ // Can only add one facet at a time, hence need a tmp_locale,
+ // unless we write:
+
+ std::locale new_locale(std::locale(std::locale(std::locale(),
+ new boost::math::nonfinite_num_put<char>),
+ new boost::math::nonfinite_num_get<char>));
+
+ stringstream ss; // Both input and output, so need both get and put facets.
+
+ ss.imbue(new_locale);
+
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Write out.
+ double r;
+ ss >> r; // Read back in.
+
+ BOOST_ASSERT(inf == r); // OK MSVC <= 10.0!
+
+} // int main()
+
+/*
+
+Output:
+
+nonfinite_loopback_ok.vcxproj -> J:\Cpp\fp_facet\fp_facet\Debug\nonfinite_loopback_ok.exe
+
+*/
+
+
diff --git a/src/boost/libs/math/example/nonfinite_num_facet.cpp b/src/boost/libs/math/example/nonfinite_num_facet.cpp
new file mode 100644
index 000000000..80e4e8140
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_num_facet.cpp
@@ -0,0 +1,291 @@
+/** nonfinite_num_facet.cpp
+ *
+ * Copyright (c) 2011 Francois Mauger
+ * Copyright (c) 2011 Paul A. Bristow
+ *
+ * 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)
+ *
+ * This simple program illustrates how to use the
+ * `boost/math/nonfinite_num_facets.hpp' material from the original
+ * Floating Point Utilities contribution by Johan Rade.
+ * Floating Point Utility library has been accepted into Boost,
+ * but the utilities have been/will be incorporated into Boost.Math library.
+ *
+\file
+
+\brief A fairly simple example of using non_finite_num facet for
+C99 standard output of infinity and NaN.
+
+\detail This program illustrates how to use the
+ `boost/math/nonfinite_num_facets.hpp' material from the original
+ Floating Point Utilities contribution by Johan Rade.
+ Floating Point Utility library has been accepted into Boost,
+ but the utilities have been/will be incorporated into Boost.Math library.
+
+ Based on an example from Francois Mauger.
+
+ Double and float variables are assigned ordinary finite values (pi),
+ and nonfinite like infinity and NaN.
+
+ These values are then output and read back in, and then redisplayed.
+
+*/
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4127) // conditional expression is constant.
+#endif
+
+#include <iostream>
+#include <iomanip>
+using std::cout;
+using std::endl;
+
+#include <limits> // numeric_limits
+using std::numeric_limits;
+
+#include <boost/cstdint.hpp>
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+
+static const char sep = ','; // Separator of bracketed float and double values.
+
+// Use max_digits10 (or equivalent) to obtain
+// all potentially significant decimal digits for the floating-point types.
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ std::streamsize max_digits10_float = 2 + std::numeric_limits<float>::digits * 30103UL / 100000UL;
+ std::streamsize max_digits10_double = 2 + std::numeric_limits<double>::digits * 30103UL / 100000UL;
+#else
+ // Can use new C++0X max_digits10 (the maximum potentially significant digits).
+ std::streamsize max_digits10_float = std::numeric_limits<float>::max_digits10;
+ std::streamsize max_digits10_double = std::numeric_limits<double>::max_digits10;
+#endif
+
+
+/* A class with a float and a double */
+struct foo
+{
+ foo () : fvalue (3.1415927F), dvalue (3.1415926535897931)
+ {
+ }
+ // Set both the values to -infinity :
+ void minus_infinity ()
+ {
+ fvalue = -std::numeric_limits<float>::infinity ();
+ dvalue = -std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // Set the values to +infinity :
+ void plus_infinity ()
+ {
+ fvalue = +std::numeric_limits<float>::infinity ();
+ dvalue = +std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // Set the values to NaN :
+ void nan ()
+ {
+ fvalue = +std::numeric_limits<float>::quiet_NaN ();
+ dvalue = +std::numeric_limits<double>::quiet_NaN ();
+ return;
+ }
+ // Print a foo:
+ void print (std::ostream & a_out, const std::string & a_title)
+ {
+ if (a_title.empty ()) a_out << "foo";
+ else a_out << a_title;
+ a_out << " : " << std::endl;
+ a_out << "|-- " << "fvalue = ";
+
+ a_out.precision (max_digits10_float);
+ a_out << fvalue << std::endl;
+ a_out << "`-- " << "dvalue = ";
+ a_out.precision (max_digits10_double);
+ a_out << dvalue << std::endl;
+ return;
+ }
+
+ // I/O operators for a foo structure of a float and a double :
+ friend std::ostream & operator<< (std::ostream & a_out, const foo & a_foo);
+ friend std::istream & operator>> (std::istream & a_in, foo & a_foo);
+
+ // Attributes :
+ float fvalue; // Single precision floating number.
+ double dvalue; // Double precision floating number.
+};
+
+std::ostream & operator<< (std::ostream & a_out, const foo & a_foo)
+{ // Output bracketed FPs, for example "(3.1415927,3.1415926535897931)"
+ a_out.precision (max_digits10_float);
+ a_out << "(" << a_foo.fvalue << sep ;
+ a_out.precision (max_digits10_double);
+ a_out << a_foo.dvalue << ")";
+ return a_out;
+}
+
+std::istream & operator>> (std::istream & a_in, foo & a_foo)
+{ // Input bracketed floating-point values into a foo structure,
+ // for example from "(3.1415927,3.1415926535897931)"
+ char c = 0;
+ a_in.get (c);
+ if (c != '(')
+ {
+ std::cerr << "ERROR: operator>> No ( " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ float f;
+ a_in >> std::ws >> f;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != sep)
+ {
+ std::cerr << "ERROR: operator>> c='" << c << "'" << std::endl;
+ std::cerr << "ERROR: operator>> No '" << sep << "'" << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ double d;
+ a_in >> std::ws >> d;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != ')')
+ {
+ std::cerr << "ERROR: operator>> No ) " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ a_foo.fvalue = f;
+ a_foo.dvalue = d;
+ return a_in;
+} // std::istream & operator>> (std::istream & a_in, foo & a_foo)
+
+int main ()
+{
+ std::cout << "nonfinite_num_facet simple example." << std::endl;
+
+ if((std::numeric_limits<double>::has_infinity == false) || (std::numeric_limits<double>::infinity() == 0))
+ {
+ std::cout << "Infinity not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ if((std::numeric_limits<double>::has_quiet_NaN == false) || (std::numeric_limits<double>::quiet_NaN() == 0))
+ {
+ std::cout << "NaN not supported on this platform." << std::endl;
+ return 0;
+ }
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined, so no max_digits10 available either:"
+ "\n we'll have to calculate our own version." << endl;
+#endif
+ std::cout << "std::numeric_limits<float>::max_digits10 is " << max_digits10_float << endl;
+ std::cout << "std::numeric_limits<double>::max_digits10 is " << max_digits10_double << endl;
+
+ std::locale the_default_locale (std::locale::classic ());
+
+ {
+ std::cout << "Write to a string buffer (using default locale) :" << std::endl;
+ foo f0; // pi
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+
+ f0.print (std::cout, "f0"); // pi
+ f1.print (std::cout, "f1"); // +inf
+ f2.print (std::cout, "f2"); // -inf
+ f3.print (std::cout, "f3"); // NaN
+
+ std::ostringstream oss;
+ std::locale C99_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ oss.imbue (C99_out_locale);
+ oss.precision (15);
+ oss << f0 << f1 << f2 << f3;
+ std::cout << "Output in C99 format is: \"" << oss.str () << "\"" << std::endl;
+ std::cout << "Output done." << std::endl;
+ }
+
+ {
+ std::string the_string = "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)"; // C99 format
+ // Must have correct separator!
+ std::cout << "Read C99 format from a string buffer containing \"" << the_string << "\""<< std::endl;
+
+ std::locale C99_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ std::istringstream iss (the_string);
+ iss.imbue (C99_in_locale);
+
+ foo f0, f1, f2, f3;
+ iss >> f0 >> f1 >> f2 >> f3;
+ if (! iss)
+ {
+ std::cerr << "Input Format error !" << std::endl;
+ }
+ else
+ {
+ std::cerr << "Input OK." << std::endl;
+ cout << "Display in default locale format " << endl;
+ f0.print (std::cout, "f0");
+ f1.print (std::cout, "f1");
+ f2.print (std::cout, "f2");
+ f3.print (std::cout, "f3");
+ }
+ std::cout << "Input done." << std::endl;
+ }
+
+ std::cout << "End nonfinite_num_facet.cpp" << std::endl;
+ return 0;
+} // int main()
+
+ // end of test_nonfinite_num_facets.cpp
+
+/*
+
+Output:
+
+nonfinite_num_facet simple example.
+ std::numeric_limits<float>::max_digits10 is 8
+ std::numeric_limits<double>::max_digits10 is 17
+ Write to a string buffer (using default locale) :
+ f0 :
+ |-- fvalue = 3.1415927
+ `-- dvalue = 3.1415926535897931
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Output in C99 format is: "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)"
+ Output done.
+ Read C99 format from a string buffer containing "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)"
+ Display in default locale format
+ f0 :
+ |-- fvalue = 3.1415927
+ `-- dvalue = 3.1415926535897931
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Input done.
+ End nonfinite_num_facet.cpp
+
+*/
diff --git a/src/boost/libs/math/example/nonfinite_num_facet_serialization.cpp b/src/boost/libs/math/example/nonfinite_num_facet_serialization.cpp
new file mode 100644
index 000000000..e2972a10f
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_num_facet_serialization.cpp
@@ -0,0 +1,433 @@
+/** nonfinite_num_facet_serialization.cpp
+ *
+ * Copyright (c) 2011 Francois Mauger
+ * Copyright (c) 2011 Paul A. Bristow
+ *
+ * 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)
+ *
+ * This sample program by Francois Mauger illustrates how to use the
+ * `boost/math/nonfinite_num_facets.hpp' material from the original
+ * Floating Point Utilities contribution by Johan Rade. Here it is
+ * shown how non finite floating number can be serialized and
+ * deserialized from I/O streams and/or Boost text/XML archives. It
+ * produces two archives stored in `test.txt' and `test.xml' files.
+ *
+ * Tested with Boost 1.44, gcc 4.4.1, Linux/i686 (32bits).
+ * Tested with Boost.1.46.1 MSVC 10.0 32 bit.
+ */
+
+#ifdef _MSC_VER
+# pragma warning(push)
+//# pragma warning(disable : 4100) // unreferenced formal parameter.
+#endif
+
+#include <iostream>
+#include <sstream>
+#include <fstream>
+#include <limits>
+
+#include <boost/cstdint.hpp>
+#include <boost/serialization/nvp.hpp>
+#include <boost/archive/text_oarchive.hpp>
+#include <boost/archive/text_iarchive.hpp>
+#include <boost/archive/xml_oarchive.hpp>
+#include <boost/archive/xml_iarchive.hpp>
+#include <boost/archive/codecvt_null.hpp>
+
+// from the Floating Point Utilities :
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+
+static const char sep = ','; // Separator of bracketed float and double values.
+
+// Use max_digits10 (or equivalent) to obtain
+// all potentially significant decimal digits for the floating-point types.
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ std::streamsize max_digits10_float = 2 + std::numeric_limits<float>::digits * 30103UL / 100000UL;
+ std::streamsize max_digits10_double = 2 + std::numeric_limits<double>::digits * 30103UL / 100000UL;
+#else
+ // Can use new C++0X max_digits10 (the maximum potentially significant digits).
+ std::streamsize max_digits10_float = std::numeric_limits<float>::max_digits10;
+ std::streamsize max_digits10_double = std::numeric_limits<double>::max_digits10;
+#endif
+
+
+/* A class with a float and a double */
+struct foo
+{
+ foo () : fvalue (3.1415927F), dvalue (3.1415926535897931)
+ { // Construct using 32 and 64-bit max_digits10 decimal digits value of pi.
+ }
+ // Set the values at -infinity :
+ void minus_infinity ()
+ {
+ fvalue = -std::numeric_limits<float>::infinity ();
+ dvalue = -std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // Set the values at +infinity :
+ void plus_infinity ()
+ {
+ fvalue = +std::numeric_limits<float>::infinity ();
+ dvalue = +std::numeric_limits<double>::infinity ();
+ return;
+ }
+ // Set the values at NaN :
+ void nan ()
+ {
+ fvalue = +std::numeric_limits<float>::quiet_NaN ();
+ dvalue = +std::numeric_limits<double>::quiet_NaN ();
+ return;
+ }
+ // Print :
+ void print (std::ostream & a_out, const std::string & a_title)
+ {
+ if (a_title.empty ()) a_out << "foo";
+ else a_out << a_title;
+ a_out << " : " << std::endl;
+ a_out << "|-- " << "fvalue = ";
+ a_out.precision (7);
+ a_out << fvalue << std::endl;
+ a_out << "`-- " << "dvalue = ";
+ a_out.precision (15);
+ a_out << dvalue << std::endl;
+ return;
+ }
+
+ // I/O operators :
+ friend std::ostream & operator<< (std::ostream & a_out, const foo & a_foo);
+ friend std::istream & operator>> (std::istream & a_in, foo & a_foo);
+
+ // Boost serialization :
+ template <class Archive>
+ void serialize (Archive & ar, int /*version*/)
+ {
+ ar & BOOST_SERIALIZATION_NVP (fvalue);
+ ar & BOOST_SERIALIZATION_NVP (dvalue);
+ return;
+ }
+
+ // Attributes :
+ float fvalue; // Single precision floating-point number.
+ double dvalue; // Double precision floating-point number.
+};
+
+std::ostream & operator<< (std::ostream & a_out, const foo & a_foo)
+{ // Output bracketed FPs, for example "(3.1415927,3.1415926535897931)"
+ a_out.precision (max_digits10_float);
+ a_out << "(" << a_foo.fvalue << sep ;
+ a_out.precision (max_digits10_double);
+ a_out << a_foo.dvalue << ")";
+ return a_out;
+}
+
+std::istream & operator>> (std::istream & a_in, foo & a_foo)
+{ // Input bracketed floating-point values into a foo structure,
+ // for example from "(3.1415927,3.1415926535897931)"
+ char c = 0;
+ a_in.get (c);
+ if (c != '(')
+ {
+ std::cerr << "ERROR: operator>> No ( " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ float f;
+ a_in >> std::ws >> f;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != sep)
+ {
+ std::cerr << "ERROR: operator>> c='" << c << "'" << std::endl;
+ std::cerr << "ERROR: operator>> No '" << sep << "'" << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ double d;
+ a_in >> std::ws >> d;
+ if (! a_in)
+ {
+ return a_in;
+ }
+ a_in >> std::ws;
+ a_in.get (c);
+ if (c != ')')
+ {
+ std::cerr << "ERROR: operator>> No ) " << std::endl;
+ a_in.setstate(std::ios::failbit);
+ return a_in;
+ }
+ a_foo.fvalue = f;
+ a_foo.dvalue = d;
+ return a_in;
+}
+
+int main (void)
+{
+ std::clog << std::endl
+ << "Nonfinite_serialization.cpp' example program." << std::endl;
+
+#ifdef BOOST_NO_CXX11_NUMERIC_LIMITS
+ std::cout << "BOOST_NO_CXX11_NUMERIC_LIMITS is defined, so no max_digits10 available either,"
+ "using our own version instead." << std::endl;
+#endif
+ std::cout << "std::numeric_limits<float>::max_digits10 is " << max_digits10_float << std::endl;
+ std::cout << "std::numeric_limits<double>::max_digits10 is " << max_digits10_double << std::endl;
+
+ std::locale the_default_locale (std::locale::classic (),
+ new boost::archive::codecvt_null<char>);
+
+ // Demonstrate use of nonfinite facets with stringstreams.
+ {
+ std::clog << "Construct some foo structures with a finite and nonfinites." << std::endl;
+ foo f0;
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+ // Display them.
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+ std::clog << " Write to a string buffer." << std::endl;
+
+ std::ostringstream oss;
+ std::locale the_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ oss.imbue (the_out_locale);
+ oss.precision (max_digits10_double);
+ oss << f0 << f1 << f2 << f3;
+ std::clog << "Output is: `" << oss.str () << "'" << std::endl;
+ std::clog << "Done output to ostringstream." << std::endl;
+ }
+
+ {
+ std::clog << "Read foo structures from a string buffer." << std::endl;
+
+ std::string the_string = "(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)";
+ std::clog << "Input is: `" << the_string << "'" << std::endl;
+
+ std::locale the_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ std::istringstream iss (the_string);
+ iss.imbue (the_in_locale);
+
+ foo f0, f1, f2, f3;
+ iss >> f0 >> f1 >> f2 >> f3;
+ if (! iss)
+ {
+ std::cerr << "Format error !" << std::endl;
+ }
+ else
+ {
+ std::cerr << "Read OK." << std::endl;
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+ }
+ std::clog << "Done input from istringstream." << std::endl;
+ }
+
+ { // Demonstrate use of nonfinite facets for Serialization with Boost text archives.
+ std::clog << "Serialize (using Boost text archive)." << std::endl;
+ // Construct some foo structures with a finite and nonfinites.
+ foo f0;
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+ // Display them.
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::locale the_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ // Use a temporary folder .temps (which contains "boost-no-inspect" so that it will not be inspected, and made 'hidden' too).
+ std::ofstream fout ("./.temps/nonfinite_archive_test.txt");
+ fout.imbue (the_out_locale);
+ boost::archive::text_oarchive toar (fout, boost::archive::no_codecvt);
+ // Write to archive.
+ toar & f0;
+ toar & f1;
+ toar & f2;
+ toar & f3;
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Deserialize (Boost text archive)..." << std::endl;
+ std::locale the_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ // Use a temporary folder .temps (which contains "boost-no-inspect" so that it will not be inspected, and made 'hidden' too).
+ std::ifstream fin ("./.temps/nonfinite_archive_test.txt");
+ fin.imbue (the_in_locale);
+ boost::archive::text_iarchive tiar (fin, boost::archive::no_codecvt);
+ foo f0, f1, f2, f3;
+ // Read from archive.
+ tiar & f0;
+ tiar & f1;
+ tiar & f2;
+ tiar & f3;
+ // Display foos.
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::clog << "Done." << std::endl;
+ }
+
+ { // Demonstrate use of nonfinite facets for Serialization with Boost XML Archive.
+ std::clog << "Serialize (Boost XML archive)..." << std::endl;
+ // Construct some foo structures with a finite and nonfinites.
+ foo f0;
+ foo f1; f1.minus_infinity ();
+ foo f2; f2.plus_infinity ();
+ foo f3; f3.nan ();
+ // Display foos.
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::locale the_out_locale (the_default_locale, new boost::math::nonfinite_num_put<char>);
+ // Use a temporary folder /.temps (which contains "boost-no-inspect" so that it will not be inspected, and made 'hidden' too).
+ std::ofstream fout ("./.temps/nonfinite_XML_archive_test.txt");
+ fout.imbue (the_out_locale);
+ boost::archive::xml_oarchive xoar (fout, boost::archive::no_codecvt);
+
+ xoar & BOOST_SERIALIZATION_NVP (f0);
+ xoar & BOOST_SERIALIZATION_NVP (f1);
+ xoar & BOOST_SERIALIZATION_NVP (f2);
+ xoar & BOOST_SERIALIZATION_NVP (f3);
+ std::clog << "Done." << std::endl;
+ }
+
+ {
+ std::clog << "Deserialize (Boost XML archive)..." << std::endl;
+ std::locale the_in_locale (the_default_locale, new boost::math::nonfinite_num_get<char>);
+ // Use a temporary folder /.temps (which contains "boost-no-inspect" so that it will not be inspected, and made 'hidden' too).
+ std::ifstream fin ("./.temps/nonfinite_XML_archive_test.txt"); // Previously written above.
+ fin.imbue (the_in_locale);
+ boost::archive::xml_iarchive xiar (fin, boost::archive::no_codecvt);
+ foo f0, f1, f2, f3;
+
+ xiar & BOOST_SERIALIZATION_NVP (f0);
+ xiar & BOOST_SERIALIZATION_NVP (f1);
+ xiar & BOOST_SERIALIZATION_NVP (f2);
+ xiar & BOOST_SERIALIZATION_NVP (f3);
+
+ f0.print (std::clog, "f0");
+ f1.print (std::clog, "f1");
+ f2.print (std::clog, "f2");
+ f3.print (std::clog, "f3");
+
+ std::clog << "Done." << std::endl;
+ }
+
+ std::clog << "End nonfinite_serialization.cpp' example program." << std::endl;
+ return 0;
+}
+
+/*
+
+Output:
+
+ Nonfinite_serialization.cpp' example program.
+ std::numeric_limits<float>::max_digits10 is 8
+ std::numeric_limits<double>::max_digits10 is 17
+ Construct some foo structures with a finite and nonfinites.
+ f0 :
+ |-- fvalue = 3.141593
+ `-- dvalue = 3.14159265358979
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Write to a string buffer.
+ Output is: `(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)'
+ Done output to ostringstream.
+ Read foo structures from a string buffer.
+ Input is: `(3.1415927,3.1415926535897931)(-inf,-inf)(inf,inf)(nan,nan)'
+ Read OK.
+ f0 :
+ |-- fvalue = 3.141593
+ `-- dvalue = 3.14159265358979
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Done input from istringstream.
+ Serialize (using Boost text archive).
+ f0 :
+ |-- fvalue = 3.141593
+ `-- dvalue = 3.14159265358979
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Done.
+ Deserialize (Boost text archive)...
+ f0 :
+ |-- fvalue = 3.141593
+ `-- dvalue = 3.14159265358979
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Done.
+ Serialize (Boost XML archive)...
+ f0 :
+ |-- fvalue = 3.141593
+ `-- dvalue = 3.14159265358979
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Done.
+ Deserialize (Boost XML archive)...
+ f0 :
+ |-- fvalue = 3.141593
+ `-- dvalue = 3.14159265358979
+ f1 :
+ |-- fvalue = -1.#INF
+ `-- dvalue = -1.#INF
+ f2 :
+ |-- fvalue = 1.#INF
+ `-- dvalue = 1.#INF
+ f3 :
+ |-- fvalue = 1.#QNAN
+ `-- dvalue = 1.#QNAN
+ Done.
+ End nonfinite_serialization.cpp' example program.
+
+ */
diff --git a/src/boost/libs/math/example/nonfinite_num_facet_trap.cpp b/src/boost/libs/math/example/nonfinite_num_facet_trap.cpp
new file mode 100644
index 000000000..9a4b2d58e
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_num_facet_trap.cpp
@@ -0,0 +1,115 @@
+
+/** nonfinite_num_facet_trap.cpp
+*
+* Copyright (c) 2012 Paul A. Bristow
+*
+* 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)
+*
+* This very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp` trapping output of infinity and/or NaNs.
+*
+\file
+
+\brief A very simple example of using non_finite_num facet for
+trapping output of infinity and/or NaNs.
+
+\note To actually get an exception throw by the iostream library
+one must enable exceptions.
+ `oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);`
+\note Which bit is set is implementation dependent, so enable exceptions for both.
+
+This is a fairly brutal method of catching nonfinites on output,
+but may suit some applications.
+
+*/
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4127) // conditional expression is constant.
+// assumes C++ exceptions enabled /EHsc
+#endif
+
+#include <boost/cstdint.hpp>
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+
+#include <iostream>
+#include <iomanip>
+using std::cout;
+using std::endl;
+using std::hex;
+#include <exception>
+#include <limits> // numeric_limits
+using std::numeric_limits;
+
+int main()
+{
+ using namespace boost::math;
+
+ std::cout << "nonfinite_num_facet_trap.cpp" << std::endl;
+
+ const double inf = +std::numeric_limits<double>::infinity ();
+ const double nan = +std::numeric_limits<double>::quiet_NaN ();
+
+ { // Output infinity and NaN with default flags (no trapping).
+ std::ostringstream oss;
+ std::locale default_locale (std::locale::classic ());
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>);
+ oss.imbue (C99_out_locale);
+ oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
+ oss << inf << ' ' << nan;
+ cout << "oss.rdstate() = " << hex << oss.rdstate() << endl; // 0
+ cout << "os.str() = " << oss.str() << endl; // os.str() = inf nan
+ }
+
+ try
+ { // // Output infinity with flags set to trap and catch any infinity.
+ std::ostringstream oss;
+ std::locale default_locale (std::locale::classic ());
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>(trap_infinity));
+ oss.imbue (C99_out_locale);
+ oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
+ // Note that which bit is set is implementation dependent, so enable exceptions for both.
+ oss << inf;
+ cout << "oss.rdstate() = " << hex << oss.rdstate() << endl;
+ cout << "oss.str() = " << oss.str() << endl;
+ }
+ catch(const std::ios_base::failure& e)
+ { // Expect "Infinity".
+ std::cout << "\n""Message from thrown exception was: " << e.what() << std::endl;
+ }
+
+ try
+ { // // Output NaN with flags set to catch any NaNs.
+ std::ostringstream oss;
+ std::locale default_locale (std::locale::classic ());
+ std::locale C99_out_locale (default_locale, new boost::math::nonfinite_num_put<char>(trap_nan));
+ oss.imbue (C99_out_locale);
+ oss.exceptions(std::ios_base::failbit | std::ios_base::badbit);
+ // Note that which bit is set is implementation dependent, so enable exceptions for both.
+ oss << nan;
+ cout << "oss.str() = " << oss.str() << endl;
+ }
+ catch(const std::ios_base::failure& e)
+ { // Expect "Infinity".
+ std::cout << "\n""Message from thrown exception was: " << e.what() << std::endl;
+ }
+
+
+ return 0; // end of nonfinite_num_facet_trap.cpp
+} // int main()
+
+
+/*
+
+Output:
+
+ nonfinite_num_facet_trap.cpp
+ oss.rdstate() = 0
+ os.str() = inf nan
+
+ Message from thrown exception was: Infinity
+
+ Message from thrown exception was: NaN
+
+*/
diff --git a/src/boost/libs/math/example/nonfinite_serialization_archives.cpp b/src/boost/libs/math/example/nonfinite_serialization_archives.cpp
new file mode 100644
index 000000000..0cb53ff0c
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_serialization_archives.cpp
@@ -0,0 +1,136 @@
+/** nonfinite_serialization_archives.cpp
+*
+* Copyright (c) 2011 Paul A. Bristow
+*
+* 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)
+*
+* This very simple program illustrates how to use the
+* `boost/math/nonfinite_num_facets.hpp' to obtain C99
+* representation of infinity and NaN.
+* From the original Floating Point Utilities contribution by Johan Rade.
+* Floating Point Utility library has been accepted into Boost,
+* but the utilities are incorporated into Boost.Math library.
+*
+\file
+
+\brief A simple example of using non_finite_num facet for
+C99 standard output of infinity and NaN in serialization archives.
+
+\detail This example shows how to create a C99 non-finite locale,
+and imbue input and output streams with the non_finite_num put and get facets.
+This allow output and input of infinity and NaN in a Standard portable way,
+This permits 'loop-back' of output back into input (and portably across different system too).
+This is particularly useful when used with Boost.Serialization so that non-finite NaNs and infinity
+values in text and xml archives can be handled correctly and portably.
+
+*/
+
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4127) // conditional expression is constant.
+#endif
+
+
+#include <boost/archive/text_oarchive.hpp>
+using boost::archive::text_oarchive;
+#include <boost/archive/codecvt_null.hpp>
+using boost::archive::codecvt_null;
+using boost::archive::no_codecvt;
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+using std::cerr;
+
+#include <iomanip>
+using std::setw;
+using std::left;
+using std::right;
+using std::internal;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+using std::istringstream;
+
+#include <fstream>
+using std::ofstream;
+
+#include <limits>
+using std::numeric_limits;
+
+#include <locale>
+using std::locale;
+
+
+/*
+Use with serialization archives.
+
+It is important that the same locale is used
+when an archive is saved and when it is loaded.
+Otherwise, loading the archive may fail.
+
+By default, archives are saved and loaded with a classic C locale with a
+`boost::archive::codecvt_null` facet added.
+Normally you do not have to worry about that.
+The constructors for the archive classes, as a side-effect,
+imbue the stream with such a locale.
+
+However, if you want to use the facets `nonfinite_num_put` and `nonfinite_num_get`
+with archives,`then you have to manage the locale manually.
+
+That is done by calling the archive constructor with the flag `boost::archive::no_codecvt`.
+Then the archive constructor will not imbue the stream with a new locale.
+
+The following code shows how to use `nonfinite_num_put` with a `text_oarchive`:
+
+*/
+
+int main()
+{
+
+ if((std::numeric_limits<double>::has_infinity == false) || (std::numeric_limits<double>::infinity() == 0))
+ {
+ std::cout << "Infinity not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ if((std::numeric_limits<double>::has_quiet_NaN == false) || (std::numeric_limits<double>::quiet_NaN() == 0))
+ {
+ std::cout << "NaN not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ locale default_locale(locale::classic(), new boost::archive::codecvt_null<char>);
+ // codecvt_null so the archive constructor will not imbue the stream with a new locale.
+
+ locale my_locale(default_locale, new nonfinite_num_put<char>);
+ // Add nonfinite_num_put facet to locale.
+
+ // Use a temporary folder /.temps (which contains "boost-no-inspect" so that it will not be inspected, and made 'hidden' too).
+ ofstream ofs("./.temps/test.txt");
+ ofs.imbue(my_locale);
+
+ boost::archive::text_oarchive oa(ofs, no_codecvt);
+
+ double x = numeric_limits<double>::infinity();
+ oa & x;
+
+} // int main()
+
+
+/* The same method works with nonfinite_num_get and text_iarchive.
+
+If you use the trap_infinity and trap_nan flags with a serialization archive,
+then you must set the exception mask of the stream.
+Serialization archives do not check the stream state.
+
+
+*/
diff --git a/src/boost/libs/math/example/nonfinite_signaling_NaN.cpp b/src/boost/libs/math/example/nonfinite_signaling_NaN.cpp
new file mode 100644
index 000000000..98ccdd1d9
--- /dev/null
+++ b/src/boost/libs/math/example/nonfinite_signaling_NaN.cpp
@@ -0,0 +1,189 @@
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Tests of nonfinite signaling NaN loopback.
+
+\detail nonfinite signaling NaN
+test outputs using nonfinite facets
+(output and input) and reads back in, and checks if loopback OK.
+
+Not expected to work on all platforms (if any). But shows that on MSVC,
+this legacy locale can ensure a consistent quiet NaN input from representations
+"1.#QNAN", "1.#SNAN" and "1.#IND"
+
+*/
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4702)
+#endif
+
+#include <boost/math/special_functions/nonfinite_num_facets.hpp>
+using boost::math::nonfinite_num_get;
+using boost::math::nonfinite_num_put;
+
+#include <iostream>
+using std::cout;
+using std::endl;
+
+#include <locale>
+using std::locale;
+
+#include <string>
+using std::string;
+
+#include <sstream>
+ using std::stringstream;
+ using std::istringstream;
+
+#include <limits>
+using std::numeric_limits;
+
+int main()
+{
+ if((std::numeric_limits<double>::has_infinity == false) || (std::numeric_limits<double>::infinity() == 0))
+ {
+ std::cout << "Infinity not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ if((std::numeric_limits<double>::has_quiet_NaN == false) || (std::numeric_limits<double>::quiet_NaN() == 0))
+ {
+ std::cout << "NaN not supported on this platform." << std::endl;
+ return 0;
+ }
+
+ locale default_locale; // Current global locale.
+ // Try to use the default locale first.
+ // On MSVC this doesn't work.
+
+ { // Try Quiet NaN
+ stringstream ss; // Both input and output.
+ ss.imbue(default_locale); // Redundant, of course.
+ string infs;
+ if(numeric_limits<double>::has_quiet_NaN)
+ { // Make sure quiet NaN is specialised for type double.
+ double qnan = numeric_limits<double>::quiet_NaN();
+ ss << qnan; // Output quiet_NaN.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for quiet NaN.
+ infs = "1.#QNAN";
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "quiet_NaN output was " << infs << endl; // "1.#QNAN"
+ cout << "quiet_NaN input was " << r << endl; // "1"
+ }
+
+#if (!defined __BORLANDC__ && !defined __CODEGEARC__)
+ // These compilers trap when trying to create a signaling_NaN!
+ { // Try Signaling NaN
+ stringstream ss; // Both input and output.
+ ss.imbue(default_locale); // Redundant, of course.
+ string infs;
+ if(numeric_limits<double>::has_signaling_NaN)
+ { // Make sure signaling NaN is specialised for type double.
+ double qnan = numeric_limits<double>::signaling_NaN();
+ ss << qnan; // Output signaling_NaN.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for signaling NaN.
+ infs = "1.#SNAN";
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "signaling_NaN output was " << infs << endl; // "1.#QNAN" (or "1.#SNAN"?)
+ cout << "signaling_NaN input was " << r << endl; // "1"
+ }
+#endif // Not Borland or CodeGear.
+
+ // Create legacy_locale and store the nonfinite_num_get facet (with legacy flag) in it.
+ locale legacy_locale(default_locale, new nonfinite_num_get<char>(boost::math::legacy));
+ // Note that the legacy flag has no effect on the nonfinite_num_put output facet.
+
+ cout << "Use legacy locale." << endl;
+
+ { // Try infinity.
+ stringstream ss; // Both input and output.
+ ss.imbue(legacy_locale);
+ string infs;
+ if(numeric_limits<double>::has_infinity)
+ { // Make sure infinity is specialised for type double.
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Output infinity.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for infinity.
+ infs = "1.#INF";
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "infinity output was " << infs << endl; // "1.#INF"
+ cout << "infinity input was " << r << endl; // "1.#INF"
+ }
+
+ { // Try input of "1.#SNAN".
+ //double inf = numeric_limits<double>::signaling_NaN(); // Assigns "1.#QNAN" on MSVC.
+ // So must use explicit string "1.#SNAN" instead.
+ stringstream ss; // Both input and output.
+ ss.imbue(legacy_locale);
+ string s = "1.#SNAN";
+
+ ss << s; // Write out.
+ double r;
+
+ ss >> r; // Read back in.
+
+ cout << "SNAN output was " << s << endl; // "1.#SNAN"
+ cout << "SNAN input was " << r << endl; // "1.#QNAN"
+ }
+
+ { // Try input of "1.#IND" .
+ stringstream ss; // Both input and output.
+ ss.imbue(legacy_locale);
+ string s = "1.#IND";
+ ss << s; // Write out.
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "IND output was " << s << endl; // "1.#IND"
+ cout << "IND input was " << r << endl; // "1.#QNAN"
+ }
+
+} // int main()
+
+/*
+
+Output:
+ nonfinite_signaling_NaN.vcxproj -> J:\Cpp\fp_facet\fp_facet\Debug\nonfinite_signaling_NaN.exe
+
+ quiet_NaN output was 1.#QNAN
+ quiet_NaN input was 1
+ signaling_NaN output was 1.#QNAN
+ signaling_NaN input was 1
+ Use legacy locale.
+ infinity output was 1.#INF
+ infinity input was 1.#INF
+ SNAN output was 1.#SNAN
+ SNAN input was 1.#QNAN
+ IND output was 1.#IND
+ IND input was 1.#QNAN
+
+
+*/
+
diff --git a/src/boost/libs/math/example/normal_misc_examples.cpp b/src/boost/libs/math/example/normal_misc_examples.cpp
new file mode 100644
index 000000000..3d0f3acff
--- /dev/null
+++ b/src/boost/libs/math/example/normal_misc_examples.cpp
@@ -0,0 +1,509 @@
+// normal_misc_examples.cpp
+
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+// Example of using normal distribution.
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[normal_basic1
+/*`
+First we need some includes to access the normal distribution
+(and some std output of course).
+*/
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution
+ using boost::math::normal; // typedef provides default type is double.
+
+#include <iostream>
+ using std::cout; using std::endl; using std::left; using std::showpoint; using std::noshowpoint;
+#include <iomanip>
+ using std::setw; using std::setprecision;
+#include <limits>
+ using std::numeric_limits;
+
+int main()
+{
+ cout << "Example: Normal distribution, Miscellaneous Applications.";
+
+ try
+ {
+ { // Traditional tables and values.
+/*`Let's start by printing some traditional tables.
+*/
+ double step = 1.; // in z
+ double range = 4; // min and max z = -range to +range.
+ int precision = 17; // traditional tables are only computed to much lower precision.
+ // but std::numeric_limits<double>::max_digits10; on new Standard Libraries gives
+ // 17, the maximum number of digits that can possibly be significant.
+ // std::numeric_limits<double>::digits10; == 15 is number of guaranteed digits,
+ // the other two digits being 'noisy'.
+
+ // Construct a standard normal distribution s
+ normal s; // (default mean = zero, and standard deviation = unity)
+ cout << "Standard normal distribution, mean = "<< s.mean()
+ << ", standard deviation = " << s.standard_deviation() << endl;
+
+/*` First the probability distribution function (pdf).
+*/
+ cout << "Probability distribution function values" << endl;
+ cout << " z " " pdf " << endl;
+ cout.precision(5);
+ for (double z = -range; z < range + step; z += step)
+ {
+ cout << left << setprecision(3) << setw(6) << z << " "
+ << setprecision(precision) << setw(12) << pdf(s, z) << endl;
+ }
+ cout.precision(6); // default
+ /*`And the area under the normal curve from -[infin] up to z,
+ the cumulative distribution function (cdf).
+*/
+ // For a standard normal distribution
+ cout << "Standard normal mean = "<< s.mean()
+ << ", standard deviation = " << s.standard_deviation() << endl;
+ cout << "Integral (area under the curve) from - infinity up to z " << endl;
+ cout << " z " " cdf " << endl;
+ for (double z = -range; z < range + step; z += step)
+ {
+ cout << left << setprecision(3) << setw(6) << z << " "
+ << setprecision(precision) << setw(12) << cdf(s, z) << endl;
+ }
+ cout.precision(6); // default
+
+/*`And all this you can do with a nanoscopic amount of work compared to
+the team of *human computers* toiling with Milton Abramovitz and Irene Stegen
+at the US National Bureau of Standards (now [@http://www.nist.gov NIST]).
+Starting in 1938, their "Handbook of Mathematical Functions with Formulas, Graphs and Mathematical Tables",
+was eventually published in 1964, and has been reprinted numerous times since.
+(A major replacement is planned at [@http://dlmf.nist.gov Digital Library of Mathematical Functions]).
+
+Pretty-printing a traditional 2-dimensional table is left as an exercise for the student,
+but why bother now that the Math Toolkit lets you write
+*/
+ double z = 2.;
+ cout << "Area for z = " << z << " is " << cdf(s, z) << endl; // to get the area for z.
+/*`
+Correspondingly, we can obtain the traditional 'critical' values for significance levels.
+For the 95% confidence level, the significance level usually called alpha,
+is 0.05 = 1 - 0.95 (for a one-sided test), so we can write
+*/
+ cout << "95% of area has a z below " << quantile(s, 0.95) << endl;
+ // 95% of area has a z below 1.64485
+/*`and a two-sided test (a comparison between two levels, rather than a one-sided test)
+
+*/
+ cout << "95% of area has a z between " << quantile(s, 0.975)
+ << " and " << -quantile(s, 0.975) << endl;
+ // 95% of area has a z between 1.95996 and -1.95996
+/*`
+
+First, define a table of significance levels: these are the probabilities
+that the true occurrence frequency lies outside the calculated interval.
+
+It is convenient to have an alpha level for the probability that z lies outside just one standard deviation.
+This will not be some nice neat number like 0.05, but we can easily calculate it,
+*/
+ double alpha1 = cdf(s, -1) * 2; // 0.3173105078629142
+ cout << setprecision(17) << "Significance level for z == 1 is " << alpha1 << endl;
+/*`
+ and place in our array of favorite alpha values.
+*/
+ double alpha[] = {0.3173105078629142, // z for 1 standard deviation.
+ 0.20, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+/*`
+
+Confidence value as % is (1 - alpha) * 100 (so alpha 0.05 == 95% confidence)
+that the true occurrence frequency lies *inside* the calculated interval.
+
+*/
+ cout << "level of significance (alpha)" << setprecision(4) << endl;
+ cout << "2-sided 1 -sided z(alpha) " << endl;
+ for (unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ cout << setw(15) << alpha[i] << setw(15) << alpha[i] /2 << setw(10) << quantile(complement(s, alpha[i]/2)) << endl;
+ // Use quantile(complement(s, alpha[i]/2)) to avoid potential loss of accuracy from quantile(s, 1 - alpha[i]/2)
+ }
+ cout << endl;
+
+/*`Notice the distinction between one-sided (also called one-tailed)
+where we are using a > *or* < test (and not both)
+and considering the area of the tail (integral) from z up to +[infin],
+and a two-sided test where we are using two > *and* < tests, and thus considering two tails,
+from -[infin] up to z low and z high up to +[infin].
+
+So the 2-sided values alpha[i] are calculated using alpha[i]/2.
+
+If we consider a simple example of alpha = 0.05, then for a two-sided test,
+the lower tail area from -[infin] up to -1.96 is 0.025 (alpha/2)
+and the upper tail area from +z up to +1.96 is also 0.025 (alpha/2),
+and the area between -1.96 up to 12.96 is alpha = 0.95.
+and the sum of the two tails is 0.025 + 0.025 = 0.05,
+
+*/
+//] [/[normal_basic1]
+
+//[normal_basic2
+
+/*`Armed with the cumulative distribution function, we can easily calculate the
+easy to remember proportion of values that lie within 1, 2 and 3 standard deviations from the mean.
+
+*/
+ cout.precision(3);
+ cout << showpoint << "cdf(s, s.standard_deviation()) = "
+ << cdf(s, s.standard_deviation()) << endl; // from -infinity to 1 sd
+ cout << "cdf(complement(s, s.standard_deviation())) = "
+ << cdf(complement(s, s.standard_deviation())) << endl;
+ cout << "Fraction 1 standard deviation within either side of mean is "
+ << 1 - cdf(complement(s, s.standard_deviation())) * 2 << endl;
+ cout << "Fraction 2 standard deviations within either side of mean is "
+ << 1 - cdf(complement(s, 2 * s.standard_deviation())) * 2 << endl;
+ cout << "Fraction 3 standard deviations within either side of mean is "
+ << 1 - cdf(complement(s, 3 * s.standard_deviation())) * 2 << endl;
+
+/*`
+To a useful precision, the 1, 2 & 3 percentages are 68, 95 and 99.7,
+and these are worth memorising as useful 'rules of thumb', as, for example, in
+[@http://en.wikipedia.org/wiki/Standard_deviation standard deviation]:
+
+[pre
+Fraction 1 standard deviation within either side of mean is 0.683
+Fraction 2 standard deviations within either side of mean is 0.954
+Fraction 3 standard deviations within either side of mean is 0.997
+]
+
+We could of course get some really accurate values for these
+[@http://en.wikipedia.org/wiki/Confidence_interval confidence intervals]
+by using cout.precision(15);
+
+[pre
+Fraction 1 standard deviation within either side of mean is 0.682689492137086
+Fraction 2 standard deviations within either side of mean is 0.954499736103642
+Fraction 3 standard deviations within either side of mean is 0.997300203936740
+]
+
+But before you get too excited about this impressive precision,
+don't forget that the *confidence intervals of the standard deviation* are surprisingly wide,
+especially if you have estimated the standard deviation from only a few measurements.
+*/
+//] [/[normal_basic2]
+
+
+//[normal_bulbs_example1
+/*`
+Examples from K. Krishnamoorthy, Handbook of Statistical Distributions with Applications,
+ISBN 1 58488 635 8, page 125... implemented using the Math Toolkit library.
+
+A few very simple examples are shown here:
+*/
+// K. Krishnamoorthy, Handbook of Statistical Distributions with Applications,
+ // ISBN 1 58488 635 8, page 125, example 10.3.5
+/*`Mean lifespan of 100 W bulbs is 1100 h with standard deviation of 100 h.
+Assuming, perhaps with little evidence and much faith, that the distribution is normal,
+we construct a normal distribution called /bulbs/ with these values:
+*/
+ double mean_life = 1100.;
+ double life_standard_deviation = 100.;
+ normal bulbs(mean_life, life_standard_deviation);
+ double expected_life = 1000.;
+
+/*`The we can use the Cumulative distribution function to predict fractions
+(or percentages, if * 100) that will last various lifetimes.
+*/
+ cout << "Fraction of bulbs that will last at best (<=) " // P(X <= 1000)
+ << expected_life << " is "<< cdf(bulbs, expected_life) << endl;
+ cout << "Fraction of bulbs that will last at least (>) " // P(X > 1000)
+ << expected_life << " is "<< cdf(complement(bulbs, expected_life)) << endl;
+ double min_life = 900;
+ double max_life = 1200;
+ cout << "Fraction of bulbs that will last between "
+ << min_life << " and " << max_life << " is "
+ << cdf(bulbs, max_life) // P(X <= 1200)
+ - cdf(bulbs, min_life) << endl; // P(X <= 900)
+/*`
+[note Real-life failures are often very ab-normal,
+with a significant number that 'dead-on-arrival' or suffer failure very early in their life:
+the lifetime of the survivors of 'early mortality' may be well described by the normal distribution.]
+*/
+//] [/normal_bulbs_example1 Quickbook end]
+ }
+ {
+ // K. Krishnamoorthy, Handbook of Statistical Distributions with Applications,
+ // ISBN 1 58488 635 8, page 125, Example 10.3.6
+
+//[normal_bulbs_example3
+/*`Weekly demand for 5 lb sacks of onions at a store is normally distributed with mean 140 sacks and standard deviation 10.
+*/
+ double mean = 140.; // sacks per week.
+ double standard_deviation = 10;
+ normal sacks(mean, standard_deviation);
+
+ double stock = 160.; // per week.
+ cout << "Percentage of weeks overstocked "
+ << cdf(sacks, stock) * 100. << endl; // P(X <=160)
+ // Percentage of weeks overstocked 97.7
+
+/*`So there will be lots of mouldy onions!
+So we should be able to say what stock level will meet demand 95% of the weeks.
+*/
+ double stock_95 = quantile(sacks, 0.95);
+ cout << "Store should stock " << int(stock_95) << " sacks to meet 95% of demands." << endl;
+/*`And it is easy to estimate how to meet 80% of demand, and waste even less.
+*/
+ double stock_80 = quantile(sacks, 0.80);
+ cout << "Store should stock " << int(stock_80) << " sacks to meet 8 out of 10 demands." << endl;
+//] [/normal_bulbs_example3 Quickbook end]
+ }
+ { // K. Krishnamoorthy, Handbook of Statistical Distributions with Applications,
+ // ISBN 1 58488 635 8, page 125, Example 10.3.7
+
+//[normal_bulbs_example4
+
+/*`A machine is set to pack 3 kg of ground beef per pack.
+Over a long period of time it is found that the average packed was 3 kg
+with a standard deviation of 0.1 kg.
+Assuming the packing is normally distributed,
+we can find the fraction (or %) of packages that weigh more than 3.1 kg.
+*/
+
+double mean = 3.; // kg
+double standard_deviation = 0.1; // kg
+normal packs(mean, standard_deviation);
+
+double max_weight = 3.1; // kg
+cout << "Percentage of packs > " << max_weight << " is "
+<< cdf(complement(packs, max_weight)) << endl; // P(X > 3.1)
+
+double under_weight = 2.9;
+cout <<"fraction of packs <= " << under_weight << " with a mean of " << mean
+ << " is " << cdf(complement(packs, under_weight)) << endl;
+// fraction of packs <= 2.9 with a mean of 3 is 0.841345
+// This is 0.84 - more than the target 0.95
+// Want 95% to be over this weight, so what should we set the mean weight to be?
+// KK StatCalc says:
+double over_mean = 3.0664;
+normal xpacks(over_mean, standard_deviation);
+cout << "fraction of packs >= " << under_weight
+<< " with a mean of " << xpacks.mean()
+ << " is " << cdf(complement(xpacks, under_weight)) << endl;
+// fraction of packs >= 2.9 with a mean of 3.06449 is 0.950005
+double under_fraction = 0.05; // so 95% are above the minimum weight mean - sd = 2.9
+double low_limit = standard_deviation;
+double offset = mean - low_limit - quantile(packs, under_fraction);
+double nominal_mean = mean + offset;
+
+normal nominal_packs(nominal_mean, standard_deviation);
+cout << "Setting the packer to " << nominal_mean << " will mean that "
+ << "fraction of packs >= " << under_weight
+ << " is " << cdf(complement(nominal_packs, under_weight)) << endl;
+
+/*`
+Setting the packer to 3.06449 will mean that fraction of packs >= 2.9 is 0.95.
+
+Setting the packer to 3.13263 will mean that fraction of packs >= 2.9 is 0.99,
+but will more than double the mean loss from 0.0644 to 0.133.
+
+Alternatively, we could invest in a better (more precise) packer with a lower standard deviation.
+
+To estimate how much better (how much smaller standard deviation) it would have to be,
+we need to get the 5% quantile to be located at the under_weight limit, 2.9
+*/
+double p = 0.05; // wanted p th quantile.
+cout << "Quantile of " << p << " = " << quantile(packs, p)
+ << ", mean = " << packs.mean() << ", sd = " << packs.standard_deviation() << endl; //
+/*`
+Quantile of 0.05 = 2.83551, mean = 3, sd = 0.1
+
+With the current packer (mean = 3, sd = 0.1), the 5% quantile is at 2.8551 kg,
+a little below our target of 2.9 kg.
+So we know that the standard deviation is going to have to be smaller.
+
+Let's start by guessing that it (now 0.1) needs to be halved, to a standard deviation of 0.05
+*/
+normal pack05(mean, 0.05);
+cout << "Quantile of " << p << " = " << quantile(pack05, p)
+ << ", mean = " << pack05.mean() << ", sd = " << pack05.standard_deviation() << endl;
+
+cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack05.standard_deviation()
+ << " is " << cdf(complement(pack05, under_weight)) << endl;
+//
+/*`
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.05 is 0.9772
+
+So 0.05 was quite a good guess, but we are a little over the 2.9 target,
+so the standard deviation could be a tiny bit more. So we could do some
+more guessing to get closer, say by increasing to 0.06
+*/
+
+normal pack06(mean, 0.06);
+cout << "Quantile of " << p << " = " << quantile(pack06, p)
+ << ", mean = " << pack06.mean() << ", sd = " << pack06.standard_deviation() << endl;
+
+cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack06.standard_deviation()
+ << " is " << cdf(complement(pack06, under_weight)) << endl;
+/*`
+Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.06 is 0.9522
+
+Now we are getting really close, but to do the job properly,
+we could use root finding method, for example the tools provided, and used elsewhere,
+in the Math Toolkit, see __root_finding_without_derivatives.
+
+But in this normal distribution case, we could be even smarter and make a direct calculation.
+*/
+
+normal s; // For standard normal distribution,
+double sd = 0.1;
+double x = 2.9; // Our required limit.
+// then probability p = N((x - mean) / sd)
+// So if we want to find the standard deviation that would be required to meet this limit,
+// so that the p th quantile is located at x,
+// in this case the 0.95 (95%) quantile at 2.9 kg pack weight, when the mean is 3 kg.
+
+double prob = pdf(s, (x - mean) / sd);
+double qp = quantile(s, 0.95);
+cout << "prob = " << prob << ", quantile(p) " << qp << endl; // p = 0.241971, quantile(p) 1.64485
+// Rearranging, we can directly calculate the required standard deviation:
+double sd95 = std::abs((x - mean)) / qp;
+
+cout << "If we want the "<< p << " th quantile to be located at "
+ << x << ", would need a standard deviation of " << sd95 << endl;
+
+normal pack95(mean, sd95); // Distribution of the 'ideal better' packer.
+cout <<"Fraction of packs >= " << under_weight << " with a mean of " << mean
+ << " and standard deviation of " << pack95.standard_deviation()
+ << " is " << cdf(complement(pack95, under_weight)) << endl;
+
+// Fraction of packs >= 2.9 with a mean of 3 and standard deviation of 0.0608 is 0.95
+
+/*`Notice that these two deceptively simple questions
+(do we over-fill or measure better) are actually very common.
+The weight of beef might be replaced by a measurement of more or less anything.
+But the calculations rely on the accuracy of the standard deviation - something
+that is almost always less good than we might wish,
+especially if based on a few measurements.
+*/
+
+//] [/normal_bulbs_example4 Quickbook end]
+ }
+
+ { // K. Krishnamoorthy, Handbook of Statistical Distributions with Applications,
+ // ISBN 1 58488 635 8, page 125, example 10.3.8
+//[normal_bulbs_example5
+/*`A bolt is usable if between 3.9 and 4.1 long.
+From a large batch of bolts, a sample of 50 show a
+mean length of 3.95 with standard deviation 0.1.
+Assuming a normal distribution, what proportion is usable?
+The true sample mean is unknown,
+but we can use the sample mean and standard deviation to find approximate solutions.
+*/
+
+ normal bolts(3.95, 0.1);
+ double top = 4.1;
+ double bottom = 3.9;
+
+cout << "Fraction long enough [ P(X <= " << top << ") ] is " << cdf(bolts, top) << endl;
+cout << "Fraction too short [ P(X <= " << bottom << ") ] is " << cdf(bolts, bottom) << endl;
+cout << "Fraction OK -between " << bottom << " and " << top
+ << "[ P(X <= " << top << ") - P(X<= " << bottom << " ) ] is "
+ << cdf(bolts, top) - cdf(bolts, bottom) << endl;
+
+cout << "Fraction too long [ P(X > " << top << ") ] is "
+ << cdf(complement(bolts, top)) << endl;
+
+cout << "95% of bolts are shorter than " << quantile(bolts, 0.95) << endl;
+
+//] [/normal_bulbs_example5 Quickbook end]
+ }
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+
+/*
+
+Output is:
+
+Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\normal_misc_examples.exe"
+Example: Normal distribution, Miscellaneous Applications.Standard normal distribution, mean = 0, standard deviation = 1
+Probability distribution function values
+ z pdf
+-4 0.00013383022576488537
+-3 0.0044318484119380075
+-2 0.053990966513188063
+-1 0.24197072451914337
+0 0.3989422804014327
+1 0.24197072451914337
+2 0.053990966513188063
+3 0.0044318484119380075
+4 0.00013383022576488537
+Standard normal mean = 0, standard deviation = 1
+Integral (area under the curve) from - infinity up to z
+ z cdf
+-4 3.1671241833119979e-005
+-3 0.0013498980316300959
+-2 0.022750131948179219
+-1 0.1586552539314571
+0 0.5
+1 0.84134474606854293
+2 0.97724986805182079
+3 0.9986501019683699
+4 0.99996832875816688
+Area for z = 2 is 0.97725
+95% of area has a z below 1.64485
+95% of area has a z between 1.95996 and -1.95996
+Significance level for z == 1 is 0.3173105078629142
+level of significance (alpha)
+2-sided 1 -sided z(alpha)
+0.3173 0.1587 1
+0.2 0.1 1.282
+0.1 0.05 1.645
+0.05 0.025 1.96
+0.01 0.005 2.576
+0.001 0.0005 3.291
+0.0001 5e-005 3.891
+1e-005 5e-006 4.417
+cdf(s, s.standard_deviation()) = 0.841
+cdf(complement(s, s.standard_deviation())) = 0.159
+Fraction 1 standard deviation within either side of mean is 0.683
+Fraction 2 standard deviations within either side of mean is 0.954
+Fraction 3 standard deviations within either side of mean is 0.997
+Fraction of bulbs that will last at best (<=) 1.00e+003 is 0.159
+Fraction of bulbs that will last at least (>) 1.00e+003 is 0.841
+Fraction of bulbs that will last between 900. and 1.20e+003 is 0.819
+Percentage of weeks overstocked 97.7
+Store should stock 156 sacks to meet 95% of demands.
+Store should stock 148 sacks to meet 8 out of 10 demands.
+Percentage of packs > 3.10 is 0.159
+fraction of packs <= 2.90 with a mean of 3.00 is 0.841
+fraction of packs >= 2.90 with a mean of 3.07 is 0.952
+Setting the packer to 3.06 will mean that fraction of packs >= 2.90 is 0.950
+Quantile of 0.0500 = 2.84, mean = 3.00, sd = 0.100
+Quantile of 0.0500 = 2.92, mean = 3.00, sd = 0.0500
+Fraction of packs >= 2.90 with a mean of 3.00 and standard deviation of 0.0500 is 0.977
+Quantile of 0.0500 = 2.90, mean = 3.00, sd = 0.0600
+Fraction of packs >= 2.90 with a mean of 3.00 and standard deviation of 0.0600 is 0.952
+prob = 0.242, quantile(p) 1.64
+If we want the 0.0500 th quantile to be located at 2.90, would need a standard deviation of 0.0608
+Fraction of packs >= 2.90 with a mean of 3.00 and standard deviation of 0.0608 is 0.950
+Fraction long enough [ P(X <= 4.10) ] is 0.933
+Fraction too short [ P(X <= 3.90) ] is 0.309
+Fraction OK -between 3.90 and 4.10[ P(X <= 4.10) - P(X<= 3.90 ) ] is 0.625
+Fraction too long [ P(X > 4.10) ] is 0.0668
+95% of bolts are shorter than 4.11
+
+*/
diff --git a/src/boost/libs/math/example/normal_tables.cpp b/src/boost/libs/math/example/normal_tables.cpp
new file mode 100644
index 000000000..e130f5fd4
--- /dev/null
+++ b/src/boost/libs/math/example/normal_tables.cpp
@@ -0,0 +1,566 @@
+
+// normal_misc_examples.cpp
+
+// Copyright Paul A. Bristow 2007, 2010, 2014, 2016.
+
+// 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)
+
+// Example of using normal distribution.
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+/*`
+First we need some includes to access the normal distribution
+(and some std output of course).
+*/
+
+#include <boost/cstdfloat.hpp> // MUST be first include!!!
+// See Implementation of Float128 type, Overloading template functions with float128_t.
+
+#include <boost/math/distributions/normal.hpp> // for normal_distribution.
+ using boost::math::normal; // typedef provides default type of double.
+
+#include <iostream>
+ //using std::cout; using std::endl;
+ //using std::left; using std::showpoint; using std::noshowpoint;
+#include <iomanip>
+ //using std::setw; using std::setprecision;
+#include <limits>
+ //using std::numeric_limits;
+
+ /*!
+Function max_digits10
+Returns maximum number of possibly significant decimal digits for a floating-point type FPT,
+even for older compilers/standard libraries that
+lack support for std::std::numeric_limits<FPT>::max_digits10,
+when the Kahan formula 2 + binary_digits * 0.3010 is used instead.
+Also provides the correct result for Visual Studio 2010 where the max_digits10 provided for float is wrong.
+*/
+namespace boost
+{
+namespace math
+{
+template <typename FPT>
+int max_digits10()
+{
+// Since max_digits10 is not defined (or wrong) on older systems, define a local max_digits10.
+
+ // Usage: int m = max_digits10<boost::float64_t>();
+ const int m =
+#if (defined BOOST_NO_CXX11_NUMERIC_LIMITS) || (_MSC_VER == 1600) // is wrongly 8 not 9 for VS2010.
+ 2 + std::numeric_limits<FPT>::digits * 3010/10000;
+#else
+ std::numeric_limits<FPT>::max_digits10;
+#endif
+ return m;
+}
+} // namespace math
+} // namespace boost
+
+template <typename FPT>
+void normal_table()
+{
+ using namespace boost::math;
+
+ FPT step = static_cast<FPT>(1.); // step in z.
+ FPT range = static_cast<FPT>(10.); // min and max z = -range to +range.
+
+ // Traditional tables are only computed to much lower precision.
+ // but @c std::std::numeric_limits<double>::max_digits10;
+ // on new Standard Libraries gives 17,
+ // the maximum number of digits from 64-bit double that can possibly be significant.
+ // @c std::std::numeric_limits<double>::digits10; == 15
+ // is number of @b guaranteed digits, the other two digits being 'noisy'.
+ // Here we use a custom version of max_digits10 which deals with those platforms
+ // where @c std::numeric_limits is not specialized,
+ // or @c std::numeric_limits<>::max_digits10 not implemented, or wrong.
+ int precision = boost::math::max_digits10<FPT>();
+
+// std::cout << typeid(FPT).name() << std::endl;
+// demo_normal.cpp:85: undefined reference to `typeinfo for __float128'
+// [@http://gcc.gnu.org/bugzilla/show_bug.cgi?id=43622 GCC 43622]
+// typeinfo for __float128 was missing GCC 4.9 Mar 2014, but OK for GCC 6.1.1.
+
+ // Construct a standard normal distribution s, with
+ // (default mean = zero, and standard deviation = unity)
+ normal s;
+ std::cout << "\nStandard normal distribution, mean = "<< s.mean()
+ << ", standard deviation = " << s.standard_deviation() << std::endl;
+
+ std::cout << "maxdigits_10 is " << precision
+ << ", digits10 is " << std::numeric_limits<FPT>::digits10 << std::endl;
+
+ std::cout << "Probability distribution function values" << std::endl;
+
+ std::cout << " z " " PDF " << std::endl;
+ for (FPT z = -range; z < range + step; z += step)
+ {
+ std::cout << std::left << std::setprecision(3) << std::setw(6) << z << " "
+ << std::setprecision(precision) << std::setw(12) << pdf(s, z) << std::endl;
+ }
+ std::cout.precision(6); // Restore to default precision.
+
+/*`And the area under the normal curve from -[infin] up to z,
+ the cumulative distribution function (CDF).
+*/
+ // For a standard normal distribution:
+ std::cout << "Standard normal mean = "<< s.mean()
+ << ", standard deviation = " << s.standard_deviation() << std::endl;
+ std::cout << "Integral (area under the curve) from - infinity up to z." << std::endl;
+ std::cout << " z " " CDF " << std::endl;
+ for (FPT z = -range; z < range + step; z += step)
+ {
+ std::cout << std::left << std::setprecision(3) << std::setw(6) << z << " "
+ << std::setprecision(precision) << std::setw(12) << cdf(s, z) << std::endl;
+ }
+ std::cout.precision(6); // Reset to default precision.
+} // template <typename FPT> void normal_table()
+
+int main()
+{
+ std::cout << "\nExample: Normal distribution tables." << std::endl;
+
+ using namespace boost::math;
+
+ try
+ {// Tip - always use try'n'catch blocks to ensure that messages from thrown exceptions are shown.
+
+//[normal_table_1
+#ifdef BOOST_FLOAT32_C
+ normal_table<boost::float32_t>(); // Usually type float
+#endif
+ normal_table<boost::float64_t>(); // Usually type double. Assume that float64_t is always available.
+#ifdef BOOST_FLOAT80_C
+ normal_table<boost::float80_t>(); // Type long double on some X86 platforms.
+#endif
+#ifdef BOOST_FLOAT128_C
+ normal_table<boost::float128_t>(); // Type _Quad on some Intel and __float128 on some GCC platforms.
+#endif
+ normal_table<boost::floatmax_t>();
+//] [/normal_table_1 ]
+ }
+ catch(std::exception ex)
+ {
+ std::cout << "exception thrown " << ex.what() << std::endl;
+ }
+
+ return 0;
+} // int main()
+
+
+/*
+
+GCC 4.8.1 with quadmath
+
+Example: Normal distribution tables.
+
+Standard normal distribution, mean = 0, standard deviation = 1
+maxdigits_10 is 9, digits10 is 6
+Probability distribution function values
+ z PDF
+-10 7.69459863e-023
+-9 1.02797736e-018
+-8 5.05227108e-015
+-7 9.13472041e-012
+-6 6.07588285e-009
+-5 1.48671951e-006
+-4 0.000133830226
+-3 0.00443184841
+-2 0.0539909665
+-1 0.241970725
+0 0.39894228
+1 0.241970725
+2 0.0539909665
+3 0.00443184841
+4 0.000133830226
+5 1.48671951e-006
+6 6.07588285e-009
+7 9.13472041e-012
+8 5.05227108e-015
+9 1.02797736e-018
+10 7.69459863e-023
+Standard normal mean = 0, standard deviation = 1
+Integral (area under the curve) from - infinity up to z.
+ z CDF
+-10 7.61985302e-024
+-9 1.12858841e-019
+-8 6.22096057e-016
+-7 1.27981254e-012
+-6 9.86587645e-010
+-5 2.86651572e-007
+-4 3.16712418e-005
+-3 0.00134989803
+-2 0.0227501319
+-1 0.158655254
+0 0.5
+1 0.841344746
+2 0.977249868
+3 0.998650102
+4 0.999968329
+5 0.999999713
+6 0.999999999
+7 1
+8 1
+9 1
+10 1
+
+Standard normal distribution, mean = 0, standard deviation = 1
+maxdigits_10 is 17, digits10 is 15
+Probability distribution function values
+ z PDF
+-10 7.6945986267064199e-023
+-9 1.0279773571668917e-018
+-8 5.0522710835368927e-015
+-7 9.1347204083645953e-012
+-6 6.0758828498232861e-009
+-5 1.4867195147342979e-006
+-4 0.00013383022576488537
+-3 0.0044318484119380075
+-2 0.053990966513188063
+-1 0.24197072451914337
+0 0.3989422804014327
+1 0.24197072451914337
+2 0.053990966513188063
+3 0.0044318484119380075
+4 0.00013383022576488537
+5 1.4867195147342979e-006
+6 6.0758828498232861e-009
+7 9.1347204083645953e-012
+8 5.0522710835368927e-015
+9 1.0279773571668917e-018
+10 7.6945986267064199e-023
+Standard normal mean = 0, standard deviation = 1
+Integral (area under the curve) from - infinity up to z.
+ z CDF
+-10 7.6198530241605945e-024
+-9 1.1285884059538422e-019
+-8 6.2209605742718204e-016
+-7 1.279812543885835e-012
+-6 9.865876450377014e-010
+-5 2.8665157187919455e-007
+-4 3.1671241833119972e-005
+-3 0.0013498980316300957
+-2 0.022750131948179216
+-1 0.15865525393145705
+0 0.5
+1 0.84134474606854293
+2 0.97724986805182079
+3 0.9986501019683699
+4 0.99996832875816688
+5 0.99999971334842808
+6 0.9999999990134123
+7 0.99999999999872013
+8 0.99999999999999933
+9 1
+10 1
+
+Standard normal distribution, mean = 0, standard deviation = 1
+maxdigits_10 is 21, digits10 is 18
+Probability distribution function values
+ z PDF
+-10 7.69459862670641993759e-023
+-9 1.0279773571668916523e-018
+-8 5.05227108353689273243e-015
+-7 9.13472040836459525705e-012
+-6 6.07588284982328608733e-009
+-5 1.48671951473429788965e-006
+-4 0.00013383022576488536764
+-3 0.00443184841193800752729
+-2 0.0539909665131880628364
+-1 0.241970724519143365328
+0 0.398942280401432702863
+1 0.241970724519143365328
+2 0.0539909665131880628364
+3 0.00443184841193800752729
+4 0.00013383022576488536764
+5 1.48671951473429788965e-006
+6 6.07588284982328608733e-009
+7 9.13472040836459525705e-012
+8 5.05227108353689273243e-015
+9 1.0279773571668916523e-018
+10 7.69459862670641993759e-023
+Standard normal mean = 0, standard deviation = 1
+Integral (area under the curve) from - infinity up to z.
+ z CDF
+-10 7.61985302416059451083e-024
+-9 1.12858840595384222719e-019
+-8 6.22096057427182035917e-016
+-7 1.279812543885834962e-012
+-6 9.86587645037701399241e-010
+-5 2.86651571879194547129e-007
+-4 3.16712418331199717608e-005
+-3 0.00134989803163009566139
+-2 0.0227501319481792155242
+-1 0.158655253931457046468
+0 0.5
+1 0.841344746068542925777
+2 0.977249868051820791415
+3 0.998650101968369896532
+4 0.999968328758166880021
+5 0.999999713348428076465
+6 0.999999999013412299576
+7 0.999999999998720134897
+8 0.999999999999999333866
+9 1
+10 1
+
+Standard normal distribution, mean = 0, standard deviation = 1
+maxdigits_10 is 36, digits10 is 34
+Probability distribution function values
+ z PDF
+-10 7.69459862670641993759264402330435296e-023
+-9 1.02797735716689165230378750485667109e-018
+-8 5.0522710835368927324337437844893081e-015
+-7 9.13472040836459525705208369548147081e-012
+-6 6.07588284982328608733411870229841611e-009
+-5 1.48671951473429788965346931561839483e-006
+-4 0.00013383022576488536764006964663309418
+-3 0.00443184841193800752728870762098267733
+-2 0.0539909665131880628363703067407186609
+-1 0.241970724519143365327522587904240936
+0 0.398942280401432702863218082711682655
+1 0.241970724519143365327522587904240936
+2 0.0539909665131880628363703067407186609
+3 0.00443184841193800752728870762098267733
+4 0.00013383022576488536764006964663309418
+5 1.48671951473429788965346931561839483e-006
+6 6.07588284982328608733411870229841611e-009
+7 9.13472040836459525705208369548147081e-012
+8 5.0522710835368927324337437844893081e-015
+9 1.02797735716689165230378750485667109e-018
+10 7.69459862670641993759264402330435296e-023
+Standard normal mean = 0, standard deviation = 1
+Integral (area under the curve) from - infinity up to z.
+ z CDF
+-10 7.61985302416059451083278826816793623e-024
+-9 1.1285884059538422271881384555435713e-019
+-8 6.22096057427182035917417257601387863e-016
+-7 1.27981254388583496200054074948511201e-012
+-6 9.86587645037701399241244820583623953e-010
+-5 2.86651571879194547128505464808623238e-007
+-4 3.16712418331199717608064048146587766e-005
+-3 0.001349898031630095661392854111682027
+-2 0.0227501319481792155241528519127314212
+-1 0.158655253931457046467912164189328905
+0 0.5
+1 0.841344746068542925776512220181757584
+2 0.977249868051820791414741051994496956
+3 0.998650101968369896532351503992686048
+4 0.999968328758166880021462930017150939
+5 0.999999713348428076464813329948810861
+6 0.999999999013412299575520592043176293
+7 0.999999999998720134897212119540199637
+8 0.999999999999999333866185224906075746
+9 1
+10 1
+
+Standard normal distribution, mean = 0, standard deviation = 1
+maxdigits_10 is 36, digits10 is 34
+Probability distribution function values
+ z PDF
+-10 7.69459862670641993759264402330435296e-023
+-9 1.02797735716689165230378750485667109e-018
+-8 5.0522710835368927324337437844893081e-015
+-7 9.13472040836459525705208369548147081e-012
+-6 6.07588284982328608733411870229841611e-009
+-5 1.48671951473429788965346931561839483e-006
+-4 0.00013383022576488536764006964663309418
+-3 0.00443184841193800752728870762098267733
+-2 0.0539909665131880628363703067407186609
+-1 0.241970724519143365327522587904240936
+0 0.398942280401432702863218082711682655
+1 0.241970724519143365327522587904240936
+2 0.0539909665131880628363703067407186609
+3 0.00443184841193800752728870762098267733
+4 0.00013383022576488536764006964663309418
+5 1.48671951473429788965346931561839483e-006
+6 6.07588284982328608733411870229841611e-009
+7 9.13472040836459525705208369548147081e-012
+8 5.0522710835368927324337437844893081e-015
+9 1.02797735716689165230378750485667109e-018
+10 7.69459862670641993759264402330435296e-023
+Standard normal mean = 0, standard deviation = 1
+Integral (area under the curve) from - infinity up to z.
+ z CDF
+-10 7.61985302416059451083278826816793623e-024
+-9 1.1285884059538422271881384555435713e-019
+-8 6.22096057427182035917417257601387863e-016
+-7 1.27981254388583496200054074948511201e-012
+-6 9.86587645037701399241244820583623953e-010
+-5 2.86651571879194547128505464808623238e-007
+-4 3.16712418331199717608064048146587766e-005
+-3 0.001349898031630095661392854111682027
+-2 0.0227501319481792155241528519127314212
+-1 0.158655253931457046467912164189328905
+0 0.5
+1 0.841344746068542925776512220181757584
+2 0.977249868051820791414741051994496956
+3 0.998650101968369896532351503992686048
+4 0.999968328758166880021462930017150939
+5 0.999999713348428076464813329948810861
+6 0.999999999013412299575520592043176293
+7 0.999999999998720134897212119540199637
+8 0.999999999999999333866185224906075746
+9 1
+10 1
+
+MSVC 2013 64-bit
+1>
+1> Example: Normal distribution tables.
+1>
+1> Standard normal distribution, mean = 0, standard deviation = 1
+1> maxdigits_10 is 9, digits10 is 6
+1> Probability distribution function values
+1> z PDF
+1> -10 7.69459863e-023
+1> -9 1.02797736e-018
+1> -8 5.05227108e-015
+1> -7 9.13472041e-012
+1> -6 6.07588285e-009
+1> -5 1.48671951e-006
+1> -4 0.000133830226
+1> -3 0.00443184841
+1> -2 0.0539909665
+1> -1 0.241970725
+1> 0 0.39894228
+1> 1 0.241970725
+1> 2 0.0539909665
+1> 3 0.00443184841
+1> 4 0.000133830226
+1> 5 1.48671951e-006
+1> 6 6.07588285e-009
+1> 7 9.13472041e-012
+1> 8 5.05227108e-015
+1> 9 1.02797736e-018
+1> 10 7.69459863e-023
+1> Standard normal mean = 0, standard deviation = 1
+1> Integral (area under the curve) from - infinity up to z.
+1> z CDF
+1> -10 7.61985302e-024
+1> -9 1.12858841e-019
+1> -8 6.22096057e-016
+1> -7 1.27981254e-012
+1> -6 9.86587645e-010
+1> -5 2.86651572e-007
+1> -4 3.16712418e-005
+1> -3 0.00134989803
+1> -2 0.0227501319
+1> -1 0.158655254
+1> 0 0.5
+1> 1 0.841344746
+1> 2 0.977249868
+1> 3 0.998650102
+1> 4 0.999968329
+1> 5 0.999999713
+1> 6 0.999999999
+1> 7 1
+1> 8 1
+1> 9 1
+1> 10 1
+1>
+1> Standard normal distribution, mean = 0, standard deviation = 1
+1> maxdigits_10 is 17, digits10 is 15
+1> Probability distribution function values
+1> z PDF
+1> -10 7.6945986267064199e-023
+1> -9 1.0279773571668917e-018
+1> -8 5.0522710835368927e-015
+1> -7 9.1347204083645953e-012
+1> -6 6.0758828498232861e-009
+1> -5 1.4867195147342979e-006
+1> -4 0.00013383022576488537
+1> -3 0.0044318484119380075
+1> -2 0.053990966513188063
+1> -1 0.24197072451914337
+1> 0 0.3989422804014327
+1> 1 0.24197072451914337
+1> 2 0.053990966513188063
+1> 3 0.0044318484119380075
+1> 4 0.00013383022576488537
+1> 5 1.4867195147342979e-006
+1> 6 6.0758828498232861e-009
+1> 7 9.1347204083645953e-012
+1> 8 5.0522710835368927e-015
+1> 9 1.0279773571668917e-018
+1> 10 7.6945986267064199e-023
+1> Standard normal mean = 0, standard deviation = 1
+1> Integral (area under the curve) from - infinity up to z.
+1> z CDF
+1> -10 7.6198530241605813e-024
+1> -9 1.1285884059538408e-019
+1> -8 6.2209605742718292e-016
+1> -7 1.2798125438858352e-012
+1> -6 9.8658764503770161e-010
+1> -5 2.8665157187919439e-007
+1> -4 3.1671241833119979e-005
+1> -3 0.0013498980316300957
+1> -2 0.022750131948179219
+1> -1 0.15865525393145707
+1> 0 0.5
+1> 1 0.84134474606854293
+1> 2 0.97724986805182079
+1> 3 0.9986501019683699
+1> 4 0.99996832875816688
+1> 5 0.99999971334842808
+1> 6 0.9999999990134123
+1> 7 0.99999999999872013
+1> 8 0.99999999999999933
+1> 9 1
+1> 10 1
+1>
+1> Standard normal distribution, mean = 0, standard deviation = 1
+1> maxdigits_10 is 17, digits10 is 15
+1> Probability distribution function values
+1> z PDF
+1> -10 7.6945986267064199e-023
+1> -9 1.0279773571668917e-018
+1> -8 5.0522710835368927e-015
+1> -7 9.1347204083645953e-012
+1> -6 6.0758828498232861e-009
+1> -5 1.4867195147342979e-006
+1> -4 0.00013383022576488537
+1> -3 0.0044318484119380075
+1> -2 0.053990966513188063
+1> -1 0.24197072451914337
+1> 0 0.3989422804014327
+1> 1 0.24197072451914337
+1> 2 0.053990966513188063
+1> 3 0.0044318484119380075
+1> 4 0.00013383022576488537
+1> 5 1.4867195147342979e-006
+1> 6 6.0758828498232861e-009
+1> 7 9.1347204083645953e-012
+1> 8 5.0522710835368927e-015
+1> 9 1.0279773571668917e-018
+1> 10 7.6945986267064199e-023
+1> Standard normal mean = 0, standard deviation = 1
+1> Integral (area under the curve) from - infinity up to z.
+1> z CDF
+1> -10 7.6198530241605813e-024
+1> -9 1.1285884059538408e-019
+1> -8 6.2209605742718292e-016
+1> -7 1.2798125438858352e-012
+1> -6 9.8658764503770161e-010
+1> -5 2.8665157187919439e-007
+1> -4 3.1671241833119979e-005
+1> -3 0.0013498980316300957
+1> -2 0.022750131948179219
+1> -1 0.15865525393145707
+1> 0 0.5
+1> 1 0.84134474606854293
+1> 2 0.97724986805182079
+1> 3 0.9986501019683699
+1> 4 0.99996832875816688
+1> 5 0.99999971334842808
+1> 6 0.9999999990134123
+1> 7 0.99999999999872013
+1> 8 0.99999999999999933
+1> 9 1
+1> 10 1
+
+
+*/
diff --git a/src/boost/libs/math/example/numerical_derivative_example.cpp b/src/boost/libs/math/example/numerical_derivative_example.cpp
new file mode 100644
index 000000000..214ed498e
--- /dev/null
+++ b/src/boost/libs/math/example/numerical_derivative_example.cpp
@@ -0,0 +1,209 @@
+// Copyright Christopher Kormanyos 2013.
+// 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).
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4996) // assignment operator could not be generated.
+#endif
+
+# include <iostream>
+# include <iomanip>
+# include <limits>
+# include <cmath>
+
+#include <boost/static_assert.hpp>
+#include <boost/type_traits/is_floating_point.hpp>
+#include <boost/math/special_functions/next.hpp> // for float_distance
+
+//[numeric_derivative_example
+/*`The following example shows how multiprecision calculations can be used to
+obtain full precision in a numerical derivative calculation that suffers from precision loss.
+
+Consider some well-known central difference rules for numerically
+computing the 1st derivative of a function [f'(x)] with [/x] real.
+
+Need a reference here? Introduction to Partial Differential Equations, Peter J. Olver
+ December 16, 2012
+
+Here, the implementation uses a C++ template that can be instantiated with various
+floating-point types such as `float`, `double`, `long double`, or even
+a user-defined floating-point type like __multiprecision.
+
+We will now use the derivative template with the built-in type `double` in
+order to numerically compute the derivative of a function, and then repeat
+with a 5 decimal digit higher precision user-defined floating-point type.
+
+Consider the function shown below.
+!!
+(3)
+We will now take the derivative of this function with respect to x evaluated
+at x = 3= 2. In other words,
+
+(4)
+
+The expected result is
+
+ 0:74535 59924 99929 89880 . (5)
+The program below uses the derivative template in order to perform
+the numerical calculation of this derivative. The program also compares the
+numerically-obtained result with the expected result and reports the absolute
+relative error scaled to a deviation that can easily be related to the number of
+bits of lost precision.
+
+*/
+
+/*` [note Requires the C++11 feature of
+[@http://en.wikipedia.org/wiki/Anonymous_function#C.2B.2B anonymous functions]
+for the derivative function calls like `[]( const double & x_) -> double`.
+*/
+
+
+
+template <typename value_type, typename function_type>
+value_type derivative (const value_type x, const value_type dx, function_type function)
+{
+ /*! \brief Compute the derivative of function using a 3-point central difference rule of O(dx^6).
+ \tparam value_type, floating-point type, for example: `double` or `cpp_dec_float_50`
+ \tparam function_type
+
+ \param x Value at which to evaluate derivative.
+ \param dx Incremental step-size.
+ \param function Function whose derivative is to computed.
+
+ \return derivative at x.
+ */
+
+ BOOST_STATIC_ASSERT_MSG(false == std::numeric_limits<value_type>::is_integer, "value_type must be a floating-point type!");
+
+ const value_type dx2(dx * 2U);
+ const value_type dx3(dx * 3U);
+ // Difference terms.
+ const value_type m1 ((function (x + dx) - function(x - dx)) / 2U);
+ const value_type m2 ((function (x + dx2) - function(x - dx2)) / 4U);
+ const value_type m3 ((function (x + dx3) - function(x - dx3)) / 6U);
+ const value_type fifteen_m1 (m1 * 15U);
+ const value_type six_m2 (m2 * 6U);
+ const value_type ten_dx (dx * 10U);
+ return ((fifteen_m1 - six_m2) + m3) / ten_dx; // Derivative.
+} //
+
+#include <boost/multiprecision/cpp_dec_float.hpp>
+ using boost::multiprecision::number;
+ using boost::multiprecision::cpp_dec_float;
+
+// Re-compute using 5 extra decimal digits precision (22) than double (17).
+#define MP_DIGITS10 unsigned (std::numeric_limits<double>::max_digits10 + 5)
+
+typedef cpp_dec_float<MP_DIGITS10> mp_backend;
+typedef number<mp_backend> mp_type;
+
+
+int main()
+{
+ {
+ const double d =
+ derivative
+ ( 1.5, // x = 3.2
+ std::ldexp (1., -9), // step size 2^-9 = see below for choice.
+ [](const double & x)->double // Function f(x).
+ {
+ return std::sqrt((x * x) - 1.) - std::acos(1. / x);
+ }
+ );
+
+ // The 'exactly right' result is [sqrt]5 / 3 = 0.74535599249992989880.
+ const double rel_error = (d - 0.74535599249992989880) / 0.74535599249992989880;
+ const double bit_error = std::abs(rel_error) / std::numeric_limits<double>::epsilon();
+ std::cout.precision (std::numeric_limits<double>::digits10); // Show all guaranteed decimal digits.
+ std::cout << std::showpoint ; // Ensure that any trailing zeros are shown too.
+
+ std::cout << " derivative : " << d << std::endl;
+ std::cout << " expected : " << 0.74535599249992989880 << std::endl;
+ // Can compute an 'exact' value using multiprecision type.
+ std::cout << " expected : " << sqrt(static_cast<mp_type>(5))/3U << std::endl;
+ std::cout << " bit_error : " << static_cast<unsigned long>(bit_error) << std::endl;
+
+ std::cout.precision(6);
+ std::cout << "float_distance = " << boost::math::float_distance(0.74535599249992989880, d) << std::endl;
+
+ }
+
+ { // Compute using multiprecision type with an extra 5 decimal digits of precision.
+ const mp_type mp =
+ derivative(mp_type(mp_type(3) / 2U), // x = 3/2
+ mp_type(mp_type(1) / 10000000U), // Step size 10^7.
+ [](const mp_type & x)->mp_type
+ {
+ return sqrt((x * x) - 1.) - acos (1. / x); // Function
+ }
+ );
+
+ const double d = mp.convert_to<double>(); // Convert to closest double.
+ const double rel_error = (d - 0.74535599249992989880) / 0.74535599249992989880;
+ const double bit_error = std::abs (rel_error) / std::numeric_limits<double>::epsilon();
+ std::cout.precision (std::numeric_limits <double>::digits10); // All guaranteed decimal digits.
+ std::cout << std::showpoint ; // Ensure that any trailing zeros are shown too.
+ std::cout << " derivative : " << d << std::endl;
+ // Can compute an 'exact' value using multiprecision type.
+ std::cout << " expected : " << sqrt(static_cast<mp_type>(5))/3U << std::endl;
+ std::cout << " expected : " << 0.74535599249992989880
+ << std::endl;
+ std::cout << " bit_error : " << static_cast<unsigned long>(bit_error) << std::endl;
+
+ std::cout.precision(6);
+ std::cout << "float_distance = " << boost::math::float_distance(0.74535599249992989880, d) << std::endl;
+
+
+ }
+
+
+} // int main()
+
+/*`
+The result of this program on a system with an eight-byte, 64-bit IEEE-754
+conforming floating-point representation for `double` is:
+
+ derivative : 0.745355992499951
+
+ derivative : 0.745355992499943
+ expected : 0.74535599249993
+ bit_error : 78
+
+ derivative : 0.745355992499930
+ expected : 0.745355992499930
+ bit_error : 0
+
+The resulting bit error is 0. This means that the result of the derivative
+calculation is bit-identical with the double representation of the expected result,
+and this is the best result possible for the built-in type.
+
+The derivative in this example has a known closed form. There are, however,
+countless situations in numerical analysis (and not only for numerical deriva-
+tives) for which the calculation at hand does not have a known closed-form
+solution or for which the closed-form solution is highly inconvenient to use. In
+such cases, this technique may be useful.
+
+This example has shown how multiprecision can be used to add extra digits
+to an ill-conditioned calculation that suffers from precision loss. When the result
+of the multiprecision calculation is converted to a built-in type such as double,
+the entire precision of the result in double is preserved.
+
+ */
+
+/*
+
+ Description: Autorun "J:\Cpp\big_number\Debug\numerical_derivative_example.exe"
+ derivative : 0.745355992499943
+ expected : 0.745355992499930
+ expected : 0.745355992499930
+ bit_error : 78
+ float_distance = 117.000
+ derivative : 0.745355992499930
+ expected : 0.745355992499930
+ expected : 0.745355992499930
+ bit_error : 0
+ float_distance = 0.000000
+
+ */
+
diff --git a/src/boost/libs/math/example/ooura_fourier_integrals_cosine_example.cpp b/src/boost/libs/math/example/ooura_fourier_integrals_cosine_example.cpp
new file mode 100644
index 000000000..2269202d3
--- /dev/null
+++ b/src/boost/libs/math/example/ooura_fourier_integrals_cosine_example.cpp
@@ -0,0 +1,83 @@
+// Copyright Paul A. Bristow, 2019
+// Copyright Nick Thompson, 2019
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+//#define BOOST_MATH_INSTRUMENT_OOURA // or -DBOOST_MATH_INSTRUMENT_OOURA etc for diagnostic output.
+
+#include <boost/math/quadrature/ooura_fourier_integrals.hpp> // For ooura_fourier_cos
+#include <boost/math/constants/constants.hpp> // For pi (including for multiprecision types, if used.)
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+#include <iostream>
+
+int main()
+{
+ try
+ {
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // Show all potentially significant digits.
+
+ using boost::math::quadrature::ooura_fourier_cos;
+ using boost::math::constants::half_pi;
+ using boost::math::constants::e;
+
+ //[ooura_fourier_integrals_cosine_example_1
+ auto integrator = ooura_fourier_cos<double>();
+ // Use the default tolerance root_epsilon and eight levels for type double.
+
+ auto f = [](double x)
+ { // More complex example function.
+ return 1 / (x * x + 1);
+ };
+
+ double omega = 1;
+
+ auto [result, relative_error] = integrator.integrate(f, omega);
+ std::cout << "Integral = " << result << ", relative error estimate " << relative_error << std::endl;
+
+ //] [/ooura_fourier_integrals_cosine_example_1]
+
+ //[ooura_fourier_integrals_cosine_example_2
+
+ constexpr double expected = half_pi<double>() / e<double>();
+ std::cout << "pi/(2e) = " << expected << ", difference " << result - expected << std::endl;
+ //] [/ooura_fourier_integrals_cosine_example_2]
+ }
+ catch (std::exception const & ex)
+ {
+ // Lacking try&catch blocks, the program will abort after any throw, whereas the
+ // message below from the thrown exception will give some helpful clues as to the cause of the problem.
+ std::cout << "\n""Message from thrown exception was:\n " << ex.what() << std::endl;
+ }
+
+} // int main()
+
+/*
+
+//[ooura_fourier_integrals_example_cosine_output_1
+``
+Integral = 0.57786367489546109, relative error estimate 6.4177395404415149e-09
+pi/(2e) = 0.57786367489546087, difference 2.2204460492503131e-16
+``
+//] [/ooura_fourier_integrals_example_cosine_output_1]
+
+
+//[ooura_fourier_integrals_example_cosine_diagnostic_output_1
+``
+ooura_fourier_cos with relative error goal 1.4901161193847656e-08 & 8 levels.
+epsilon for type = 2.2204460492503131e-16
+h = 1.000000000000000, I_h = 0.588268622591776 = 0x1.2d318b7e96dbe00p-1, absolute error estimate = nan
+h = 0.500000000000000, I_h = 0.577871642184837 = 0x1.27decab8f07b200p-1, absolute error estimate = 1.039698040693926e-02
+h = 0.250000000000000, I_h = 0.577863671186883 = 0x1.27ddbf42969be00p-1, absolute error estimate = 7.970997954576120e-06
+h = 0.125000000000000, I_h = 0.577863674895461 = 0x1.27ddbf6271dc000p-1, absolute error estimate = 3.708578555361441e-09
+Integral = 5.778636748954611e-01, relative error estimate 6.417739540441515e-09
+pi/(2e) = 5.778636748954609e-01, difference 2.220446049250313e-16
+``
+//] [/ooura_fourier_integrals_example_cosine_diagnostic_output_1]
+
+*/
diff --git a/src/boost/libs/math/example/ooura_fourier_integrals_example.cpp b/src/boost/libs/math/example/ooura_fourier_integrals_example.cpp
new file mode 100644
index 000000000..22a9d015a
--- /dev/null
+++ b/src/boost/libs/math/example/ooura_fourier_integrals_example.cpp
@@ -0,0 +1,83 @@
+// Copyright Paul A. Bristow, 2019
+// Copyright Nick Thompson, 2019
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#ifdef BOOST_NO_CXX11_LAMBDAS
+# error "This example requires a C++11 compiler that supports lambdas. Try C++11 or later."
+#endif
+
+//#define BOOST_MATH_INSTRUMENT_OOURA // or -DBOOST_MATH_INSTRUMENT_OOURA etc for diagnostics.
+
+#include <boost/math/quadrature/ooura_fourier_integrals.hpp>
+#include <boost/math/constants/constants.hpp> // For pi (including for multiprecision types, if used.)
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+#include <iostream>
+
+int main()
+{
+ try
+ {
+ std::cout.precision(std::numeric_limits<double>::max_digits10); // Show all potentially significant digits.
+
+ using boost::math::quadrature::ooura_fourier_sin;
+ using boost::math::constants::half_pi;
+
+//[ooura_fourier_integrals_example_1
+ ooura_fourier_sin<double>integrator = ooura_fourier_sin<double>();
+ // Use the default tolerance root_epsilon and eight levels for type double.
+
+ auto f = [](double x)
+ { // Simple reciprocal function for sinc.
+ return 1 / x;
+ };
+
+ double omega = 1;
+ std::pair<double, double> result = integrator.integrate(f, omega);
+ std::cout << "Integral = " << result.first << ", relative error estimate " << result.second << std::endl;
+
+//] [/ooura_fourier_integrals_example_1]
+
+//[ooura_fourier_integrals_example_2
+
+ constexpr double expected = half_pi<double>();
+ std::cout << "pi/2 = " << expected << ", difference " << result.first - expected << std::endl;
+//] [/ooura_fourier_integrals_example_2]
+ }
+ catch (std::exception const & ex)
+ {
+ // Lacking try&catch blocks, the program will abort after any throw, whereas the
+ // message below from the thrown exception will give some helpful clues as to the cause of the problem.
+ std::cout << "\n""Message from thrown exception was:\n " << ex.what() << std::endl;
+ }
+} // int main()
+
+/*
+
+//[ooura_fourier_integrals_example_output_1
+
+integral = 1.5707963267948966, relative error estimate 1.2655356398390254e-11
+pi/2 = 1.5707963267948966, difference 0
+
+//] [/ooura_fourier_integrals_example_output_1]
+
+
+//[ooura_fourier_integrals_example_diagnostic_output_1
+
+ooura_fourier_sin with relative error goal 1.4901161193847656e-08 & 8 levels.
+h = 1.000000000000000, I_h = 1.571890732004545 = 0x1.92676e56d853500p+0, absolute error estimate = nan
+h = 0.500000000000000, I_h = 1.570793292491940 = 0x1.921f825c076f600p+0, absolute error estimate = 1.097439512605325e-03
+h = 0.250000000000000, I_h = 1.570796326814776 = 0x1.921fb54458acf00p+0, absolute error estimate = 3.034322835882008e-06
+h = 0.125000000000000, I_h = 1.570796326794897 = 0x1.921fb54442d1800p+0, absolute error estimate = 1.987898734512328e-11
+Integral = 1.570796326794897e+00, relative error estimate 1.265535639839025e-11
+pi/2 = 1.570796326794897e+00, difference 0.000000000000000e+00
+
+//] [/ooura_fourier_integrals_example_diagnostic_output_1]
+
+*/
diff --git a/src/boost/libs/math/example/ooura_fourier_integrals_multiprecision_example.cpp b/src/boost/libs/math/example/ooura_fourier_integrals_multiprecision_example.cpp
new file mode 100644
index 000000000..f2ac13194
--- /dev/null
+++ b/src/boost/libs/math/example/ooura_fourier_integrals_multiprecision_example.cpp
@@ -0,0 +1,98 @@
+// Copyright Paul A. Bristow, 2019
+// Copyright Nick Thompson, 2019
+
+// Use, modification and distribution are subject to the
+// Boost Software License, Version 1.0.
+// (See accompanying file LICENSE_1_0.txt
+// or copy at http://www.boost.org/LICENSE_1_0.txt)
+
+#if !defined(__cpp_structured_bindings) || (__cpp_structured_bindings < 201606L)
+# error "This example requires a C++17 compiler that supports 'structured bindings'. Try /std:c++17 or -std=c++17 or later."
+#endif
+
+//#define BOOST_MATH_INSTRUMENT_OOURA // or -DBOOST_MATH_INSTRUMENT_OOURA etc for diagnostic output.
+
+#include <boost/math/quadrature/ooura_fourier_integrals.hpp>
+#include <boost/multiprecision/cpp_bin_float.hpp> // for cpp_bin_float_quad, cpp_bin_float_50...
+#include <boost/math/constants/constants.hpp> // For pi (including for multiprecision types, if used.)
+
+#include <cmath>
+#include <iostream>
+#include <limits>
+#include <iostream>
+#include <exception>
+
+int main()
+{
+ try
+ {
+ typedef boost::multiprecision::cpp_bin_float_quad Real;
+
+ std::cout.precision(std::numeric_limits<Real>::max_digits10); // Show all potentially significant digits.
+
+ using boost::math::quadrature::ooura_fourier_cos;
+ using boost::math::constants::half_pi;
+ using boost::math::constants::e;
+
+ //[ooura_fourier_integrals_multiprecision_example_1
+
+ // Use the default parameters for tolerance root_epsilon and eight levels for a type of 8 bytes.
+ //auto integrator = ooura_fourier_cos<Real>();
+ // Decide on a (tight) tolerance.
+ const Real tol = 2 * std::numeric_limits<Real>::epsilon();
+ auto integrator = ooura_fourier_cos<Real>(tol, 8); // Loops or gets worse for more than 8.
+
+ auto f = [](Real x)
+ { // More complex example function.
+ return 1 / (x * x + 1);
+ };
+
+ double omega = 1;
+ auto [result, relative_error] = integrator.integrate(f, omega);
+
+ //] [/ooura_fourier_integrals_multiprecision_example_1]
+
+ //[ooura_fourier_integrals_multiprecision_example_2
+ std::cout << "Integral = " << result << ", relative error estimate " << relative_error << std::endl;
+
+ const Real expected = half_pi<Real>() / e<Real>(); // Expect integral = 1/(2e)
+ std::cout << "pi/(2e) = " << expected << ", difference " << result - expected << std::endl;
+ //] [/ooura_fourier_integrals_multiprecision_example_2]
+ }
+ catch (std::exception const & ex)
+ {
+ // Lacking try&catch blocks, the program will abort after any throw, whereas the
+ // message below from the thrown exception will give some helpful clues as to the cause of the problem.
+ std::cout << "\n""Message from thrown exception was:\n " << ex.what() << std::endl;
+ }
+} // int main()
+
+/*
+
+//[ooura_fourier_integrals_example_multiprecision_output_1
+``
+Integral = 0.5778636748954608589550465916563501587, relative error estimate 4.609814684522163895264277312610830278e-17
+pi/(2e) = 0.5778636748954608659545328919193707407, difference -6.999486300263020581921171645255733758e-18
+``
+//] [/ooura_fourier_integrals_example_multiprecision_output_1]
+
+
+//[ooura_fourier_integrals_example_multiprecision_diagnostic_output_1
+``
+ooura_fourier_cos with relative error goal 3.851859888774471706111955885169854637e-34 & 15 levels.
+epsilon for type = 1.925929944387235853055977942584927319e-34
+h = 1.000000000000000000000000000000000, I_h = 0.588268622591776615359568690603776 = 0.5882686225917766153595686906037760, absolute error estimate = nan
+h = 0.500000000000000000000000000000000, I_h = 0.577871642184837461311756940493259 = 0.5778716421848374613117569404932595, absolute error estimate = 1.039698040693915404781175011051656e-02
+h = 0.250000000000000000000000000000000, I_h = 0.577863671186882539559996800783122 = 0.5778636711868825395599968007831220, absolute error estimate = 7.970997954921751760139710137450075e-06
+h = 0.125000000000000000000000000000000, I_h = 0.577863674895460885593491133506723 = 0.5778636748954608855934911335067232, absolute error estimate = 3.708578346033494332723601147051768e-09
+h = 0.062500000000000000000000000000000, I_h = 0.577863674895460858955046591656350 = 0.5778636748954608589550465916563502, absolute error estimate = 2.663844454185037302771663314961535e-17
+h = 0.031250000000000000000000000000000, I_h = 0.577863674895460858955046591656348 = 0.5778636748954608589550465916563484, absolute error estimate = 1.733336949948512267750380148326435e-33
+h = 0.015625000000000000000000000000000, I_h = 0.577863674895460858955046591656348 = 0.5778636748954608589550465916563479, absolute error estimate = 4.814824860968089632639944856462318e-34
+h = 0.007812500000000000000000000000000, I_h = 0.577863674895460858955046591656347 = 0.5778636748954608589550465916563473, absolute error estimate = 6.740754805355325485695922799047246e-34
+h = 0.003906250000000000000000000000000, I_h = 0.577863674895460858955046591656347 = 0.5778636748954608589550465916563475, absolute error estimate = 1.925929944387235853055977942584927e-34
+Integral = 5.778636748954608589550465916563475e-01, relative error estimate 3.332844800697411177051445985473052e-34
+pi/(2e) = 5.778636748954608589550465916563481e-01, difference -6.740754805355325485695922799047246e-34
+``
+//] [/ooura_fourier_integrals_example_multiprecision_diagnostic_output_1]
+
+*/
diff --git a/src/boost/libs/math/example/owens_t_example.cpp b/src/boost/libs/math/example/owens_t_example.cpp
new file mode 100644
index 000000000..6c6d20417
--- /dev/null
+++ b/src/boost/libs/math/example/owens_t_example.cpp
@@ -0,0 +1,113 @@
+// Copyright Benjamin Sobotta 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)
+
+#ifdef _MSC_VER
+# pragma warning(disable : 4127) // conditional expression is constant.
+#endif
+
+#include <boost/math/special_functions/owens_t.hpp>
+#include <iostream>
+
+int main()
+{
+ double h = 0.0,a;
+ std::cout << std::setprecision(20);
+
+ static const double a_vec[] = {
+ 0.5000000000000000E+00,
+ 0.1000000000000000E+01,
+ 0.2000000000000000E+01,
+ 0.3000000000000000E+01,
+ 0.5000000000000000E+00,
+ 0.1000000000000000E+01,
+ 0.2000000000000000E+01,
+ 0.3000000000000000E+01,
+ 0.5000000000000000E+00,
+ 0.1000000000000000E+01,
+ 0.2000000000000000E+01,
+ 0.3000000000000000E+01,
+ 0.5000000000000000E+00,
+ 0.1000000000000000E+01,
+ 0.2000000000000000E+01,
+ 0.3000000000000000E+01,
+ 0.5000000000000000E+00,
+ 0.1000000000000000E+01,
+ 0.2000000000000000E+01,
+ 0.3000000000000000E+01,
+ 0.1000000000000000E+02,
+ 0.1000000000000000E+03 };
+
+ static const double h_vec[] = {
+ 0.1000000000000000E+01,
+ 0.1000000000000000E+01,
+ 0.1000000000000000E+01,
+ 0.1000000000000000E+01,
+ 0.5000000000000000E+00,
+ 0.5000000000000000E+00,
+ 0.5000000000000000E+00,
+ 0.5000000000000000E+00,
+ 0.2500000000000000E+00,
+ 0.2500000000000000E+00,
+ 0.2500000000000000E+00,
+ 0.2500000000000000E+00,
+ 0.1250000000000000E+00,
+ 0.1250000000000000E+00,
+ 0.1250000000000000E+00,
+ 0.1250000000000000E+00,
+ 0.7812500000000000E-02,
+ 0.7812500000000000E-02,
+ 0.7812500000000000E-02,
+ 0.7812500000000000E-02,
+ 0.7812500000000000E-02,
+ 0.7812500000000000E-02 };
+
+ static const double t_vec[] = {
+ 0.4306469112078537E-01,
+ 0.6674188216570097E-01,
+ 0.7846818699308410E-01,
+ 0.7929950474887259E-01,
+ 0.6448860284750376E-01,
+ 0.1066710629614485E+00,
+ 0.1415806036539784E+00,
+ 0.1510840430760184E+00,
+ 0.7134663382271778E-01,
+ 0.1201285306350883E+00,
+ 0.1666128410939293E+00,
+ 0.1847501847929859E+00,
+ 0.7317273327500385E-01,
+ 0.1237630544953746E+00,
+ 0.1737438887583106E+00,
+ 0.1951190307092811E+00,
+ 0.7378938035365546E-01,
+ 0.1249951430754052E+00,
+ 0.1761984774738108E+00,
+ 0.1987772386442824E+00,
+ 0.2340886964802671E+00,
+ 0.2479460829231492E+00 };
+
+ for(unsigned i = 0; i != 22; ++i)
+ {
+ h = h_vec[i];
+ a = a_vec[i];
+ const double t = boost::math::owens_t(h, a);
+ std::cout << "h=" << h << "\ta=" << a << "\tcomp="
+ << t << "\ttab=" << t_vec[i]
+ << "\tdiff=" << std::fabs(t_vec[i]-t) << std::endl;;
+ }
+
+ return 0;
+}
+
+
+// EOF
+
+
+
+
+
+
+
+
diff --git a/src/boost/libs/math/example/policy_eg_1.cpp b/src/boost/libs/math/example/policy_eg_1.cpp
new file mode 100644
index 000000000..7f8d9fbb4
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_1.cpp
@@ -0,0 +1,70 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A> Bristow 2010
+// 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)
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <cerrno> // for ::errno
+
+//[policy_eg_1
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma;
+
+// Define the policy to use:
+using namespace boost::math::policies; // may be convenient, or
+
+using boost::math::policies::policy;
+// Types of error whose action can be altered by policies:.
+using boost::math::policies::evaluation_error;
+using boost::math::policies::domain_error;
+using boost::math::policies::overflow_error;
+using boost::math::policies::domain_error;
+using boost::math::policies::pole_error;
+// Actions on error (in enum error_policy_type):
+using boost::math::policies::errno_on_error;
+using boost::math::policies::ignore_error;
+using boost::math::policies::throw_on_error;
+using boost::math::policies::user_error;
+
+typedef policy<
+ domain_error<errno_on_error>,
+ pole_error<errno_on_error>,
+ overflow_error<errno_on_error>,
+ evaluation_error<errno_on_error>
+> c_policy;
+//
+// Now use the policy when calling tgamma:
+
+// http://msdn.microsoft.com/en-us/library/t3ayayh1.aspx
+// Microsoft errno declared in STDLIB.H as "extern int errno;"
+
+int main()
+{
+ errno = 0; // Reset.
+ cout << "Result of tgamma(30000) is: "
+ << tgamma(30000, c_policy()) << endl; // Too big parameter
+ cout << "errno = " << errno << endl; // errno 34 Numerical result out of range.
+ cout << "Result of tgamma(-10) is: "
+ << boost::math::tgamma(-10, c_policy()) << endl; // Negative parameter.
+ cout << "errno = " << errno << endl; // error 33 Numerical argument out of domain.
+} // int main()
+
+//]
+
+/* Output
+
+policy_eg_1.cpp
+ Generating code
+ Finished generating code
+ policy_eg_1.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\policy_eg_1.exe
+ Result of tgamma(30000) is: 1.#INF
+ errno = 34
+ Result of tgamma(-10) is: 1.#QNAN
+ errno = 33
+
+*/
+
+
diff --git a/src/boost/libs/math/example/policy_eg_10.cpp b/src/boost/libs/math/example/policy_eg_10.cpp
new file mode 100644
index 000000000..87f84c090
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_10.cpp
@@ -0,0 +1,183 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[policy_eg_10
+
+/*`
+
+To understand how the rounding policies for
+the discrete distributions can be used, we'll
+use the 50-sample binomial distribution with a
+success fraction of 0.5 once again, and calculate
+all the possible quantiles at 0.05 and 0.95.
+
+Begin by including the needed headers (and some using statements for conciseness):
+
+*/
+#include <iostream>
+using std::cout; using std::endl;
+using std::left; using std::fixed; using std::right; using std::scientific;
+#include <iomanip>
+using std::setw;
+using std::setprecision;
+
+#include <boost/math/distributions/binomial.hpp>
+/*`
+
+Next we'll bring the needed declarations into scope, and
+define distribution types for all the available rounding policies:
+
+*/
+// Avoid
+// using namespace std; // and
+// using namespace boost::math;
+// to avoid potential ambiguity of names, like binomial.
+// using namespace boost::math::policies; is small risk, but
+// the necessary items are brought into scope thus:
+
+using boost::math::binomial_distribution;
+using boost::math::policies::policy;
+using boost::math::policies::discrete_quantile;
+
+using boost::math::policies::integer_round_outwards;
+using boost::math::policies::integer_round_down;
+using boost::math::policies::integer_round_up;
+using boost::math::policies::integer_round_nearest;
+using boost::math::policies::integer_round_inwards;
+using boost::math::policies::real;
+
+using boost::math::binomial_distribution; // Not std::binomial_distribution.
+
+typedef binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_outwards> > >
+ binom_round_outwards;
+
+typedef binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_inwards> > >
+ binom_round_inwards;
+
+typedef binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_down> > >
+ binom_round_down;
+
+typedef binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_up> > >
+ binom_round_up;
+
+typedef binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_nearest> > >
+ binom_round_nearest;
+
+typedef binomial_distribution<
+ double,
+ policy<discrete_quantile<real> > >
+ binom_real_quantile;
+
+/*`
+Now let's set to work calling those quantiles:
+*/
+
+int main()
+{
+ cout <<
+ "Testing rounding policies for a 50 sample binomial distribution,\n"
+ "with a success fraction of 0.5.\n\n"
+ "Lower quantiles are calculated at p = 0.05\n\n"
+ "Upper quantiles at p = 0.95.\n\n";
+
+ cout << setw(25) << right
+ << "Policy"<< setw(18) << right
+ << "Lower Quantile" << setw(18) << right
+ << "Upper Quantile" << endl;
+
+ // Test integer_round_outwards:
+ cout << setw(25) << right
+ << "integer_round_outwards"
+ << setw(18) << right
+ << quantile(binom_round_outwards(50, 0.5), 0.05)
+ << setw(18) << right
+ << quantile(binom_round_outwards(50, 0.5), 0.95)
+ << endl;
+
+ // Test integer_round_inwards:
+ cout << setw(25) << right
+ << "integer_round_inwards"
+ << setw(18) << right
+ << quantile(binom_round_inwards(50, 0.5), 0.05)
+ << setw(18) << right
+ << quantile(binom_round_inwards(50, 0.5), 0.95)
+ << endl;
+
+ // Test integer_round_down:
+ cout << setw(25) << right
+ << "integer_round_down"
+ << setw(18) << right
+ << quantile(binom_round_down(50, 0.5), 0.05)
+ << setw(18) << right
+ << quantile(binom_round_down(50, 0.5), 0.95)
+ << endl;
+
+ // Test integer_round_up:
+ cout << setw(25) << right
+ << "integer_round_up"
+ << setw(18) << right
+ << quantile(binom_round_up(50, 0.5), 0.05)
+ << setw(18) << right
+ << quantile(binom_round_up(50, 0.5), 0.95)
+ << endl;
+
+ // Test integer_round_nearest:
+ cout << setw(25) << right
+ << "integer_round_nearest"
+ << setw(18) << right
+ << quantile(binom_round_nearest(50, 0.5), 0.05)
+ << setw(18) << right
+ << quantile(binom_round_nearest(50, 0.5), 0.95)
+ << endl;
+
+ // Test real:
+ cout << setw(25) << right
+ << "real"
+ << setw(18) << right
+ << quantile(binom_real_quantile(50, 0.5), 0.05)
+ << setw(18) << right
+ << quantile(binom_real_quantile(50, 0.5), 0.95)
+ << endl;
+} // int main()
+
+/*`
+
+Which produces the program output:
+
+[pre
+ policy_eg_10.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\policy_eg_10.exe
+ Testing rounding policies for a 50 sample binomial distribution,
+ with a success fraction of 0.5.
+
+ Lower quantiles are calculated at p = 0.05
+
+ Upper quantiles at p = 0.95.
+
+ Policy Lower Quantile Upper Quantile
+ integer_round_outwards 18 31
+ integer_round_inwards 19 30
+ integer_round_down 18 30
+ integer_round_up 19 31
+ integer_round_nearest 19 30
+ real 18.701 30.299
+]
+
+*/
+
+//] //[policy_eg_10] ends quickbook import.
diff --git a/src/boost/libs/math/example/policy_eg_2.cpp b/src/boost/libs/math/example/policy_eg_2.cpp
new file mode 100644
index 000000000..3ab8312e8
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_2.cpp
@@ -0,0 +1,65 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <cerrno> // for ::errno
+
+//[policy_eg_2
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma;
+
+int main()
+{
+ // using namespace boost::math::policies; // or
+ using boost::math::policies::errno_on_error;
+ using boost::math::policies::make_policy;
+ using boost::math::policies::pole_error;
+ using boost::math::policies::domain_error;
+ using boost::math::policies::overflow_error;
+ using boost::math::policies::evaluation_error;
+
+ errno = 0;
+ std::cout << "Result of tgamma(30000) is: "
+ << boost::math::tgamma(
+ 30000,
+ make_policy(
+ domain_error<errno_on_error>(),
+ pole_error<errno_on_error>(),
+ overflow_error<errno_on_error>(),
+ evaluation_error<errno_on_error>()
+ )
+ ) << std::endl;
+ // Check errno was set:
+ std::cout << "errno = " << errno << std::endl;
+ // and again with evaluation at a pole:
+ std::cout << "Result of tgamma(-10) is: "
+ << boost::math::tgamma(
+ -10,
+ make_policy(
+ domain_error<errno_on_error>(),
+ pole_error<errno_on_error>(),
+ overflow_error<errno_on_error>(),
+ evaluation_error<errno_on_error>()
+ )
+ ) << std::endl;
+ // Check errno was set:
+ std::cout << "errno = " << errno << std::endl;
+}
+
+//] //[/policy_eg_2]
+
+/*
+
+Output:
+
+ Result of tgamma(30000) is: 1.#INF
+ errno = 34
+ Result of tgamma(-10) is: 1.#QNAN
+ errno = 33
+*/
+
diff --git a/src/boost/libs/math/example/policy_eg_3.cpp b/src/boost/libs/math/example/policy_eg_3.cpp
new file mode 100644
index 000000000..adf8c9e44
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_3.cpp
@@ -0,0 +1,55 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2007, 2010.
+
+// 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)
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4305) // 'initializing' : truncation from 'long double' to 'const eval_type'
+# pragma warning (disable : 4244) // conversion from 'long double' to 'const eval_type'
+#endif
+
+#include <iostream>
+using std::cout; using std::endl;
+
+//[policy_eg_3
+
+#include <boost/math/distributions/binomial.hpp>
+using boost::math::binomial_distribution;
+
+// Begin by defining a policy type, that gives the behaviour we want:
+
+//using namespace boost::math::policies; or explicitly
+using boost::math::policies::policy;
+
+using boost::math::policies::promote_float;
+using boost::math::policies::discrete_quantile;
+using boost::math::policies::integer_round_nearest;
+
+typedef policy<
+ promote_float<false>, // Do not promote to double.
+ discrete_quantile<integer_round_nearest> // Round result to nearest integer.
+> mypolicy;
+//
+// Then define a new distribution that uses it:
+typedef boost::math::binomial_distribution<float, mypolicy> mybinom;
+
+// And now use it to get the quantile:
+
+int main()
+{
+ cout << "quantile(mybinom(200, 0.25), 0.05) is: " <<
+ quantile(mybinom(200, 0.25), 0.05) << endl;
+}
+
+//]
+
+/*
+
+Output:
+
+ quantile(mybinom(200, 0.25), 0.05) is: 40
+
+*/
+
diff --git a/src/boost/libs/math/example/policy_eg_4.cpp b/src/boost/libs/math/example/policy_eg_4.cpp
new file mode 100644
index 000000000..5cd281618
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_4.cpp
@@ -0,0 +1,107 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <cerrno> // for ::errno
+
+//[policy_eg_4
+
+/*`
+Suppose we want `C::foo()` to behave in a C-compatible way and set
+`::errno` on error rather than throwing any exceptions.
+
+We'll begin by including the needed header for our function:
+*/
+
+#include <boost/math/special_functions.hpp>
+//using boost::math::tgamma; // Not needed because using C::tgamma.
+
+/*`
+Open up the "C" namespace that we'll use for our functions, and
+define the policy type we want: in this case a C-style one that sets
+::errno and returns a standard value, rather than throwing exceptions.
+
+Any policies we don't specify here will inherit the defaults.
+*/
+
+namespace C
+{ // To hold our C-style policy.
+ //using namespace boost::math::policies; or explicitly:
+ using boost::math::policies::policy;
+
+ using boost::math::policies::domain_error;
+ using boost::math::policies::pole_error;
+ using boost::math::policies::overflow_error;
+ using boost::math::policies::evaluation_error;
+ using boost::math::policies::errno_on_error;
+
+ typedef policy<
+ domain_error<errno_on_error>,
+ pole_error<errno_on_error>,
+ overflow_error<errno_on_error>,
+ evaluation_error<errno_on_error>
+ > c_policy;
+
+/*`
+All we need do now is invoke the BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS
+macro passing our policy type c_policy as the single argument:
+*/
+
+BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(c_policy)
+
+} // close namespace C
+
+/*`
+We now have a set of forwarding functions defined in namespace C
+that all look something like this:
+
+``
+template <class RealType>
+inline typename boost::math::tools::promote_args<RT>::type
+ tgamma(RT z)
+{
+ return boost::math::tgamma(z, c_policy());
+}
+``
+
+So that when we call `C::tgamma(z)`, we really end up calling
+`boost::math::tgamma(z, C::c_policy())`:
+*/
+
+int main()
+{
+ errno = 0;
+ cout << "Result of tgamma(30000) is: "
+ << C::tgamma(30000) << endl; // Note using C::tgamma
+ cout << "errno = " << errno << endl; // errno = 34
+ cout << "Result of tgamma(-10) is: "
+ << C::tgamma(-10) << endl;
+ cout << "errno = " << errno << endl; // errno = 33, overwriting previous value of 34.
+}
+
+/*`
+
+Which outputs:
+
+[pre
+Result of C::tgamma(30000) is: 1.#INF
+errno = 34
+Result of C::tgamma(-10) is: 1.#QNAN
+errno = 33
+]
+
+This mechanism is particularly useful when we want to define a project-wide policy,
+and don't want to modify the Boost source,
+or to set project wide build macros (possibly fragile and easy to forget).
+
+*/
+//] //[/policy_eg_4]
+
diff --git a/src/boost/libs/math/example/policy_eg_5.cpp b/src/boost/libs/math/example/policy_eg_5.cpp
new file mode 100644
index 000000000..d022c9c85
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_5.cpp
@@ -0,0 +1,66 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <cerrno> // for ::errno
+
+//[policy_eg_5
+
+#include <boost/math/special_functions.hpp>
+// using boost::math::tgamma; // Would create an ambiguity between
+// 'double boost::math::tgamma<int>(T)' and
+// 'double 'anonymous-namespace'::tgamma<int>(RT)'.
+
+namespace mymath
+{ // unnamed
+
+using namespace boost::math::policies;
+
+typedef policy<
+ domain_error<errno_on_error>,
+ pole_error<errno_on_error>,
+ overflow_error<errno_on_error>,
+ evaluation_error<errno_on_error>
+> c_policy;
+
+BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(c_policy)
+
+/*`
+So that when we call `mymath::tgamma(z)`, we really end up calling
+ `boost::math::tgamma(z, anonymous-namespace::c_policy())`.
+*/
+
+} // close unnamed namespace
+
+int main()
+{
+ errno = 0;
+ cout << "Result of tgamma(30000) is: "
+ << mymath::tgamma(30000) << endl;
+ // tgamma in unnamed namespace in this translation unit (file) only.
+ cout << "errno = " << errno << endl;
+ cout << "Result of tgamma(-10) is: "
+ << mymath::tgamma(-10) << endl;
+ cout << "errno = " << errno << endl;
+ // Default tgamma policy would throw an exception, and abort.
+}
+
+//] //[/policy_eg_5]
+
+/*
+Output:
+
+ Result of tgamma(30000) is: 1.#INF
+ errno = 34
+ Result of tgamma(-10) is: 1.#QNAN
+ errno = 33
+
+
+*/
diff --git a/src/boost/libs/math/example/policy_eg_6.cpp b/src/boost/libs/math/example/policy_eg_6.cpp
new file mode 100644
index 000000000..57f92fccc
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_6.cpp
@@ -0,0 +1,121 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <cerrno> // for ::errno
+
+//[policy_eg_6
+
+/*`
+Suppose we want a set of distributions to behave as follows:
+
+* Return infinity on overflow, rather than throwing an exception.
+* Don't perform any promotion from double to long double internally.
+* Return the closest integer result from the quantiles of discrete
+distributions.
+
+We'll begin by including the needed header for all the distributions:
+*/
+
+#include <boost/math/distributions.hpp>
+
+/*`
+
+Open up an appropriate namespace, calling it `my_distributions`,
+for our distributions, and define the policy type we want.
+Any policies we don't specify here will inherit the defaults:
+
+*/
+
+namespace my_distributions
+{
+ using namespace boost::math::policies;
+ // using boost::math::policies::errno_on_error; // etc.
+
+ typedef policy<
+ // return infinity and set errno rather than throw:
+ overflow_error<errno_on_error>,
+ // Don't promote double -> long double internally:
+ promote_double<false>,
+ // Return the closest integer result for discrete quantiles:
+ discrete_quantile<integer_round_nearest>
+ > my_policy;
+
+/*`
+
+All we need do now is invoke the BOOST_MATH_DECLARE_DISTRIBUTIONS
+macro passing the floating point type `double` and policy types `my_policy` as arguments:
+
+*/
+
+BOOST_MATH_DECLARE_DISTRIBUTIONS(double, my_policy)
+
+} // close namespace my_namespace
+
+/*`
+
+We now have a set of typedefs defined in namespace my_distributions
+that all look something like this:
+
+``
+typedef boost::math::normal_distribution<double, my_policy> normal;
+typedef boost::math::cauchy_distribution<double, my_policy> cauchy;
+typedef boost::math::gamma_distribution<double, my_policy> gamma;
+// etc
+``
+
+So that when we use my_distributions::normal we really end up using
+`boost::math::normal_distribution<double, my_policy>`:
+
+*/
+
+int main()
+{
+ // Construct distribution with something we know will overflow
+ // (using double rather than if promoted to long double):
+ my_distributions::normal norm(10, 2);
+
+ errno = 0;
+ cout << "Result of quantile(norm, 0) is: "
+ << quantile(norm, 0) << endl; // -infinity.
+ cout << "errno = " << errno << endl;
+ errno = 0;
+ cout << "Result of quantile(norm, 1) is: "
+ << quantile(norm, 1) << endl; // +infinity.
+ cout << "errno = " << errno << endl;
+
+ // Now try a discrete distribution.
+ my_distributions::binomial binom(20, 0.25);
+ cout << "Result of quantile(binom, 0.05) is: "
+ << quantile(binom, 0.05) << endl; // To check we get integer results.
+ cout << "Result of quantile(complement(binom, 0.05)) is: "
+ << quantile(complement(binom, 0.05)) << endl;
+}
+
+/*`
+
+Which outputs:
+
+[pre
+Result of quantile(norm, 0) is: -1.#INF
+errno = 34
+Result of quantile(norm, 1) is: 1.#INF
+errno = 34
+Result of quantile(binom, 0.05) is: 1
+Result of quantile(complement(binom, 0.05)) is: 8
+]
+
+This mechanism is particularly useful when we want to define a
+project-wide policy, and don't want to modify the Boost source
+or set project wide build macros (possibly fragile and easy to forget).
+
+*/
+//] //[/policy_eg_6]
+
diff --git a/src/boost/libs/math/example/policy_eg_7.cpp b/src/boost/libs/math/example/policy_eg_7.cpp
new file mode 100644
index 000000000..2865bea36
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_7.cpp
@@ -0,0 +1,73 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <cerrno> // for ::errno
+
+//[policy_eg_7
+
+#include <boost/math/distributions.hpp> // All distributions.
+// using boost::math::normal; // Would create an ambiguity between
+// boost::math::normal_distribution<RealType> boost::math::normal and
+// 'anonymous-namespace'::normal'.
+
+namespace
+{ // anonymous or unnamed (rather than named as in policy_eg_6.cpp).
+
+ using namespace boost::math::policies;
+ // using boost::math::policies::errno_on_error; // etc.
+ typedef policy<
+ // return infinity and set errno rather than throw:
+ overflow_error<errno_on_error>,
+ // Don't promote double -> long double internally:
+ promote_double<false>,
+ // Return the closest integer result for discrete quantiles:
+ discrete_quantile<integer_round_nearest>
+ > my_policy;
+
+ BOOST_MATH_DECLARE_DISTRIBUTIONS(double, my_policy)
+
+} // close namespace my_namespace
+
+int main()
+{
+ // Construct distribution with something we know will overflow.
+ normal norm(10, 2); // using 'anonymous-namespace'::normal
+ errno = 0;
+ cout << "Result of quantile(norm, 0) is: "
+ << quantile(norm, 0) << endl;
+ cout << "errno = " << errno << endl;
+ errno = 0;
+ cout << "Result of quantile(norm, 1) is: "
+ << quantile(norm, 1) << endl;
+ cout << "errno = " << errno << endl;
+ //
+ // Now try a discrete distribution:
+ binomial binom(20, 0.25);
+ cout << "Result of quantile(binom, 0.05) is: "
+ << quantile(binom, 0.05) << endl;
+ cout << "Result of quantile(complement(binom, 0.05)) is: "
+ << quantile(complement(binom, 0.05)) << endl;
+}
+
+//] //[/policy_eg_7]
+
+/*
+
+Output:
+
+ Result of quantile(norm, 0) is: -1.#INF
+ errno = 34
+ Result of quantile(norm, 1) is: 1.#INF
+ errno = 34
+ Result of quantile(binom, 0.05) is: 1
+ Result of quantile(complement(binom, 0.05)) is: 8
+
+*/
diff --git a/src/boost/libs/math/example/policy_eg_8.cpp b/src/boost/libs/math/example/policy_eg_8.cpp
new file mode 100644
index 000000000..775f042e2
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_8.cpp
@@ -0,0 +1,133 @@
+// Copyright John Maddock 2007.
+// Copyright Paul a. Bristow 2010
+// 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)
+
+// 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 : 4100) // unreferenced formal parameters
+#endif
+
+#include <iostream>
+using std::cout; using std::endl; using std::cerr;
+
+//[policy_eg_8
+
+/*`
+Suppose we want our own user-defined error handlers rather than the
+any of the default ones supplied by the library to be used.
+If we set the policy for a specific type of error to `user_error`
+then the library will call a user-supplied error handler.
+These are forward declared, but not defined in
+boost/math/policies/error_handling.hpp like this:
+
+ namespace boost{ namespace math{ namespace policies{
+
+ template <class T>
+ T user_domain_error(const char* function, const char* message, const T& val);
+ template <class T>
+ T user_pole_error(const char* function, const char* message, const T& val);
+ template <class T>
+ T user_overflow_error(const char* function, const char* message, const T& val);
+ template <class T>
+ T user_underflow_error(const char* function, const char* message, const T& val);
+ template <class T>
+ T user_denorm_error(const char* function, const char* message, const T& val);
+ template <class T>
+ T user_evaluation_error(const char* function, const char* message, const T& val);
+ template <class T, class TargetType>
+ T user_rounding_error(const char* function, const char* message, const T& val, const TargetType& t);
+ template <class T>
+ T user_indeterminate_result_error(const char* function, const char* message, const T& val);
+
+ }}} // namespaces
+
+So out first job is to include the header we want to use, and then
+provide definitions for our user-defined error handlers that we want to use.
+We only provide our special domain and pole error handlers;
+other errors like overflow and underflow use the default.
+*/
+
+#include <boost/math/special_functions.hpp>
+
+namespace boost{ namespace math
+{
+ namespace policies
+ {
+ template <class T>
+ T user_domain_error(const char* function, const char* message, const T& val)
+ { // Ignoring function, message and val for this example, perhaps unhelpfully.
+ cerr << "Domain Error!" << endl;
+ return std::numeric_limits<T>::quiet_NaN();
+ }
+
+ template <class T>
+ T user_pole_error(const char* function, const char* message, const T& val)
+ { // Ignoring function, message and val for this example, perhaps unhelpfully.
+ cerr << "Pole Error!" << endl;
+ return std::numeric_limits<T>::quiet_NaN();
+ }
+ } // namespace policies
+}} // namespace boost{ namespace math
+
+
+/*`
+Now we'll need to define a suitable policy that will call these handlers,
+and define some forwarding functions that make use of the policy:
+*/
+
+namespace mymath{
+
+using namespace boost::math::policies;
+
+typedef policy<
+ domain_error<user_error>,
+ pole_error<user_error>
+> user_error_policy;
+
+BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(user_error_policy)
+
+} // close unnamed namespace
+
+/*`
+We now have a set of forwarding functions defined in namespace mymath
+that all look something like this:
+
+``
+template <class RealType>
+inline typename boost::math::tools::promote_args<RT>::type
+ tgamma(RT z)
+{
+ return boost::math::tgamma(z, user_error_policy());
+}
+``
+
+So that when we call `mymath::tgamma(z)` we really end up calling
+`boost::math::tgamma(z, user_error_policy())`, and any
+errors will get directed to our own error handlers.
+*/
+
+int main()
+{
+ cout << "Result of erf_inv(-10) is: "
+ << mymath::erf_inv(-10) << endl;
+ cout << "Result of tgamma(-10) is: "
+ << mymath::tgamma(-10) << endl;
+}
+
+/*`
+
+Which outputs:
+
+[pre
+ Domain Error!
+ Pole Error!
+ Result of erf_inv(-10) is: 1.#QNAN
+ Result of tgamma(-10) is: 1.#QNAN
+]
+*/
+
+//] // //[/policy_eg_8]
diff --git a/src/boost/libs/math/example/policy_eg_9.cpp b/src/boost/libs/math/example/policy_eg_9.cpp
new file mode 100644
index 000000000..dceda875c
--- /dev/null
+++ b/src/boost/libs/math/example/policy_eg_9.cpp
@@ -0,0 +1,313 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+#include <boost/format.hpp>
+using std::cout; using std::endl; using std::cerr;
+
+//[policy_eg_9
+
+/*`
+The previous example was all well and good, but the custom error handlers
+didn't really do much of any use. In this example we'll implement all
+the custom handlers and show how the information provided to them can be
+used to generate nice formatted error messages.
+
+Each error handler has the general form:
+
+ template <class T>
+ T user_``['error_type]``(
+ const char* function,
+ const char* message,
+ const T& val);
+
+and accepts three arguments:
+
+[variablelist
+[[const char* function]
+ [The name of the function that raised the error, this string
+ contains one or more %1% format specifiers that should be
+ replaced by the name of real type T, like float or double.]]
+[[const char* message]
+ [A message associated with the error, normally this
+ contains a %1% format specifier that should be replaced with
+ the value of ['value]: however note that overflow and underflow messages
+ do not contain this %1% specifier (since the value of ['value] is
+ immaterial in these cases).]]
+[[const T& value]
+ [The value that caused the error: either an argument to the function
+ if this is a domain or pole error, the tentative result
+ if this is a denorm or evaluation error, or zero or infinity for
+ underflow or overflow errors.]]
+]
+
+As before we'll include the headers we need first:
+
+*/
+
+#include <boost/math/special_functions.hpp>
+
+/*`
+Next we'll implement our own error handlers for each type of error,
+starting with domain errors:
+*/
+
+namespace boost{ namespace math{
+namespace policies
+{
+
+template <class T>
+T user_domain_error(const char* function, const char* message, const T& val)
+{
+ /*`
+ We'll begin with a bit of defensive programming in case function or message are empty:
+ */
+ if(function == 0)
+ function = "Unknown function with arguments of type %1%";
+ if(message == 0)
+ message = "Cause unknown with bad argument %1%";
+ /*`
+ Next we'll format the name of the function with the name of type T, perhaps double:
+ */
+ std::string msg("Error in function ");
+ msg += (boost::format(function) % typeid(T).name()).str();
+ /*`
+ Then likewise format the error message with the value of parameter /val/,
+ making sure we output all the potentially significant digits of /val/:
+ */
+ msg += ": \n";
+ int prec = 2 + (std::numeric_limits<T>::digits * 30103UL) / 100000UL;
+ // int prec = std::numeric_limits<T>::max_digits10; // For C++0X Standard Library
+ msg += (boost::format(message) % boost::io::group(std::setprecision(prec), val)).str();
+ /*`
+ Now we just have to do something with the message, we could throw an
+ exception, but for the purposes of this example we'll just dump the message
+ to std::cerr:
+ */
+ std::cerr << msg << std::endl;
+ /*`
+ Finally the only sensible value we can return from a domain error is a NaN:
+ */
+ return std::numeric_limits<T>::quiet_NaN();
+}
+
+/*`
+Pole errors are essentially a special case of domain errors,
+so in this example we'll just return the result of a domain error:
+*/
+
+template <class T>
+T user_pole_error(const char* function, const char* message, const T& val)
+{
+ return user_domain_error(function, message, val);
+}
+
+/*`
+Overflow errors are very similar to domain errors, except that there's
+no %1% format specifier in the /message/ parameter:
+*/
+template <class T>
+T user_overflow_error(const char* function, const char* message, const T& val)
+{
+ if(function == 0)
+ function = "Unknown function with arguments of type %1%";
+ if(message == 0)
+ message = "Result of function is too large to represent";
+
+ std::string msg("Error in function ");
+ msg += (boost::format(function) % typeid(T).name()).str();
+
+ msg += ": \n";
+ msg += message;
+
+ std::cerr << msg << std::endl;
+
+ // Value passed to the function is an infinity, just return it:
+ return val;
+}
+
+/*`
+Underflow errors are much the same as overflow:
+*/
+
+template <class T>
+T user_underflow_error(const char* function, const char* message, const T& val)
+{
+ if(function == 0)
+ function = "Unknown function with arguments of type %1%";
+ if(message == 0)
+ message = "Result of function is too small to represent";
+
+ std::string msg("Error in function ");
+ msg += (boost::format(function) % typeid(T).name()).str();
+
+ msg += ": \n";
+ msg += message;
+
+ std::cerr << msg << std::endl;
+
+ // Value passed to the function is zero, just return it:
+ return val;
+}
+
+/*`
+Denormalised results are much the same as underflow:
+*/
+
+template <class T>
+T user_denorm_error(const char* function, const char* message, const T& val)
+{
+ if(function == 0)
+ function = "Unknown function with arguments of type %1%";
+ if(message == 0)
+ message = "Result of function is denormalised";
+
+ std::string msg("Error in function ");
+ msg += (boost::format(function) % typeid(T).name()).str();
+
+ msg += ": \n";
+ msg += message;
+
+ std::cerr << msg << std::endl;
+
+ // Value passed to the function is denormalised, just return it:
+ return val;
+}
+
+/*`
+Which leaves us with evaluation errors: these occur when an internal
+error occurs that prevents the function being fully evaluated.
+The parameter /val/ contains the closest approximation to the result
+found so far:
+*/
+
+template <class T>
+T user_evaluation_error(const char* function, const char* message, const T& val)
+{
+ if(function == 0)
+ function = "Unknown function with arguments of type %1%";
+ if(message == 0)
+ message = "An internal evaluation error occurred with "
+ "the best value calculated so far of %1%";
+
+ std::string msg("Error in function ");
+ msg += (boost::format(function) % typeid(T).name()).str();
+
+ msg += ": \n";
+ int prec = 2 + (std::numeric_limits<T>::digits * 30103UL) / 100000UL;
+ // int prec = std::numeric_limits<T>::max_digits10; // For C++0X Standard Library
+ msg += (boost::format(message) % boost::io::group(std::setprecision(prec), val)).str();
+
+ std::cerr << msg << std::endl;
+
+ // What do we return here? This is generally a fatal error, that should never occur,
+ // so we just return a NaN for the purposes of the example:
+ return std::numeric_limits<T>::quiet_NaN();
+}
+
+} // policies
+}} // boost::math
+
+
+/*`
+Now we'll need to define a suitable policy that will call these handlers,
+and define some forwarding functions that make use of the policy:
+*/
+
+namespace mymath
+{ // unnamed.
+
+using namespace boost::math::policies;
+
+typedef policy<
+ domain_error<user_error>,
+ pole_error<user_error>,
+ overflow_error<user_error>,
+ underflow_error<user_error>,
+ denorm_error<user_error>,
+ evaluation_error<user_error>
+> user_error_policy;
+
+BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(user_error_policy)
+
+} // unnamed namespace
+
+/*`
+We now have a set of forwarding functions, defined in namespace mymath,
+that all look something like this:
+
+``
+template <class RealType>
+inline typename boost::math::tools::promote_args<RT>::type
+ tgamma(RT z)
+{
+ return boost::math::tgamma(z, user_error_policy());
+}
+``
+
+So that when we call `mymath::tgamma(z)` we really end up calling
+`boost::math::tgamma(z, user_error_policy())`, and any
+errors will get directed to our own error handlers:
+*/
+
+int main()
+{
+ // Raise a domain error:
+ cout << "Result of erf_inv(-10) is: "
+ << mymath::erf_inv(-10) << std::endl << endl;
+ // Raise a pole error:
+ cout << "Result of tgamma(-10) is: "
+ << mymath::tgamma(-10) << std::endl << endl;
+ // Raise an overflow error:
+ cout << "Result of tgamma(3000) is: "
+ << mymath::tgamma(3000) << std::endl << endl;
+ // Raise an underflow error:
+ cout << "Result of tgamma(-190.5) is: "
+ << mymath::tgamma(-190.5) << std::endl << endl;
+ // Unfortunately we can't predictably raise a denormalised
+ // result, nor can we raise an evaluation error in this example
+ // since these should never really occur!
+} // int main()
+
+/*`
+
+Which outputs:
+
+[pre
+Error in function boost::math::erf_inv<double>(double, double):
+Argument outside range \[-1, 1\] in inverse erf function (got p=-10).
+Result of erf_inv(-10) is: 1.#QNAN
+
+Error in function boost::math::tgamma<long double>(long double):
+Evaluation of tgamma at a negative integer -10.
+Result of tgamma(-10) is: 1.#QNAN
+
+Error in function boost::math::tgamma<long double>(long double):
+Result of tgamma is too large to represent.
+Error in function boost::math::tgamma<double>(double):
+Result of function is too large to represent
+Result of tgamma(3000) is: 1.#INF
+
+Error in function boost::math::tgamma<long double>(long double):
+Result of tgamma is too large to represent.
+Error in function boost::math::tgamma<long double>(long double):
+Result of tgamma is too small to represent.
+Result of tgamma(-190.5) is: 0
+]
+
+Notice how some of the calls result in an error handler being called more
+than once, or for more than one handler to be called: this is an artefact
+of the fact that many functions are implemented in terms of one or more
+sub-routines each of which may have it's own error handling. For example
+`tgamma(-190.5)` is implemented in terms of `tgamma(190.5)` - which overflows -
+the reflection formula for `tgamma` then notices that it is dividing by
+infinity and so underflows.
+*/
+
+//] //[/policy_eg_9]
diff --git a/src/boost/libs/math/example/policy_ref_snip1.cpp b/src/boost/libs/math/example/policy_ref_snip1.cpp
new file mode 100644
index 000000000..217719395
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip1.cpp
@@ -0,0 +1,75 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010.
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[policy_ref_snip1
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma;
+
+//using namespace boost::math::policies; may also be convenient.
+using boost::math::policies::policy;
+using boost::math::policies::evaluation_error;
+using boost::math::policies::domain_error;
+using boost::math::policies::overflow_error;
+using boost::math::policies::domain_error;
+using boost::math::policies::pole_error;
+using boost::math::policies::errno_on_error;
+
+// Define a policy:
+typedef policy<
+ domain_error<errno_on_error>,
+ pole_error<errno_on_error>,
+ overflow_error<errno_on_error>,
+ evaluation_error<errno_on_error>
+> my_policy;
+
+double my_value = 0.; //
+
+// Call the function applying my_policy:
+double t1 = tgamma(my_value, my_policy());
+
+// Alternatively (and equivalently) we could use helpful function
+// make_policy and define everything at the call site:
+double t2 = tgamma(my_value,
+ make_policy(
+ domain_error<errno_on_error>(),
+ pole_error<errno_on_error>(),
+ overflow_error<errno_on_error>(),
+ evaluation_error<errno_on_error>() )
+ );
+//]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << "my_value = " << my_value << endl;
+ try
+ { // First with default policy - throw an exception.
+ cout << "tgamma(my_value) = " << tgamma(my_value) << endl;
+ }
+ catch(const std::exception& e)
+ {
+ cout <<"\n""Message from thrown exception was:\n " << e.what() << endl;
+ }
+
+ cout << "tgamma(my_value, my_policy() = " << t1 << endl;
+ cout << "tgamma(my_value, make_policy(domain_error<errno_on_error>(), pole_error<errno_on_error>(), overflow_error<errno_on_error>(), evaluation_error<errno_on_error>() ) = " << t2 << endl;
+}
+
+/*
+Output:
+ my_value = 0
+
+ Message from thrown exception was:
+ Error in function boost::math::tgamma<long double>(long double): Evaluation of tgamma at a negative integer 0.
+ tgamma(my_value, my_policy() = 1.#QNAN
+ tgamma(my_value, make_policy(domain_error<errno_on_error>(), pole_error<errno_on_error>(), overflow_error<errno_on_error>(), evaluation_error<errno_on_error>() ) = 1.#QNAN
+*/
diff --git a/src/boost/libs/math/example/policy_ref_snip10.cpp b/src/boost/libs/math/example/policy_ref_snip10.cpp
new file mode 100644
index 000000000..a4806dc6e
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip10.cpp
@@ -0,0 +1,40 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+// Setting precision in a single function call using make_policy.
+
+#include <iostream>
+using std::cout; using std::endl;
+
+//[policy_ref_snip10
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma;
+
+using namespace boost::math::policies;
+
+double t = tgamma(12, policy<digits10<5> >()); // Concise make_policy.
+
+//] //[/policy_ref_snip10]
+
+
+
+int main()
+{
+ cout << "tgamma(12, policy<digits10<5> >()) = "<< t << endl;
+}
+
+/*
+
+Output:
+
+ tgamma(12, policy<digits10<5> >()) = 3.99168e+007
+
+*/
+
diff --git a/src/boost/libs/math/example/policy_ref_snip11.cpp b/src/boost/libs/math/example/policy_ref_snip11.cpp
new file mode 100644
index 000000000..ea7c737c6
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip11.cpp
@@ -0,0 +1,45 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+
+// Setting (approximate) precision 25 bits in a single function call using make_policy.
+
+//[policy_ref_snip11
+
+#include <boost/math/distributions/normal.hpp>
+using boost::math::normal_distribution;
+
+using namespace boost::math::policies;
+
+const int bits = 25; // approximate precision.
+
+double q = quantile(
+ normal_distribution<double, policy<digits2<bits> > >(),
+ 0.05); // 5% quantile.
+
+//] //[/policy_ref_snip11]
+
+int main()
+{
+ std::streamsize p = 2 + (bits * 30103UL) / 100000UL;
+ // Approximate number of significant decimal digits for 25 bits.
+ cout.precision(p);
+ cout << bits << " binary bits is approximately equivalent to " << p << " decimal digits " << endl;
+ cout << "quantile(normal_distribution<double, policy<digits2<25> > >(), 0.05 = "
+ << q << endl; // -1.64485
+}
+
+/*
+Output:
+ 25 binary bits is approximately equivalent to 9 decimal digits
+ quantile(normal_distribution<double, policy<digits2<25> > >(), 0.05 = -1.64485363
+ */
+
diff --git a/src/boost/libs/math/example/policy_ref_snip12.cpp b/src/boost/libs/math/example/policy_ref_snip12.cpp
new file mode 100644
index 000000000..e406ce561
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip12.cpp
@@ -0,0 +1,55 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+// Define tgamma function with a no overflow policy
+// into a specific namespace-scope.
+
+#include <iostream>
+using std::cout; using std::endl;
+
+//[policy_ref_snip12
+
+#include <boost/math/special_functions/gamma.hpp>
+//using boost::math::tgamma;
+// Need not declare using boost::math::tgamma here,
+// because will define tgamma in myspace using macro below.
+
+namespace myspace
+{
+ using namespace boost::math::policies;
+
+ // Define a policy that does not throw on overflow:
+ typedef policy<overflow_error<errno_on_error> > my_policy;
+
+ // Define the special functions in this scope to use the policy:
+ BOOST_MATH_DECLARE_SPECIAL_FUNCTIONS(my_policy)
+}
+
+// Now we can use myspace::tgamma etc.
+// They will automatically use "my_policy":
+//
+double t = myspace::tgamma(30.0); // Will *not* throw on overflow,
+// despite the large value of factorial 30 = 265252859812191058636308480000000
+// unlike default policy boost::math::tgamma;
+
+//]
+
+int main()
+{
+ cout << "myspace::tgamma(30.0) = " << t << endl;
+}
+
+/*
+
+Output:
+
+myspace::tgamma(30.0) = 8.84176e+030
+
+*/
+
diff --git a/src/boost/libs/math/example/policy_ref_snip13.cpp b/src/boost/libs/math/example/policy_ref_snip13.cpp
new file mode 100644
index 000000000..ce4b0948c
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip13.cpp
@@ -0,0 +1,81 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <boost/config.hpp>
+#ifdef _MSC_VER
+# pragma warning (disable : 4189) // 'd' : local variable is initialized but not referenced
+#endif
+#ifdef BOOST_GCC
+# pragma GCC diagnostic ignored "-Wunused-variable"
+#endif
+
+#include <iostream>
+using std::cout; using std::endl;
+
+#include <stdexcept>
+using std::domain_error;
+
+//[policy_ref_snip13
+
+#include <boost/math/distributions/cauchy.hpp>
+
+namespace myspace
+{ // using namespace boost::math::policies; // May be convenient in myspace.
+
+ // Define a policy called my_policy to use.
+ using boost::math::policies::policy;
+
+// In this case we want all the distribution accessor functions to compile,
+// even if they are mathematically undefined, so
+// make the policy assert_undefined.
+ using boost::math::policies::assert_undefined;
+
+typedef policy<assert_undefined<false> > my_policy;
+
+// Finally apply this policy to type double.
+BOOST_MATH_DECLARE_DISTRIBUTIONS(double, my_policy)
+} // namespace myspace
+
+// Now we can use myspace::cauchy etc, which will use policy
+// myspace::mypolicy:
+//
+// This compiles but throws a domain error exception at runtime.
+// Caution! If you omit the try'n'catch blocks,
+// it will just silently terminate, giving no clues as to why!
+// So try'n'catch blocks are very strongly recommended.
+
+void test_cauchy()
+{
+ try
+ {
+ double d = mean(myspace::cauchy()); // Cauchy does not have a mean!
+ (void) d;
+ }
+ catch(const std::domain_error& e)
+ {
+ cout << e.what() << endl;
+ }
+}
+
+//] //[/policy_ref_snip13]
+
+int main()
+{
+ test_cauchy();
+}
+
+/*
+
+Output:
+
+policy_snip_13.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\policy_snip_13.exe
+ Error in function boost::math::mean(cauchy<double>&): The Cauchy distribution does not have a mean: the only possible return value is 1.#QNAN.
+
+ */
+
diff --git a/src/boost/libs/math/example/policy_ref_snip2.cpp b/src/boost/libs/math/example/policy_ref_snip2.cpp
new file mode 100644
index 000000000..304250d4f
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip2.cpp
@@ -0,0 +1,47 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+
+//[policy_ref_snip2
+
+#include <boost/math/distributions/normal.hpp>
+using boost::math::normal_distribution;
+
+using namespace boost::math::policies;
+
+// Define a specific policy:
+typedef policy<
+ overflow_error<ignore_error>
+ > my_policy;
+
+// Define the distribution, using my_policy:
+typedef normal_distribution<double, my_policy> my_norm;
+
+// Construct a my_norm distribution, using default mean and standard deviation,
+// and get a 0.05 or 5% quantile:
+double q = quantile(my_norm(), 0.05); // = -1.64485
+
+//] //[/policy_ref_snip2]
+
+int main()
+{
+ my_norm n; // Construct a my_norm distribution,
+ // using default mean zero and standard deviation unity.
+ double q = quantile(n, 0.05); // and get a quantile.
+ cout << "quantile(my_norm(), 0.05) = " << q << endl;
+}
+
+/*
+
+Output:
+
+ quantile(my_norm(), 0.05) = -1.64485
+*/
diff --git a/src/boost/libs/math/example/policy_ref_snip3.cpp b/src/boost/libs/math/example/policy_ref_snip3.cpp
new file mode 100644
index 000000000..b3820ad30
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip3.cpp
@@ -0,0 +1,40 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+double some_value = 2.;
+
+//[policy_ref_snip3
+
+#include <boost/math/special_functions/gamma.hpp>
+
+using namespace boost::math::policies;
+using boost::math::tgamma;
+
+// Define a new policy *not* internally promoting RealType to double:
+typedef policy<
+ promote_double<false>
+ > my_policy;
+
+// Call the function, applying the new policy:
+double t1 = tgamma(some_value, my_policy());
+
+// Alternatively we could use helper function make_policy,
+// and concisely define everything at the call site:
+double t2 = tgamma(some_value, make_policy(promote_double<false>()));
+
+//] //[\policy_ref_snip3]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << "tgamma(some_value, my_policy()) = " << t1
+ << ", tgamma(some_value, make_policy(promote_double<false>()) = " << t2 << endl;
+}
diff --git a/src/boost/libs/math/example/policy_ref_snip4.cpp b/src/boost/libs/math/example/policy_ref_snip4.cpp
new file mode 100644
index 000000000..7df35be1c
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip4.cpp
@@ -0,0 +1,41 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010.
+// 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)
+
+// 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 : 4305) // 'initializing' : truncation from 'long double' to 'const eval_type'
+# pragma warning (disable : 4244) // 'conversion' : truncation from 'long double' to 'const eval_type'
+#endif
+
+//[policy_ref_snip4
+
+#include <boost/math/distributions/normal.hpp>
+using boost::math::normal_distribution;
+
+using namespace boost::math::policies;
+
+// Define a policy:
+typedef policy<
+ promote_float<false>
+ > my_policy;
+
+// Define the new normal distribution using my_policy:
+typedef normal_distribution<float, my_policy> my_norm;
+
+// Get a quantile:
+float q = quantile(my_norm(), 0.05f);
+
+//] [policy_ref_snip4]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << " quantile(my_norm(), 0.05f) = " << q << endl; // -1.64485
+}
diff --git a/src/boost/libs/math/example/policy_ref_snip5.cpp b/src/boost/libs/math/example/policy_ref_snip5.cpp
new file mode 100644
index 000000000..06f270af4
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip5.cpp
@@ -0,0 +1,45 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010.
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[policy_ref_snip5
+
+#include <boost/math/distributions/negative_binomial.hpp>
+using boost::math::negative_binomial_distribution;
+
+using namespace boost::math::policies;
+
+typedef negative_binomial_distribution<
+ double,
+ policy<discrete_quantile<real> >
+ > dist_type;
+
+// Lower 5% quantile:
+double x = quantile(dist_type(20, 0.3), 0.05);
+// Upper 95% quantile:
+double y = quantile(complement(dist_type(20, 0.3), 0.05));
+
+//] //[/policy_ref_snip5]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << "quantile(dist_type(20, 0.3), 0.05) = " << x
+ << "\nquantile(complement(dist_type(20, 0.3), 0.05) = " << y << endl;
+}
+
+/*
+
+Output:
+ quantile(dist_type(20, 0.3), 0.05) = 27.3898
+ quantile(complement(dist_type(20, 0.3), 0.05) = 68.1584
+
+ */
+
diff --git a/src/boost/libs/math/example/policy_ref_snip6.cpp b/src/boost/libs/math/example/policy_ref_snip6.cpp
new file mode 100644
index 000000000..9dc207297
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip6.cpp
@@ -0,0 +1,38 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010.
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[policy_ref_snip6
+
+#include <boost/math/distributions/negative_binomial.hpp>
+using boost::math::negative_binomial;
+
+// Use the default rounding policy integer_round_outwards.
+// Lower quantile rounded down:
+double x = quantile(negative_binomial(20, 0.3), 0.05); // rounded up 27 from 27.3898
+// Upper quantile rounded up:
+double y = quantile(complement(negative_binomial(20, 0.3), 0.05)); // rounded down to 69 from 68.1584
+
+//] //[/policy_ref_snip6]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << "quantile(negative_binomial(20, 0.3), 0.05) = "<< x <<endl
+ << "quantile(complement(negative_binomial(20, 0.3), 0.05)) = " << y << endl;
+}
+
+/*
+Output:
+
+ quantile(negative_binomial(20, 0.3), 0.05) = 27
+ quantile(complement(negative_binomial(20, 0.3), 0.05)) = 69
+*/
+
diff --git a/src/boost/libs/math/example/policy_ref_snip7.cpp b/src/boost/libs/math/example/policy_ref_snip7.cpp
new file mode 100644
index 000000000..004205b01
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip7.cpp
@@ -0,0 +1,48 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010.
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[policy_ref_snip7
+
+#include <boost/math/distributions/negative_binomial.hpp>
+using boost::math::negative_binomial_distribution;
+
+using namespace boost::math::policies;
+
+typedef negative_binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_inwards> >
+ > dist_type;
+
+// Lower quantile rounded up:
+double x = quantile(dist_type(20, 0.3), 0.05); // 28 rounded up from 27.3898
+// Upper quantile rounded down:
+double y = quantile(complement(dist_type(20, 0.3), 0.05)); // 68 rounded down from 68.1584
+
+//] //[/policy_ref_snip7]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << "using policy<discrete_quantile<integer_round_inwards> > " << endl
+ << "quantile(dist_type(20, 0.3), 0.05) = " << x << endl
+ << "quantile(complement(dist_type(20, 0.3), 0.05)) = " << y << endl;
+}
+
+/*
+
+Output:
+ using policy<discrete_quantile<integer_round_inwards> >
+ quantile(dist_type(20, 0.3), 0.05) = 28
+ quantile(complement(dist_type(20, 0.3), 0.05)) = 68
+
+
+*/
+
diff --git a/src/boost/libs/math/example/policy_ref_snip8.cpp b/src/boost/libs/math/example/policy_ref_snip8.cpp
new file mode 100644
index 000000000..abc48b9ae
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip8.cpp
@@ -0,0 +1,47 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010.
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//[policy_ref_snip8
+
+#include <boost/math/distributions/negative_binomial.hpp>
+using boost::math::negative_binomial_distribution;
+
+using namespace boost::math::policies;
+
+typedef negative_binomial_distribution<
+ double,
+ policy<discrete_quantile<integer_round_nearest> >
+ > dist_type;
+
+// Lower quantile rounded (down) to nearest:
+double x = quantile(dist_type(20, 0.3), 0.05); // 27
+// Upper quantile rounded (down) to nearest:
+double y = quantile(complement(dist_type(20, 0.3), 0.05)); // 68
+
+//] //[/policy_ref_snip8]
+
+#include <iostream>
+using std::cout; using std::endl;
+
+int main()
+{
+ cout << "using policy<discrete_quantile<integer_round_nearest> " << endl
+ << "quantile(dist_type(20, 0.3), 0.05) = " << x << endl
+ << "quantile(complement(dist_type(20, 0.3), 0.05)) " << y << endl;
+}
+
+/*
+
+Output:
+
+ using policy<discrete_quantile<integer_round_nearest>
+ quantile(dist_type(20, 0.3), 0.05) = 27
+ quantile(complement(dist_type(20, 0.3), 0.05)) 68
+
+*/
diff --git a/src/boost/libs/math/example/policy_ref_snip9.cpp b/src/boost/libs/math/example/policy_ref_snip9.cpp
new file mode 100644
index 000000000..ed38d4601
--- /dev/null
+++ b/src/boost/libs/math/example/policy_ref_snip9.cpp
@@ -0,0 +1,36 @@
+// Copyright John Maddock 2007.
+// Copyright Paul A. Bristow 2010
+
+// 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)
+
+// Note that this file contains quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+#include <iostream>
+using std::cout; using std::endl;
+
+//[policy_ref_snip9
+
+#include <boost/math/special_functions/gamma.hpp>
+using boost::math::tgamma;
+using boost::math::policies::policy;
+using boost::math::policies::digits10;
+
+typedef policy<digits10<5> > my_pol_5; // Define a new, non-default, policy
+// to calculate tgamma to accuracy of approximately 5 decimal digits.
+//]
+
+int main()
+{
+ cout.precision(5); // To only show 5 (hopefully) accurate decimal digits.
+ double t = tgamma(12, my_pol_5()); // Apply the 5 decimal digits accuracy policy to use of tgamma.
+ cout << "tgamma(12, my_pol_5() = " << t << endl;
+}
+
+/*
+
+Output:
+ tgamma(12, my_pol_5() = 3.9917e+007
+*/
diff --git a/src/boost/libs/math/example/polynomial_arithmetic.cpp b/src/boost/libs/math/example/polynomial_arithmetic.cpp
new file mode 100644
index 000000000..78efd06d0
--- /dev/null
+++ b/src/boost/libs/math/example/polynomial_arithmetic.cpp
@@ -0,0 +1,237 @@
+// 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)
+
+// Copyright Jeremy W. Murphy 2015.
+
+// This file is written to be included from a Quickbook .qbk document.
+// It can be compiled by the C++ compiler, and run. Any output can
+// also be added here as comment or included or pasted in elsewhere.
+// Caution: this file contains Quickbook markup as well as code
+// and comments: don't change any of the special comment markups!
+
+//[polynomial_arithmetic_0
+/*`First include the essential polynomial header (and others) to make the example:
+*/
+#include <boost/math/tools/polynomial.hpp>
+//] [polynomial_arithmetic_0
+
+#include <boost/array.hpp>
+#include <boost/lexical_cast.hpp>
+#include <boost/assert.hpp>
+
+#include <iostream>
+#include <stdexcept>
+#include <cmath>
+#include <string>
+#include <utility>
+
+//[polynomial_arithmetic_1
+/*`and some using statements are convenient:
+*/
+
+using std::string;
+using std::exception;
+using std::cout;
+using std::abs;
+using std::pair;
+
+using namespace boost::math;
+using namespace boost::math::tools; // for polynomial
+using boost::lexical_cast;
+
+//] [/polynomial_arithmetic_1]
+
+template <typename T>
+string sign_str(T const &x)
+{
+ return x < 0 ? "-" : "+";
+}
+
+template <typename T>
+string inner_coefficient(T const &x)
+{
+ string result(" " + sign_str(x) + " ");
+ if (abs(x) != T(1))
+ result += lexical_cast<string>(abs(x));
+ return result;
+}
+
+/*! Output in formula format.
+For example: from a polynomial in Boost container storage [ 10, -6, -4, 3 ]
+show as human-friendly formula notation: 3x^3 - 4x^2 - 6x + 10.
+*/
+template <typename T>
+string formula_format(polynomial<T> const &a)
+{
+ string result;
+ if (a.size() == 0)
+ result += lexical_cast<string>(T(0));
+ else
+ {
+ // First one is a special case as it may need unary negate.
+ unsigned i = a.size() - 1;
+ if (a[i] < 0)
+ result += "-";
+ if (abs(a[i]) != T(1))
+ result += lexical_cast<string>(abs(a[i]));
+
+ if (i > 0)
+ {
+ result += "x";
+ if (i > 1)
+ {
+ result += "^" + lexical_cast<string>(i);
+ i--;
+ for (; i != 1; i--)
+ if (a[i])
+ result += inner_coefficient(a[i]) + "x^" + lexical_cast<string>(i);
+
+ if (a[i])
+ result += inner_coefficient(a[i]) + "x";
+ }
+ i--;
+
+ if (a[i])
+ result += " " + sign_str(a[i]) + " " + lexical_cast<string>(abs(a[i]));
+ }
+ }
+ return result;
+} // string formula_format(polynomial<T> const &a)
+
+
+int main()
+{
+ cout << "Example: Polynomial arithmetic.\n\n";
+
+ try
+ {
+//[polynomial_arithmetic_2
+/*`Store the coefficients in a convenient way to access them,
+then create some polynomials using construction from an iterator range,
+and finally output in a 'pretty' formula format.
+
+[tip Although we might conventionally write a polynomial from left to right
+in descending order of degree, Boost.Math stores in [*ascending order of degree].]
+
+ Read/write for humans: 3x^3 - 4x^2 - 6x + 10
+ Boost polynomial storage: [ 10, -6, -4, 3 ]
+*/
+ boost::array<double, 4> const d3a = {{10, -6, -4, 3}};
+ polynomial<double> const a(d3a.begin(), d3a.end());
+
+ // With C++11 and later, you can also use initializer_list construction.
+ polynomial<double> const b{{-2.0, 1.0}};
+
+ // formula_format() converts from Boost storage to human notation.
+ cout << "a = " << formula_format(a)
+ << "\nb = " << formula_format(b) << "\n\n";
+
+//] [/polynomial_arithmetic_2]
+
+//[polynomial_arithmetic_3
+ // Now we can do arithmetic with the usual infix operators: + - * / and %.
+ polynomial<double> s = a + b;
+ cout << "a + b = " << formula_format(s) << "\n";
+ polynomial<double> d = a - b;
+ cout << "a - b = " << formula_format(d) << "\n";
+ polynomial<double> p = a * b;
+ cout << "a * b = " << formula_format(p) << "\n";
+ polynomial<double> q = a / b;
+ cout << "a / b = " << formula_format(q) << "\n";
+ polynomial<double> r = a % b;
+ cout << "a % b = " << formula_format(r) << "\n";
+//] [/polynomial_arithmetic_3]
+
+//[polynomial_arithmetic_4
+/*`
+Division is a special case where you can calculate two for the price of one.
+
+Actually, quotient and remainder are always calculated together due to the nature
+of the algorithm: the infix operators return one result and throw the other
+away.
+
+If you are doing a lot of division and want both the quotient and remainder, then
+you don't want to do twice the work necessary.
+
+In that case you can call the underlying function, [^quotient_remainder],
+to get both results together as a pair.
+*/
+ pair< polynomial<double>, polynomial<double> > result;
+ result = quotient_remainder(a, b);
+// Reassure ourselves that the result is the same.
+ BOOST_ASSERT(result.first == q);
+ BOOST_ASSERT(result.second == r);
+//] [/polynomial_arithmetic_4]
+//[polynomial_arithmetic_5
+ /*
+We can use the right and left shift operators to add and remove a factor of x.
+This has the same semantics as left and right shift for integers where it is a
+factor of 2. x is the smallest prime factor of a polynomial as is 2 for integers.
+*/
+ cout << "Right and left shift operators.\n";
+ cout << "\n" << formula_format(p) << "\n";
+ cout << "... right shift by 1 ...\n";
+ p >>= 1;
+ cout << formula_format(p) << "\n";
+ cout << "... left shift by 2 ...\n";
+ p <<= 2;
+ cout << formula_format(p) << "\n";
+
+/*
+We can also give a meaning to odd and even for a polynomial that is consistent
+with these operations: a polynomial is odd if it has a non-zero constant value,
+even otherwise. That is:
+ x^2 + 1 odd
+ x^2 even
+ */
+ cout << std::boolalpha;
+ cout << "\nPrint whether a polynomial is odd.\n";
+ cout << formula_format(s) << " odd? " << odd(s) << "\n";
+ // We cheekily use the internal details to subtract the constant, making it even.
+ s -= s.data().front();
+ cout << formula_format(s) << " odd? " << odd(s) << "\n";
+ // And of course you can check if it is even:
+ cout << formula_format(s) << " even? " << even(s) << "\n";
+
+
+ //] [/polynomial_arithmetic_5]
+ //[polynomial_arithmetic_6]
+ /* For performance and convenience, we can test whether a polynomial is zero
+ * by implicitly converting to bool with the same semantics as int. */
+ polynomial<double> zero; // Default construction is 0.
+ cout << "zero: " << (zero ? "not zero" : "zero") << "\n";
+ cout << "r: " << (r ? "not zero" : "zero") << "\n";
+ /* We can also set a polynomial to zero without needing a another zero
+ * polynomial to assign to it. */
+ r.set_zero();
+ cout << "r: " << (r ? "not zero" : "zero") << "\n";
+ //] [/polynomial_arithmetic_6]
+}
+catch (exception const &e)
+{
+ cout << "\nMessage from thrown exception was:\n " << e.what() << "\n";
+}
+} // int main()
+
+/*
+//[polynomial_output_1
+
+a = 3x^3 - 4x^2 - 6x + 10
+b = x - 2
+
+//] [/polynomial_output_1]
+
+
+//[polynomial_output_2
+
+a + b = 3x^3 - 4x^2 - 5x + 8
+a - b = 3x^3 - 4x^2 - 7x + 12
+a * b = 3x^4 - 10x^3 + 2x^2 + 22x - 20
+a / b = 3x^2 + 2x - 2
+a % b = 6
+
+//] [/polynomial_output_2]
+
+*/
diff --git a/src/boost/libs/math/example/root_elliptic_finding.cpp b/src/boost/libs/math/example/root_elliptic_finding.cpp
new file mode 100644
index 000000000..9a7e0c345
--- /dev/null
+++ b/src/boost/libs/math/example/root_elliptic_finding.cpp
@@ -0,0 +1,878 @@
+// 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 & Schroder 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/tools/roots.hpp>
+#include <boost/math/special_functions/ellint_1.hpp>
+#include <boost/math/special_functions/ellint_2.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::schroder_iterate;
+
+#include <boost/math/special_functions/next.hpp> // For float_distance.
+
+#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/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
+
+ std::string chop_last(std::string s)
+ {
+ std::string::size_type pos = s.find_last_of("\\/");
+ if(pos != std::string::npos)
+ s.erase(pos);
+ else if(s.empty())
+ abort();
+ else
+ s.erase();
+ return s;
+ }
+
+ std::string make_root()
+ {
+ std::string result;
+ if(sourcefilename.find_first_of(":") != std::string::npos)
+ {
+ result = chop_last(sourcefilename); // lose filename part
+ result = chop_last(result); // lose /example/
+ result = chop_last(result); // lose /math/
+ result = chop_last(result); // lose /libs/
+ }
+ else
+ {
+ result = chop_last(sourcefilename); // lose filename part
+ if(result.empty())
+ result = ".";
+ result += "/../../..";
+ }
+ return result;
+ }
+
+ std::string short_file_name(std::string s)
+ {
+ std::string::size_type pos = s.find_last_of("\\/");
+ if(pos != std::string::npos)
+ s.erase(0, pos + 1);
+ return s;
+ }
+
+ std::string boost_root = make_root();
+
+
+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;
+
+double digits_accuracy = 1.0; // 1 == maximum possible accuracy.
+
+std::stringstream ss;
+
+std::ofstream fout;
+
+std::vector<std::string> algo_names =
+{
+ "TOMS748", "Newton", "Halley", "Schr'''&#xf6;'''der"
+};
+
+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 & Schroder.
+ //std::vector< boost::int_least64_t> times; converted to int.
+ std::vector<int> times; // arbitrary 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;
+#if defined(_DEBUG) || !defined(NDEBUG)
+ result += "|";
+ result += " debug";
+#else
+ result += "|";
+ result += " release";
+#endif
+ result += "|";
+ return result;
+} // std::string build_test_name
+
+// Algorithms //////////////////////////////////////////////
+
+// No derivatives - using TOMS748 internally.
+//[elliptic_noderv_func
+template <typename T = double>
+struct elliptic_root_functor_noderiv
+{ // Nth root of x using only function - no derivatives.
+ elliptic_root_functor_noderiv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius)
+ { // Constructor just stores value a to find root of.
+ }
+ T operator()(T const& x)
+ {
+ using std::sqrt;
+ // return the difference between required arc-length, and the calculated arc-length for an
+ // ellipse with radii m_radius and x:
+ T a = (std::max)(m_radius, x);
+ T b = (std::min)(m_radius, x);
+ T k = sqrt(1 - b * b / (a * a));
+ return 4 * a * boost::math::ellint_2(k) - m_arc;
+ }
+private:
+ T m_arc; // length of arc.
+ T m_radius; // one of the two radii of the ellipse
+}; // template <class T> struct elliptic_root_functor_noderiv
+//]
+//[elliptic_root_noderiv
+template <class T = double>
+T elliptic_root_noderiv(T radius, T arc)
+{ // return the other radius of an ellipse, given one radii and the arc-length
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For bracket_and_solve_root.
+
+ T guess = sqrt(arc * arc / 16 - radius * radius);
+ T factor = 1.2; // How big steps to take when searching.
+
+ const boost::uintmax_t maxit = 50; // Limit to maximum iterations.
+ boost::uintmax_t it = maxit; // Initially our chosen max iterations, but updated with actual.
+ bool is_rising = true; // arc-length increases if one radii increases, so function is rising
+ // Define a termination condition, stop when nearly all digits are correct, but allow for
+ // the fact that we are returning a range, and must have some inaccuracy in the elliptic integral:
+ eps_tolerance<T> tol(std::numeric_limits<T>::digits - 2);
+ // Call bracket_and_solve_root to find the solution, note that this is a rising function:
+ std::pair<T, T> r = bracket_and_solve_root(elliptic_root_functor_noderiv<T>(arc, radius), guess, factor, is_rising, tol, it);
+ //<-
+ iters = it;
+ //->
+ // Result is midway between the endpoints of the range:
+ return r.first + (r.second - r.first) / 2;
+} // template <class T> T elliptic_root_noderiv(T x)
+//]
+// Using 1st derivative only Newton-Raphson
+//[elliptic_1deriv_func
+template <class T = double>
+struct elliptic_root_functor_1deriv
+{ // Functor also returning 1st derivative.
+ BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
+
+ elliptic_root_functor_1deriv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius)
+ { // Constructor just stores value a to find root of.
+ }
+ std::pair<T, T> operator()(T const& x)
+ {
+ using std::sqrt;
+ // Return the difference between required arc-length, and the calculated arc-length for an
+ // ellipse with radii m_radius and x, plus it's derivative.
+ // See http://www.wolframalpha.com/input/?i=d%2Fda+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]
+ // We require two elliptic integral calls, but from these we can calculate both
+ // the function and it's derivative:
+ T a = (std::max)(m_radius, x);
+ T b = (std::min)(m_radius, x);
+ T a2 = a * a;
+ T b2 = b * b;
+ T k = sqrt(1 - b2 / a2);
+ T Ek = boost::math::ellint_2(k);
+ T Kk = boost::math::ellint_1(k);
+ T fx = 4 * a * Ek - m_arc;
+ T dfx = 4 * (a2 * Ek - b2 * Kk) / (a2 - b2);
+ return std::make_pair(fx, dfx);
+ }
+private:
+ T m_arc; // length of arc.
+ T m_radius; // one of the two radii of the ellipse
+}; // struct elliptic_root__functor_1deriv
+//]
+//[elliptic_1deriv
+template <class T = double>
+T elliptic_root_1deriv(T radius, T arc)
+{
+ 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!");
+
+ T guess = sqrt(arc * arc / 16 - radius * radius);
+ T min = 0; // Minimum possible value is zero.
+ T max = arc; // Maximum possible value is the arc length.
+
+ // Accuracy doubles at each step, so stop when just over half of the digits are
+ // correct, and rely on that step to polish off the remainder:
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.6);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ T result = newton_raphson_iterate(elliptic_root_functor_1deriv<T>(arc, radius), guess, min, max, get_digits, it);
+ //<-
+ iters = it;
+ //->
+ return result;
+} // T elliptic_root_1_deriv Newton-Raphson
+//]
+
+// Using 1st and 2nd derivatives with Halley algorithm.
+//[elliptic_2deriv_func
+template <class T = double>
+struct elliptic_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!");
+
+ elliptic_root_functor_2deriv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius) {}
+ std::tuple<T, T, T> operator()(T const& x)
+ {
+ using std::sqrt;
+ // Return the difference between required arc-length, and the calculated arc-length for an
+ // ellipse with radii m_radius and x, plus it's derivative.
+ // See http://www.wolframalpha.com/input/?i=d^2%2Fda^2+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]
+ // for the second derivative.
+ T a = (std::max)(m_radius, x);
+ T b = (std::min)(m_radius, x);
+ T a2 = a * a;
+ T b2 = b * b;
+ T k = sqrt(1 - b2 / a2);
+ T Ek = boost::math::ellint_2(k);
+ T Kk = boost::math::ellint_1(k);
+ T fx = 4 * a * Ek - m_arc;
+ T dfx = 4 * (a2 * Ek - b2 * Kk) / (a2 - b2);
+ T dfx2 = 4 * b2 * ((a2 + b2) * Kk - 2 * a2 * Ek) / (a * (a2 - b2) * (a2 - b2));
+ return std::make_tuple(fx, dfx, dfx2);
+ }
+private:
+ T m_arc; // length of arc.
+ T m_radius; // one of the two radii of the ellipse
+};
+//]
+//[elliptic_2deriv
+template <class T = double>
+T elliptic_root_2deriv(T radius, T arc)
+{
+ 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!");
+
+ T guess = sqrt(arc * arc / 16 - radius * radius);
+ T min = 0; // Minimum possible value is zero.
+ T max = arc; // radius can't be larger than the arc length.
+
+ // Accuracy triples at each step, so stop when just over one-third of the digits
+ // are correct, and the last iteration will polish off the remaining digits:
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ T result = halley_iterate(elliptic_root_functor_2deriv<T>(arc, radius), guess, min, max, get_digits, it);
+ //<-
+ iters = it;
+ //->
+ return result;
+} // nth_2deriv Halley
+//]
+// Using 1st and 2nd derivatives using Schroder algorithm.
+
+template <class T = double>
+T elliptic_root_2deriv_s(T arc, T radius)
+{ // return nth root of x using 1st and 2nd derivatives and Schroder.
+
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For schroder_iterate.
+
+ BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
+
+ T guess = sqrt(arc * arc / 16 - radius * radius);
+ T min = 0; // Minimum possible value is zero.
+ T max = arc; // radius can't be larger than the arc length.
+
+ 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 = schroder_iterate(elliptic_root_functor_2deriv<T>(arc, radius), guess, min, max, get_digits, it);
+ iters = it;
+
+ return result;
+} // T elliptic_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 <typename T>
+int test_root(cpp_bin_float_100 big_radius, cpp_bin_float_100 big_arc, 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 radius = static_cast<T>(big_radius);
+ T arc = static_cast<T>(big_arc);
+
+ T result; // root
+ T sum = 0;
+ T ans = static_cast<T>(answer);
+
+ using boost::timer::nanosecond_type;
+ using boost::timer::cpu_times;
+ using boost::timer::cpu_timer;
+
+ long eval_count = boost::is_floating_point<T>::value ? 1000000 : 10000; // 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 = eval_count; i >= 0; --i)
+ {
+ result = elliptic_root_noderiv(radius, arc); //
+ sum += result;
+ }
+ 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 = eval_count; i >= 0; --i)
+ {
+ result = elliptic_root_1deriv(radius, arc); //
+ sum += result;
+ }
+ 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 = eval_count; i >= 0; --i)
+ {
+ result = elliptic_root_2deriv(radius, arc); //
+ sum += result;
+ }
+ 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("Schr'''&#xf6;'''der"); // algorithm
+ cpu_timer ti; // Can start, pause, resume and stop, and read elapsed.
+ ti.start();
+ for(long i = eval_count; i >= 0; --i)
+ {
+ result = elliptic_root_2deriv_s(arc, radius); //
+ sum += result;
+ }
+ 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);
+ }
+
+ std::cout << "Accumulated result was: " << sum << std::endl;
+
+ return 4; // eval_count of how many algorithms used.
+} // test_root
+
+/*! Fill array of times, iterations, etc for Nth root for all 4 types,
+ and write a table of results in Quickbook format.
+ */
+void table_root_info(cpp_bin_float_100 radius, cpp_bin_float_100 arc)
+{
+ using std::abs;
+
+ std::cout << nooftypes << " floating-point types tested:" << std::endl;
+#if defined(_DEBUG) || !defined(NDEBUG)
+ std::cout << "Compiled in debug mode." << std::endl;
+#else
+ std::cout << "Compiled in optimise mode." << std::endl;
+#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 = elliptic_root_noderiv(radius, arc);
+
+ root_infos.clear(); // Erase any previous data.
+ // Fill the elements of the array for each floating-point type.
+
+ test_root<float>(radius, arc, full_answer, "float", 0);
+ test_root<double>(radius, arc, full_answer, "double", 1);
+ test_root<long double>(radius, arc, full_answer, "long double", 2);
+ test_root<cpp_bin_float_50>(radius, arc, 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:elliptic root with radius " << radius << " and arc length " << arc << ") 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 radius, cpp_bin_float_100 arc, double digits_accuracy)
+{
+ ::digits_accuracy = digits_accuracy;
+ // Save globally so that it is available to root-finding algorithms. Ugly :-(
+
+#if defined(_DEBUG) || !defined(NDEBUG)
+ std::string debug_or_optimize("Compiled in debug mode.");
+#else
+ std::string debug_or_optimize("Compiled in optimise mode.");
+#endif
+
+ // Create filename for roots_table
+ std::string qbk_name = full_roots_name;
+ qbk_name += "elliptic_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 [@../../example/" << short_file_name(sourcefilename) << " " << short_file_name(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(radius, arc);
+
+ 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 radius("28.");
+ cpp_bin_float_100 arc("300.");
+ // 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 << "radius 1" << radius << std::endl;
+ std::cout << "arc length" << arc << 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(radius, arc, 1.);
+
+ // Output tables for some roots at less accuracy.
+ //roots_tables(full_value, 0.75);
+
+ return boost::exit_success;
+ }
+ catch (std::exception const& ex)
+ {
+ std::cout << "exception thrown: " << ex.what() << std::endl;
+ return boost::exit_failure;
+ }
+} // int main()
+
+/*
+
+*/
diff --git a/src/boost/libs/math/example/root_finding_algorithms.cpp b/src/boost/libs/math/example/root_finding_algorithms.cpp
new file mode 100644
index 000000000..df2e68acc
--- /dev/null
+++ b/src/boost/libs/math/example/root_finding_algorithms.cpp
@@ -0,0 +1,907 @@
+// 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, Schroder & 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/type_traits/is_fundamental.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::schroder_iterate;
+
+#include <boost/math/special_functions/next.hpp> // For float_distance.
+#include <tuple> // 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
+
+std::string chop_last(std::string s)
+{
+ std::string::size_type pos = s.find_last_of("\\/");
+ if(pos != std::string::npos)
+ s.erase(pos);
+ else if(s.empty())
+ abort();
+ else
+ s.erase();
+ return s;
+}
+
+std::string make_root()
+{
+ std::string result;
+ if(sourcefilename.find_first_of(":") != std::string::npos)
+ {
+ result = chop_last(sourcefilename); // lose filename part
+ result = chop_last(result); // lose /example/
+ result = chop_last(result); // lose /math/
+ result = chop_last(result); // lose /libs/
+ }
+ else
+ {
+ result = chop_last(sourcefilename); // lose filename part
+ if(result.empty())
+ result = ".";
+ result += "/../../..";
+ }
+ return result;
+}
+
+std::string short_file_name(std::string s)
+{
+ std::string::size_type pos = s.find_last_of("\\/");
+ if(pos != std::string::npos)
+ s.erase(0, pos + 1);
+ return s;
+}
+
+std::string boost_root = make_root();
+
+#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", "Schr'''&#xf6;'''der"
+};
+
+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 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;
+#if defined(_DEBUG ) || !defined(NDEBUG)
+ result += "|";
+ result += " debug";
+#else
+ result += "|";
+ result += " release";
+#endif
+ result += "|";
+ return result;
+}
+
+// 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; // Initially 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.
+ // Some fraction of digits is used to control how accurate to try to make the result.
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits - 2);
+
+ 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 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.
+ }
+ 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;
+ T guess;
+ if(boost::is_fundamental<T>::value)
+ {
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ guess = ldexp(static_cast<T>(1), exponent / 3); // Rough guess is to divide the exponent by three.
+ }
+ else
+ guess = boost::math::cbrt(static_cast<double>(x));
+ T min = guess / 2; // Minimum possible value is half our guess.
+ T max = 2 * guess; // Maximum possible value is twice our guess.
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.6);
+ 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,
+ }
+ 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).
+ 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.
+ }
+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;
+ T guess;
+ if(boost::is_fundamental<T>::value)
+ {
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ guess = ldexp(static_cast<T>(1), exponent / 3); // Rough guess is to divide the exponent by three.
+ }
+ else
+ guess = boost::math::cbrt(static_cast<double>(x));
+ T min = guess / 2; // Minimum possible value is half our guess.
+ T max = 2 * guess; // Maximum possible value is twice our guess.
+ // digits used to control how accurate to try to make the result.
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
+ 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 Schroder algorithm.
+
+template <class T>
+T cbrt_2deriv_s(T x)
+{ // return cube root of x using 1st and 2nd derivatives and Schroder algorithm.
+ //using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools;
+ int exponent;
+ T guess;
+ if(boost::is_fundamental<T>::value)
+ {
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ guess = ldexp(static_cast<T>(1), exponent / 3); // Rough guess is to divide the exponent by three.
+ }
+ else
+ guess = boost::math::cbrt(static_cast<double>(x));
+ T min = guess / 2; // Minimum possible value is half our guess.
+ T max = 2 * guess; // Maximum possible value is twice our guess.
+ // digits used to control how accurate to try to make the result.
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ T result = schroder_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 = std::numeric_limits<T>::digits;
+
+ 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.
+ T sum = 0;
+
+ // 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); //
+ sum += result;
+ }
+ now = ti.elapsed();
+
+ 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;
+ }
+ 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); //
+ sum += result;
+ }
+ 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); //
+ sum += result;
+ }
+ 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); //
+ sum += result;
+ }
+ 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); //
+ sum += result;
+ }
+ 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++;
+ std::cout << "Accumulated sum was " << sum << std::endl;
+ 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.
+ test_root<float>(full_value, full_answer, "float");
+ test_root<double>(full_value, full_answer, "double");
+ test_root<long double>(full_value, full_answer, "long double");
+ test_root<cpp_bin_float_50>(full_value, full_answer, "cpp_bin_float_50");
+ //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 - 2 << ", " << static_cast<int>(root_infos[tp].get_digits * 0.6) << ", " << static_cast<int>(root_infos[tp].get_digits * 0.4) << 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;
+
+ // Row for all algorithms.
+ for (unsigned 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.
+#if 0
+ 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;
+#endif
+ // 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 (size_t 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] << "][";
+ if(fabs(root_infos[tp].normed_times[algo]) <= 1.05)
+ fout << "[role blue " << std::setw(3) << std::setprecision(2) << root_infos[tp].normed_times[algo] << "]";
+ else if(fabs(root_infos[tp].normed_times[algo]) > 4)
+ fout << "[role red " << std::setw(3) << std::setprecision(2) << root_infos[tp].normed_times[algo] << "]";
+ else
+ fout << std::setw(3) << std::setprecision(2) << root_infos[tp].normed_times[algo];
+ fout
+ << "]["
+ << 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 " << short_file_name(sourcefilename) << ", "
+ << BOOST_COMPILER << ", "
+ << BOOST_STDLIB << ", "
+ << BOOST_PLATFORM << (sizeof(void*) == 8 ? ", x64" : ", x86")
+ << debug_or_optimize << "[br]"
+ << count << " evaluations of each of " << algo_names.size() << " root_finding algorithms."
+ << "]"
+ << 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 const& 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> ==================================================================
+
+
+
+*/
diff --git a/src/boost/libs/math/example/root_finding_example.cpp b/src/boost/libs/math/example/root_finding_example.cpp
new file mode 100644
index 000000000..57583b274
--- /dev/null
+++ b/src/boost/libs/math/example/root_finding_example.cpp
@@ -0,0 +1,547 @@
+// root_finding_example.cpp
+
+// Copyright Paul A. Bristow 2010, 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)
+
+// Example of finding roots using Newton-Raphson, Halley.
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+//#define BOOST_MATH_INSTRUMENT
+
+/*
+This example demonstrates how to use the various tools for root finding
+taking the simple cube root function (`cbrt`) as an example.
+
+It shows how use of derivatives can improve the speed.
+(But is only a demonstration and does not try to make the ultimate improvements of 'real-life'
+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 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.
+
+First some `#includes` that will be needed.
+
+[tip For clarity, `using` statements are provided to list what functions are being used in this example:
+you can of course partly or fully qualify the names in other ways.
+(For your application, you may wish to extract some parts into header files,
+but you should never use `using` statements globally in header files).]
+*/
+
+//[root_finding_include_1
+
+#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;
+
+#include <boost/math/special_functions/next.hpp> // For float_distance.
+#include <tuple> // for std::tuple and std::make_tuple.
+#include <boost/math/special_functions/cbrt.hpp> // For boost::math::cbrt.
+
+//] [/root_finding_include_1]
+
+// using boost::math::tuple;
+// using boost::math::make_tuple;
+// using boost::math::tie;
+// which provide convenient aliases for various implementations,
+// including std::tr1, depending on what is available.
+
+#include <iostream>
+//using std::cout; using std::endl;
+#include <iomanip>
+//using std::setw; using std::setprecision;
+#include <limits>
+//using std::numeric_limits;
+
+/*
+
+Let's suppose we want to find the root of a number ['a], and to start, compute the cube root.
+
+So the equation we want to solve is:
+
+__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.
+
+We then show how adding what we can know about this function, first just the slope,
+the 1st derivation /f'(x)/, will speed homing in on the solution.
+
+Lastly we show how adding the curvature /f''(x)/ too will speed convergence even more.
+
+*/
+
+//[root_finding_noderiv_1
+
+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'.
+};
+//] [/root_finding_noderiv_1
+
+/*
+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'.)
+
+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').
+*/
+
+//[root_finding_noderiv_2
+
+template <class T>
+T cbrt_noderiv(T x)
+{
+ // return cube root of x using bracket_and_solve (no derivatives).
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For bracket_and_solve_root.
+
+ int exponent;
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ T guess = ldexp(1., exponent/3); // Rough guess is to divide the exponent by three.
+ T factor = 2; // How big steps to take when searching.
+
+ const boost::uintmax_t maxit = 20; // Limit to maximum iterations.
+ boost::uintmax_t it = maxit; // Initially 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 = digits - 3; // We have to have a non-zero interval at each step, so
+ // maximum accuracy is digits - 1. But we also have to
+ // allow for inaccuracy in f(x), otherwise the last few
+ // iterations just thrash around.
+ 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 is our result, if necessary we could
+ // return the result as an interval here.
+}
+
+/*`
+
+[note The final parameter specifying a maximum number of iterations is optional.
+However, it defaults to `boost::uintmax_t maxit = (std::numeric_limits<boost::uintmax_t>::max)();`
+which is `18446744073709551615` and is more than anyone would wish to wait for!
+
+So it may be wise to chose some reasonable estimate of how many iterations may be needed,
+In this case the function is so well behaved that we can chose a low value of 20.
+
+Internally when Boost.Math uses these functions, it sets the maximum iterations to
+`policies::get_max_root_iterations<Policy>();`.]
+
+Should we have wished we can show how many iterations were used in `bracket_and_solve_root`
+(this information is lost outside `cbrt_noderiv`), for example with:
+
+ if (it >= maxit)
+ {
+ 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;
+ }
+
+for output like
+
+ Converged after 11 (from maximum of 20 iterations).
+*/
+//] [/root_finding_noderiv_2]
+
+
+// Cube root with 1st derivative (slope)
+
+/*
+We now solve the same problem, but using more information about the function,
+to show how this can speed up finding the best estimate of the root.
+
+For the root function, the 1st differential (the slope of the tangent to a curve at any point) is known.
+
+If you need some reminders then
+[@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]],
+allows us to get the 1st differential as ['3x[super 2]].
+
+To see how this extra information is used to find a root, view
+[@http://en.wikipedia.org/wiki/Newton%27s_method Newton-Raphson iterations]
+and the [@http://en.wikipedia.org/wiki/Newton%27s_method#mediaviewer/File:NewtonIteration_Ani.gif animation].
+
+We need to define a different functor `cbrt_functor_deriv` that returns
+both the evaluation of the function to solve, along with its first derivative:
+
+To \'return\' two values, we use a `std::pair` of floating-point values
+(though we could equally have used a std::tuple):
+*/
+
+//[root_finding_1_deriv_1
+
+template <class T>
+struct cbrt_functor_deriv
+{ // 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>(a) to use to get cube root of a.
+ }
+ 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; // Store value to be 'cube_rooted'.
+};
+
+/*`Our cube root function is now:*/
+
+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(1., exponent/3); // Rough guess is to divide the exponent by three.
+ T min = ldexp(0.5, exponent/3); // Minimum possible value is half our guess.
+ T max = ldexp(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 * 0.6); // Accuracy doubles with each step, so stop when we have
+ // just over half the digits correct.
+ 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);
+ return result;
+}
+
+//] [/root_finding_1_deriv_1]
+
+
+/*
+[h3:cbrt_2_derivatives Cube root with 1st & 2nd derivative (slope & curvature)]
+
+Finally we define yet another functor `cbrt_functor_2deriv` that returns
+both the evaluation of the function to solve,
+along with its first *and second* derivatives:
+
+__spaces[''f](x) = 6x
+
+To \'return\' three values, we use a `tuple` of three floating-point values:
+*/
+
+//[root_finding_2deriv_1
+
+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,
+ }
+ 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).
+ 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.
+ }
+private:
+ T a; // to be 'cube_rooted'.
+};
+
+/*`Our cube root function is now:*/
+
+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(1., exponent/3); // Rough guess is to divide the exponent by three.
+ T min = ldexp(0.5, exponent/3); // Minimum possible value is half our guess.
+ T max = ldexp(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 * 0.4); // Accuracy triples with each step, so stop when just
+ // over one third of the digits are correct.
+ boost::uintmax_t maxit = 20;
+ T result = halley_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, maxit);
+ return result;
+}
+
+//] [/root_finding_2deriv_1]
+
+//[root_finding_2deriv_lambda
+
+template <class T>
+T cbrt_2deriv_lambda(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(1., exponent / 3); // Rough guess is to divide the exponent by three.
+ T min = ldexp(0.5, exponent / 3); // Minimum possible value is half our guess.
+ T max = ldexp(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 * 0.4); // Accuracy triples with each step, so stop when just
+ // over one third of the digits are correct.
+ boost::uintmax_t maxit = 20;
+ T result = halley_iterate(
+ // lambda function:
+ [x](const T& g){ return std::make_tuple(g * g * g - x, 3 * g * g, 6 * g); },
+ guess, min, max, get_digits, maxit);
+ return result;
+}
+
+//] [/root_finding_2deriv_lambda]
+/*
+
+[h3 Fifth-root function]
+Let's now suppose we want to find the [*fifth root] of a number ['a].
+
+The equation we want to solve is :
+
+__spaces['f](x) = x[super 5] - a
+
+If your differentiation is a little rusty
+(or you are faced with an equation whose complexity is daunting),
+then you can get help, for example from the invaluable
+[@http://www.wolframalpha.com/ WolframAlpha site.]
+
+For example, entering the command: `differentiate x ^ 5`
+
+or the Wolfram Language command: ` D[x ^ 5, x]`
+
+gives the output: `d/dx(x ^ 5) = 5 x ^ 4`
+
+and to get the second differential, enter: `second differentiate x ^ 5`
+
+or the Wolfram Language command: `D[x ^ 5, { x, 2 }]`
+
+to get the output: `d ^ 2 / dx ^ 2(x ^ 5) = 20 x ^ 3`
+
+To get a reference value, we can enter: [^fifth root 3126]
+
+or: `N[3126 ^ (1 / 5), 50]`
+
+to get a result with a precision of 50 decimal digits:
+
+5.0003199590478625588206333405631053401128722314376
+
+(We could also get a reference value using Boost.Multiprecision - see below).
+
+The 1st and 2nd derivatives of x[super 5] are:
+
+__spaces['f]\'(x) = 5x[super 4]
+
+__spaces['f]\'\'(x) = 20x[super 3]
+
+*/
+
+//[root_finding_fifth_1
+//] [/root_finding_fifth_1]
+
+
+//[root_finding_fifth_functor_2deriv
+
+/*`Using these expressions for the derivatives, the functor is:
+*/
+
+template <class T>
+struct fifth_functor_2deriv
+{
+ // Functor returning both 1st and 2nd derivatives.
+ fifth_functor_2deriv(T const& to_find_root_of) : a(to_find_root_of)
+ { /* Constructor stores value a to find root of, for example: */ }
+
+ std::tuple<T, T, T> operator()(T const& x)
+ {
+ // Return both f(x) and f'(x) and f''(x).
+ T fx = boost::math::pow<5>(x) - a; // Difference (estimate x^3 - value).
+ T dx = 5 * boost::math::pow<4>(x); // 1st derivative = 5x^4.
+ T d2x = 20 * boost::math::pow<3>(x); // 2nd derivative = 20 x^3
+ return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
+ }
+private:
+ T a; // to be 'fifth_rooted'.
+}; // struct fifth_functor_2deriv
+
+//] [/root_finding_fifth_functor_2deriv]
+
+//[root_finding_fifth_2deriv
+
+/*`Our fifth-root function is now:
+*/
+
+template <class T>
+T fifth_2deriv(T x)
+{
+ // return fifth 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.
+
+ int exponent;
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ T guess = ldexp(1., exponent / 5); // Rough guess is to divide the exponent by five.
+ T min = ldexp(0.5, exponent / 5); // Minimum possible value is half our guess.
+ T max = ldexp(2., exponent / 5); // Maximum possible value is twice our guess.
+ // Stop when slightly more than one of the digits are correct:
+ const int digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
+ const boost::uintmax_t maxit = 50;
+ boost::uintmax_t it = maxit;
+ T result = halley_iterate(fifth_functor_2deriv<T>(x), guess, min, max, digits, it);
+ return result;
+}
+
+//] [/root_finding_fifth_2deriv]
+
+
+int main()
+{
+ std::cout << "Root finding Examples." << std::endl;
+ std::cout.precision(std::numeric_limits<double>::max_digits10);
+ // Show all possibly significant decimal digits for double.
+ // std::cout.precision(std::numeric_limits<double>::digits10);
+ // Show all guaranteed significant decimal digits for double.
+
+
+//[root_finding_main_1
+ try
+ {
+ 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.
+ std::cout <<" cast double " << static_cast<double>(3.0365889718756625194208095785056696355814539772481111) << std::endl;
+
+ // Cube root using bracketing:
+ double r = cbrt_noderiv(threecubed);
+ std::cout << "cbrt_noderiv(" << threecubed << ") = " << r << std::endl;
+ r = cbrt_noderiv(threecubedp1);
+ std::cout << "cbrt_noderiv(" << threecubedp1 << ") = " << r << std::endl;
+//] [/root_finding_main_1]
+ //[root_finding_main_2
+
+ // Cube root using 1st differential Newton-Raphson:
+ r = cbrt_deriv(threecubed);
+ std::cout << "cbrt_deriv(" << threecubed << ") = " << r << std::endl;
+ r = cbrt_deriv(threecubedp1);
+ std::cout << "cbrt_deriv(" << threecubedp1 << ") = " << r << std::endl;
+
+ // Cube root using Halley with 1st and 2nd differentials.
+ r = cbrt_2deriv(threecubed);
+ std::cout << "cbrt_2deriv(" << threecubed << ") = " << r << std::endl;
+ r = cbrt_2deriv(threecubedp1);
+ std::cout << "cbrt_2deriv(" << threecubedp1 << ") = " << r << std::endl;
+
+ // Cube root using lambda's:
+ r = cbrt_2deriv_lambda(threecubed);
+ std::cout << "cbrt_2deriv(" << threecubed << ") = " << r << std::endl;
+ r = cbrt_2deriv_lambda(threecubedp1);
+ std::cout << "cbrt_2deriv(" << threecubedp1 << ") = " << r << std::endl;
+
+ // Fifth root.
+
+ double fivepowfive = 3125; // Example of a value that has an exact integer fifth root.
+ // Exact value of fifth root is exactly 5.
+ std::cout << "Fifth root of " << fivepowfive << " is " << 5 << std::endl;
+
+ double fivepowfivep1 = fivepowfive + 1; // Example of a value whose fifth root is *not* exactly representable.
+ // Value of fifth root is 5.0003199590478625588206333405631053401128722314376 (50 decimal digits precision)
+ // and to std::numeric_limits<double>::max_digits10 double precision (usually 17) is
+
+ double root5v2 = static_cast<double>(5.0003199590478625588206333405631053401128722314376);
+ std::cout << "Fifth root of " << fivepowfivep1 << " is " << root5v2 << std::endl;
+
+ // Using Halley with 1st and 2nd differentials.
+ r = fifth_2deriv(fivepowfive);
+ std::cout << "fifth_2deriv(" << fivepowfive << ") = " << r << std::endl;
+ r = fifth_2deriv(fivepowfivep1);
+ std::cout << "fifth_2deriv(" << fivepowfivep1 << ") = " << r << std::endl;
+//] [/root_finding_main_?]
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+//[root_finding_example_output
+/*`
+Normal output is:
+
+[pre
+ root_finding_example.cpp
+ Generating code
+ Finished generating code
+ root_finding_example.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\root_finding_example.exe
+ Cube Root finding (cbrt) Example.
+ Iterations 10
+ cbrt_1(27) = 3
+ Iterations 10
+ Unable to locate solution in chosen iterations: Current best guess is between 3.0365889718756613 and 3.0365889718756627
+ cbrt_1(28) = 3.0365889718756618
+ cbrt_1(27) = 3
+ cbrt_2(28) = 3.0365889718756627
+ Iterations 4
+ cbrt_3(27) = 3
+ Iterations 5
+ cbrt_3(28) = 3.0365889718756627
+
+] [/pre]
+
+to get some (much!) diagnostic output we can add
+
+#define BOOST_MATH_INSTRUMENT
+
+[pre
+
+]
+*/
+//] [/root_finding_example_output]
+
+/*
+
+cbrt(28) 3.0365889718756622
+std::cbrt(28) 3.0365889718756627
+
+*/
diff --git a/src/boost/libs/math/example/root_finding_fifth.cpp b/src/boost/libs/math/example/root_finding_fifth.cpp
new file mode 100644
index 000000000..6c9811475
--- /dev/null
+++ b/src/boost/libs/math/example/root_finding_fifth.cpp
@@ -0,0 +1,485 @@
+// root_finding_fith.cpp
+
+// Copyright Paul A. Bristow 2014.
+
+// 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)
+
+// Example of finding fifth root using Newton-Raphson, Halley, Schroder, TOMS748 .
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+// To get (copious!) diagnostic output, add make this define here or elsewhere.
+//#define BOOST_MATH_INSTRUMENT
+
+
+//[root_fifth_headers
+/*
+This example demonstrates how to use the Boost.Math tools for root finding,
+taking the fifth root function (fifth_root) as an example.
+It shows how use of derivatives can improve the speed.
+
+First some includes that will be needed.
+Using statements are provided to list what functions are being used in this example:
+you can of course qualify the names in other ways.
+*/
+
+#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;
+
+#include <boost/math/special_functions/next.hpp>
+
+#include <tuple>
+#include <utility> // pair, make_pair
+
+//] [/root_finding_headers]
+
+#include <iostream>
+using std::cout; using std::endl;
+#include <iomanip>
+using std::setw; using std::setprecision;
+#include <limits>
+using std::numeric_limits;
+
+/*
+//[root_finding_fifth_1
+Let's suppose we want to find the fifth root of a number.
+
+The equation we want to solve is:
+
+__spaces ['f](x) = x[fifth]
+
+We will first solve this without using any information
+about the slope or curvature of the fifth function.
+
+If your differentiation is a little rusty
+(or you are faced with an equation whose complexity is daunting,
+then you can get help, for example from the invaluable
+
+http://www.wolframalpha.com/ site
+
+entering the command
+
+ differentiate x^5
+
+or the Wolfram Language command
+
+ D[x^5, x]
+
+gives the output
+
+ d/dx(x^5) = 5 x^4
+
+and to get the second differential, enter
+
+ second differentiate x^5
+
+or the Wolfram Language
+
+ D[x^5, {x, 2}]
+
+to get the output
+
+ d^2/dx^2(x^5) = 20 x^3
+
+or
+
+ 20 x^3
+
+To get a reference value we can enter
+
+ fifth root 3126
+
+or
+
+ N[3126^(1/5), 50]
+
+to get a result with a precision of 50 decimal digits
+
+ 5.0003199590478625588206333405631053401128722314376
+
+(We could also get a reference value using Boost.Multiprecision).
+
+We then show how adding what we can know, for this function, about the slope,
+the 1st derivation /f'(x)/, will speed homing in on the solution,
+and then finally how adding the curvature /f''(x)/ as well will improve even more.
+
+The 1st and 2nd derivatives of x[fifth] are:
+
+__spaces ['f]\'(x) = 2x[sup2]
+
+__spaces ['f]\'\'(x) = 6x
+
+*/
+
+//] [/root_finding_fifth_1]
+
+//[root_finding_fifth_functor_noderiv
+
+template <class T>
+struct fifth_functor_noderiv
+{ // fifth root of x using only function - no derivatives.
+ fifth_functor_noderiv(T const& to_find_root_of) : value(to_find_root_of)
+ { // Constructor stores value to find root of.
+ // For example: calling fifth_functor<T>(x) to get fifth root of x.
+ }
+ T operator()(T const& x)
+ { //! \returns f(x) - value.
+ T fx = x*x*x*x*x - value; // Difference (estimate x^5 - value).
+ return fx;
+ }
+private:
+ T value; // to be 'fifth_rooted'.
+};
+
+//] [/root_finding_fifth_functor_noderiv]
+
+//cout << ", std::numeric_limits<" << typeid(T).name() << ">::digits = " << digits
+// << ", accuracy " << get_digits << " bits."<< endl;
+
+
+/*`Implementing the fifth 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 five.
+(There are better but more complex guess algorithms used in 'real-life'.)
+
+fifth 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').
+*/
+
+//[root_finding_fifth_noderiv
+
+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::tools; // For bracket_and_solve_root.
+
+ int exponent;
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ T guess = ldexp(1., exponent / 5); // Rough guess is to divide the exponent by five.
+ T factor = 2; // To multiply and divide guess to bracket.
+ // digits used to control how accurate to try to make the result.
+ // int digits = 3 * std::numeric_limits<T>::digits / 4; // 3/4 maximum possible binary digits accuracy for type T.
+ int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
+
+ //boost::uintmax_t maxit = (std::numeric_limits<boost::uintmax_t>::max)();
+ // (std::numeric_limits<boost::uintmax_t>::max)() = 18446744073709551615
+ // which is more than anyone might wish to wait for!!!
+ // so better to choose some reasonable estimate of how many iterations may be needed.
+
+ const boost::uintmax_t maxit = 50; // Chosen max iterations,
+ // but updated on exit with actual iteration count.
+
+ // We could also have used a maximum iterations provided by any policy:
+ // boost::uintmax_t max_it = policies::get_max_root_iterations<Policy>();
+
+ boost::uintmax_t it = maxit; // Initially our chosen max iterations,
+
+ bool is_rising = true; // So if result if guess^5 is too low, try increasing guess.
+ eps_tolerance<double> tol(digits);
+ std::pair<T, T> r =
+ bracket_and_solve_root(fifth_functor_noderiv<T>(x), guess, factor, is_rising, tol, it);
+ // because the iteration count is updating,
+ // you can't call with a literal maximum iterations value thus:
+ //bracket_and_solve_root(fifth_functor_noderiv<T>(x), guess, factor, is_rising, tol, 20);
+
+ // Can show how many iterations (this information is lost outside fifth_noderiv).
+ cout << "Iterations " << it << endl;
+ if (it >= maxit)
+ { // Failed to converge (or is jumping between bracket values).
+ cout << "Unable to locate solution in chosen iterations:"
+ " Current best guess is between " << r.first << " and " << r.second << endl;
+ }
+ T distance = float_distance(r.first, r.second);
+ if (distance > 0)
+ { //
+ std::cout << distance << " bits separate the bracketing values." << std::endl;
+ for (int i = 0; i < distance; i++)
+ { // Show all the values within the bracketing values.
+ std::cout << float_advance(r.first, i) << std::endl;
+ }
+ }
+ else
+ { // distance == 0 and r.second == r.first
+ std::cout << "Converged to a single value " << r.first << std::endl;
+ }
+
+ return r.first + (r.second - r.first) / 2; // return midway between bracketed interval.
+} // T fifth_noderiv(T x)
+
+//] [/root_finding_fifth_noderiv]
+
+
+
+// maxit = 10
+// Unable to locate solution in chosen iterations: Current best guess is between 3.0365889718756613 and 3.0365889718756627
+
+
+/*`
+We now solve the same problem, but using more information about the function,
+to show how this can speed up finding the best estimate of the root.
+
+For this function, the 1st differential (the slope of the tangent to a curve at any point) is known.
+
+[@http://en.wikipedia.org/wiki/Derivative#Derivatives_of_elementary_functions Derivatives]
+gives some reminders.
+
+Using the rule that the derivative of x^n for positive n (actually all nonzero n) is nx^n-1,
+allows use to get the 1st differential as 3x^2.
+
+To see how this extra information is used to find the root, view this demo:
+[@http://en.wikipedia.org/wiki/Newton%27s_methodNewton Newton-Raphson iterations].
+
+We need to define a different functor that returns
+both the evaluation of the function to solve, along with its first derivative:
+
+To \'return\' two values, we use a pair of floating-point values:
+*/
+
+//[root_finding_fifth_functor_1stderiv
+
+template <class T>
+struct fifth_functor_1stderiv
+{ // Functor returning function and 1st derivative.
+
+ fifth_functor_1stderiv(T const& target) : value(target)
+ { // Constructor stores the value to be 'fifth_rooted'.
+ }
+
+ std::pair<T, T> operator()(T const& z) // z is best estimate so far.
+ { // Return both f(x) and first derivative f'(x).
+ T fx = z*z*z*z*z - value; // Difference estimate fx = x^5 - value.
+ T d1x = 5 * z*z*z*z; // 1st derivative d1x = 5x^4.
+ return std::make_pair(fx, d1x); // 'return' both fx and d1x.
+ }
+private:
+ T value; // to be 'fifth_rooted'.
+}; // fifth_functor_1stderiv
+
+//] [/root_finding_fifth_functor_1stderiv]
+
+
+/*`Our fifth root function using fifth_functor_1stderiv is now:*/
+
+//[root_finding_fifth_1deriv
+
+template <class T>
+T fifth_1deriv(T x)
+{ //! \return fifth root of x using 1st derivative and Newton_Raphson.
+ using namespace std; // For frexp, ldexp, numeric_limits.
+ using namespace boost::math::tools; // For newton_raphson_iterate.
+
+ int exponent;
+ frexp(x, &exponent); // Get exponent of x (ignore mantissa).
+ T guess = ldexp(1., exponent / 5); // Rough guess is to divide the exponent by three.
+ // Set an initial bracket interval.
+ T min = ldexp(0.5, exponent / 5); // Minimum possible value is half our guess.
+ T max = ldexp(2., exponent / 5);// Maximum possible value is twice our guess.
+
+ // digits used to control how accurate to try to make the result.
+ int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
+
+ const boost::uintmax_t maxit = 20; // Optionally limit the number of iterations.
+ boost::uintmax_t it = maxit; // limit the number of iterations.
+ //cout << "Max Iterations " << maxit << endl; //
+ T result = newton_raphson_iterate(fifth_functor_1stderiv<T>(x), guess, min, max, digits, it);
+ // Can check and show how many iterations (updated by newton_raphson_iterate).
+ cout << it << " iterations (from max of " << maxit << ")" << endl;
+ return result;
+} // fifth_1deriv
+
+//] [/root_finding_fifth_1deriv]
+
+// int get_digits = (digits * 2) /3; // Two thirds of maximum possible accuracy.
+
+//boost::uintmax_t maxit = (std::numeric_limits<boost::uintmax_t>::max)();
+// the default (std::numeric_limits<boost::uintmax_t>::max)() = 18446744073709551615
+// which is more than we might wish to wait for!!! so we can reduce it
+
+/*`
+Finally need to define yet another functor that returns
+both the evaluation of the function to solve,
+along with its first and second derivatives:
+
+f''(x) = 3 * 3x
+
+To \'return\' three values, we use a tuple of three floating-point values:
+*/
+
+//[root_finding_fifth_functor_2deriv
+
+template <class T>
+struct fifth_functor_2deriv
+{ // Functor returning both 1st and 2nd derivatives.
+ fifth_functor_2deriv(T const& to_find_root_of) : value(to_find_root_of)
+ { // Constructor stores value to find root of, for example:
+ }
+
+ // using boost::math::tuple; // to return three values.
+ std::tuple<T, T, T> operator()(T const& x)
+ { // Return both f(x) and f'(x) and f''(x).
+ T fx = x*x*x*x*x - value; // Difference (estimate x^3 - value).
+ T dx = 5 * x*x*x*x; // 1st derivative = 5x^4.
+ T d2x = 20 * x*x*x; // 2nd derivative = 20 x^3
+ return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
+ }
+private:
+ T value; // to be 'fifth_rooted'.
+}; // struct fifth_functor_2deriv
+
+//] [/root_finding_fifth_functor_2deriv]
+
+
+/*`Our fifth function is now:*/
+
+//[root_finding_fifth_2deriv
+
+template <class T>
+T fifth_2deriv(T x)
+{ // return fifth root of x using 1st and 2nd derivatives and Halley.
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math; // halley_iterate
+
+ int exponent;
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ T guess = ldexp(1., exponent / 5); // Rough guess is to divide the exponent by three.
+ T min = ldexp(0.5, exponent / 5); // Minimum possible value is half our guess.
+ T max = ldexp(2., exponent / 5); // Maximum possible value is twice our guess.
+
+ int digits = std::numeric_limits<T>::digits / 2; // Half maximum possible binary digits accuracy for type T.
+ const boost::uintmax_t maxit = 50;
+ boost::uintmax_t it = maxit;
+ T result = halley_iterate(fifth_functor_2deriv<T>(x), guess, min, max, digits, it);
+ // Can show how many iterations (updated by halley_iterate).
+ cout << it << " iterations (from max of " << maxit << ")" << endl;
+
+ return result;
+} // fifth_2deriv(x)
+
+//] [/root_finding_fifth_2deriv]
+
+int main()
+{
+
+ //[root_finding_example_1
+ cout << "fifth Root finding (fifth) Example." << endl;
+ // Show all possibly significant decimal digits.
+ cout.precision(std::numeric_limits<double>::max_digits10);
+ // or use cout.precision(max_digits10 = 2 + std::numeric_limits<double>::digits * 3010/10000);
+ try
+ { // Always use try'n'catch blocks with Boost.Math to get any error messages.
+
+ double v27 = 3125; // Example of a value that has an exact integer fifth root.
+ // exact value of fifth root is exactly 5.
+
+ std::cout << "Fifth root of " << v27 << " is " << 5 << std::endl;
+
+ double v28 = v27+1; // Example of a value whose fifth root is *not* exactly representable.
+ // Value of fifth root is 5.0003199590478625588206333405631053401128722314376 (50 decimal digits precision)
+ // and to std::numeric_limits<double>::max_digits10 double precision (usually 17) is
+
+ double root5v2 = static_cast<double>(5.0003199590478625588206333405631053401128722314376);
+
+ std::cout << "Fifth root of " << v28 << " is " << root5v2 << std::endl;
+
+ // Using bracketing:
+ double r = fifth_noderiv(v27);
+ cout << "fifth_noderiv(" << v27 << ") = " << r << endl;
+
+ r = fifth_noderiv(v28);
+ cout << "fifth_noderiv(" << v28 << ") = " << r << endl;
+
+ // Using 1st differential Newton-Raphson:
+ r = fifth_1deriv(v27);
+ cout << "fifth_1deriv(" << v27 << ") = " << r << endl;
+ r = fifth_1deriv(v28);
+ cout << "fifth_1deriv(" << v28 << ") = " << r << endl;
+
+ // Using Halley with 1st and 2nd differentials.
+ r = fifth_2deriv(v27);
+ cout << "fifth_2deriv(" << v27 << ") = " << r << endl;
+ r = fifth_2deriv(v28);
+ cout << "fifth_2deriv(" << v28 << ") = " << r << endl;
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ //] [/root_finding_example_1
+ return 0;
+} // int main()
+
+//[root_finding_example_output
+/*`
+Normal output is:
+
+[pre
+1> Description: Autorun "J:\Cpp\MathToolkit\test\Math_test\Release\root_finding_fifth.exe"
+1> fifth Root finding (fifth) Example.
+1> Fifth root of 3125 is 5
+1> Fifth root of 3126 is 5.0003199590478626
+1> Iterations 10
+1> Converged to a single value 5
+1> fifth_noderiv(3125) = 5
+1> Iterations 11
+1> 2 bits separate the bracketing values.
+1> 5.0003199590478609
+1> 5.0003199590478618
+1> fifth_noderiv(3126) = 5.0003199590478618
+1> 6 iterations (from max of 20)
+1> fifth_1deriv(3125) = 5
+1> 7 iterations (from max of 20)
+1> fifth_1deriv(3126) = 5.0003199590478626
+1> 4 iterations (from max of 50)
+1> fifth_2deriv(3125) = 5
+1> 4 iterations (from max of 50)
+1> fifth_2deriv(3126) = 5.0003199590478626
+[/pre]
+
+to get some (much!) diagnostic output we can add
+
+#define BOOST_MATH_INSTRUMENT
+
+[pre
+1> fifth Root finding (fifth) Example.
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:537 a = 4 b = 8 fa = -2101 fb = 29643 count = 18
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:340 a = 4.264742943548387 b = 8
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:352 a = 4.264742943548387 b = 5.1409225585147951
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:259 a = 4.264742943548387 b = 5.1409225585147951 d = 8 e = 4 fa = -1714.2037505671719 fb = 465.91652114644285 fd = 29643 fe = -2101
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:267 q11 = -3.735257056451613 q21 = -0.045655399937094755 q31 = 0.68893005658139972 d21 = -2.9047328414222999 d31 = -0.18724955838500826
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:275 q22 = -0.15074699539567221 q32 = 0.007740525571111408 d32 = -0.13385363287680208 q33 = 0.074868009790687237 c = 5.0362815354915851
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:388 a = 4.264742943548387 b = 5.0362815354915851
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:259 a = 4.264742943548387 b = 5.0362815354915851 d = 5.1409225585147951 e = 8 fa = -1714.2037505671719 fb = 115.03721886368339 fd = 465.91652114644285 fe = 29643
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:267 q11 = -0.045655399937094755 q21 = -0.034306988726112195 q31 = 0.7230181097615842 d21 = -0.1389480117493222 d31 = -0.048520482181613811
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:275 q22 = -0.00036345624935100459 q32 = 0.011175908093791367 d32 = -0.0030375853617102483 q33 = 0.00014618657296010219 c = 4.999083147976723
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:408 a = 4.999083147976723 b = 5.0362815354915851
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:433 a = 4.999083147976723 b = 5.0008904277935091
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:434 tol = -0.00036152225583956088
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:259 a = 4.999083147976723 b = 5.0008904277935091 d = 5.0362815354915851 e = 4.264742943548387 fa = -2.8641119933622576 fb = 2.7835781082976609 fd = 115.03721886368339 fe = -1714.2037505671719
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:267 q11 = -0.048520482181613811 q21 = -0.00087760104664616457 q31 = 0.00091652546535745522 d21 = -0.036268708744722128 d31 = -0.00089075435142862297
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:275 q22 = -1.9862562616034592e-005 q32 = 3.1952597740788757e-007 d32 = -1.2833778805050512e-005 q33 = 1.1763429980834706e-008 c = 5.0000000047314881
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:388 a = 4.999083147976723 b = 5.0000000047314881
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:259 a = 4.999083147976723 b = 5.0000000047314881 d = 5.0008904277935091 e = 5.0362815354915851 fa = -2.8641119933622576 fb = 1.4785900475544622e-005 fd = 2.7835781082976609 fe = 115.03721886368339
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:267 q11 = -0.00087760104664616457 q21 = -4.7298032238887272e-009 q31 = 0.00091685202154135855 d21 = -0.00089042779182425238 d31 = -4.7332236912279757e-009
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:275 q22 = -1.6486403607318402e-012 q32 = 1.7346209428817704e-012 d32 = -1.6858463963666777e-012 q33 = 9.0382569995250912e-016 c = 5
+1> I:\modular-boost\boost/math/tools/toms748_solve.hpp:592 max_iter = 10 count = 7
+1> Iterations 20
+1> 0 bits separate brackets.
+1> fifth_noderiv(3125) = 5
+]
+*/
+//] [/root_finding_example_output]
diff --git a/src/boost/libs/math/example/root_finding_multiprecision_example.cpp b/src/boost/libs/math/example/root_finding_multiprecision_example.cpp
new file mode 100644
index 000000000..0b1452ba1
--- /dev/null
+++ b/src/boost/libs/math/example/root_finding_multiprecision_example.cpp
@@ -0,0 +1,232 @@
+// 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)
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+// Example of root finding using Boost.Multiprecision.
+
+#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;
+
+#include <boost/math/special_functions/next.hpp> // For float_distance.
+#include <boost/math/special_functions/pow.hpp>
+#include <boost/math/constants/constants.hpp>
+
+//[root_finding_multiprecision_include_1
+#include <boost/multiprecision/cpp_bin_float.hpp> // For cpp_bin_float_50.
+#include <boost/multiprecision/cpp_dec_float.hpp> // For cpp_dec_float_50.
+#ifndef _MSC_VER // float128 is not yet supported by Microsoft compiler at 2013.
+# include <boost/multiprecision/float128.hpp> // Requires libquadmath.
+#endif
+//] [/root_finding_multiprecision_include_1]
+
+#include <iostream>
+// using std::cout; using std::endl;
+#include <iomanip>
+// using std::setw; using std::setprecision;
+#include <limits>
+// using std::numeric_limits;
+#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.
+ using namespace std; // Help ADL of std functions.
+ 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 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.
+ // 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 " << it << " (from max of "<< maxit << ")." << std::endl;
+ return result;
+} // cbrt_2deriv(x)
+
+
+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 to find root of, for example:
+ }
+
+ // using boost::math::tuple; // to return three values.
+ 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.
+ }
+private:
+ T a; // to be 'cube_rooted'.
+}; // struct cbrt_functor_2deriv
+
+template <int n, class T>
+struct nth_functor_2deriv
+{ // Functor returning both 1st and 2nd derivatives.
+
+ nth_functor_2deriv(T const& to_find_root_of) : value(to_find_root_of)
+ { /* Constructor stores value to find root of, for example: */ }
+
+ // using std::tuple; // to return three values.
+ std::tuple<T, T, T> operator()(T const& x)
+ {
+ // Return both f(x) and f'(x) and f''(x).
+ using boost::math::pow;
+ T fx = pow<n>(x) - value; // Difference (estimate x^3 - value).
+ T dx = n * pow<n - 1>(x); // 1st derivative = 5x^4.
+ T d2x = n * (n - 1) * pow<n - 2 >(x); // 2nd derivative = 20 x^3
+ return std::make_tuple(fx, dx, d2x); // 'return' fx, dx and d2x.
+ }
+private:
+ T value; // to be 'nth_rooted'.
+}; // struct nth_functor_2deriv
+
+
+template <int n, class T>
+T nth_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; // For halley_iterate.
+
+ int exponent;
+ frexp(x, &exponent); // Get exponent of z (ignore mantissa).
+ T guess = ldexp(static_cast<T>(1.), exponent / n); // Rough guess is to divide the exponent by three.
+ T min = ldexp(static_cast<T>(0.5), exponent / n); // Minimum possible value is half our guess.
+ T max = ldexp(static_cast<T>(2.), exponent / n); // Maximum possible value is twice our guess.
+
+ int digits = std::numeric_limits<T>::digits / 2; // Half maximum possible binary digits accuracy for type T.
+ const boost::uintmax_t maxit = 50;
+ 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).
+ std::cout << it << " iterations (from max of " << maxit << ")" << std::endl;
+
+ return result;
+} // nth_2deriv(x)
+
+//[root_finding_multiprecision_show_1
+
+template <typename T>
+T show_cube_root(T value)
+{ // Demonstrate by printing the root using all definitely significant digits.
+ std::cout.precision(std::numeric_limits<T>::digits10);
+ T r = cbrt_2deriv(value);
+ std::cout << "value = " << value << ", cube root =" << r << std::endl;
+ return r;
+}
+
+//] [/root_finding_multiprecision_show_1]
+
+int main()
+{
+ std::cout << "Multiprecision Root finding Example." << std::endl;
+ // Show all possibly significant decimal digits.
+ std::cout.precision(std::numeric_limits<double>::digits10);
+ // or use cout.precision(max_digits10 = 2 + std::numeric_limits<double>::digits * 3010/10000);
+ //[root_finding_multiprecision_example_1
+ using boost::multiprecision::cpp_dec_float_50; // decimal.
+ using boost::multiprecision::cpp_bin_float_50; // binary.
+#ifndef _MSC_VER // Not supported by Microsoft compiler.
+ using boost::multiprecision::float128;
+#endif
+ //] [/root_finding_multiprecision_example_1
+
+ try
+ { // Always use try'n'catch blocks with Boost.Math to get any error messages.
+ // Increase the precision to 50 decimal digits using Boost.Multiprecision
+//[root_finding_multiprecision_example_2
+
+ std::cout.precision(std::numeric_limits<cpp_dec_float_50>::digits10);
+
+ cpp_dec_float_50 two = 2; //
+ cpp_dec_float_50 r = cbrt_2deriv(two);
+ std::cout << "cbrt(" << two << ") = " << r << std::endl;
+
+ r = cbrt_2deriv(2.); // Passing a double, so ADL will compute a double precision result.
+ std::cout << "cbrt(" << two << ") = " << r << std::endl;
+ // cbrt(2) = 1.2599210498948731906665443602832965552806854248047 'wrong' from digits 17 onwards!
+ r = cbrt_2deriv(static_cast<cpp_dec_float_50>(2.)); // Passing a cpp_dec_float_50,
+ // so will compute a cpp_dec_float_50 precision result.
+ std::cout << "cbrt(" << two << ") = " << r << std::endl;
+ r = cbrt_2deriv<cpp_dec_float_50>(2.); // Explicitly a cpp_dec_float_50, so will compute a cpp_dec_float_50 precision result.
+ std::cout << "cbrt(" << two << ") = " << r << std::endl;
+ // cpp_dec_float_50 1.2599210498948731647672106072782283505702514647015
+//] [/root_finding_multiprecision_example_2
+ // N[2^(1/3), 50] 1.2599210498948731647672106072782283505702514647015
+
+ //show_cube_root(2); // Integer parameter - Errors!
+ //show_cube_root(2.F); // Float parameter - Warnings!
+//[root_finding_multiprecision_example_3
+ show_cube_root(2.);
+ show_cube_root(2.L);
+ show_cube_root(two);
+
+//] [/root_finding_multiprecision_example_3
+
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // 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
+
+
+*/
diff --git a/src/boost/libs/math/example/root_finding_n_example.cpp b/src/boost/libs/math/example/root_finding_n_example.cpp
new file mode 100644
index 000000000..096ed9545
--- /dev/null
+++ b/src/boost/libs/math/example/root_finding_n_example.cpp
@@ -0,0 +1,213 @@
+// Copyright Paul A. Bristow 2014, 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)
+
+// Note that this file contains Quickbook mark-up as well as code
+// and comments, don't change any of the special comment mark-ups!
+
+// Example of finding nth root using 1st and 2nd derivatives of x^n.
+
+#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;
+
+#include <boost/math/special_functions/next.hpp>
+#include <boost/multiprecision/cpp_dec_float.hpp>
+#include <boost/math/special_functions/pow.hpp>
+#include <boost/math/constants/constants.hpp>
+
+#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>
+#endif
+
+#include <iostream>
+// using std::cout; using std::endl;
+#include <iomanip>
+// using std::setw; using std::setprecision;
+#include <limits>
+using std::numeric_limits;
+#include <tuple>
+#include <utility> // pair, make_pair
+
+
+//[root_finding_nth_functor_2deriv
+template <int N, class T = double>
+struct nth_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_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;
+ 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'.
+};
+
+//] [/root_finding_nth_functor_2deriv]
+
+/*
+To show the progress, one might use this before the return statement above?
+#ifdef BOOST_MATH_ROOT_DIAGNOSTIC
+std::cout << " x = " << x << ", fx = " << fx << ", dx = " << dx << ", dx2 = " << d2x << std::endl;
+#endif
+*/
+
+// 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 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 the full range of T.
+// typedef double guess_type; is used to specify the this.
+
+//[root_finding_nth_function_2deriv
+
+template <int N, class T = double>
+T nth_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; // double may restrict (exponent) range for a multiprecision T?
+
+ int exponent;
+ frexp(static_cast<guess_type>(x), &exponent); // Get exponent of z (ignore mantissa).
+ T guess = ldexp(static_cast<guess_type>(1.), exponent / N); // Rough guess is to divide the exponent by n.
+ T min = ldexp(static_cast<guess_type>(1.) / 2, exponent / N); // Minimum possible value is half our guess.
+ T max = ldexp(static_cast<guess_type>(2.), exponent / N); // Maximum possible value is twice our guess.
+
+ int digits = std::numeric_limits<T>::digits * 0.4; // Accuracy triples with each step, so stop when
+ // slightly more than one third of the digits are correct.
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ T result = halley_iterate(nth_functor_2deriv<N, T>(x), guess, min, max, digits, it);
+ return result;
+}
+
+//] [/root_finding_nth_function_2deriv]
+
+
+template <int N, typename T = double>
+T show_nth_root(T value)
+{ // Demonstrate by printing the nth root using all possibly significant digits.
+ //std::cout.precision(std::numeric_limits<T>::max_digits10);
+ // or use cout.precision(max_digits10 = 2 + std::numeric_limits<double>::digits * 3010/10000);
+ // Or guaranteed significant digits:
+ std::cout.precision(std::numeric_limits<T>::digits10);
+
+ T r = nth_2deriv<N>(value);
+ std::cout << "Type " << typeid(T).name() << " value = " << value << ", " << N << "th root = " << r << std::endl;
+ return r;
+} // print_nth_root
+
+
+int main()
+{
+ std::cout << "nth Root finding Example." << std::endl;
+ using boost::multiprecision::cpp_dec_float_50; // decimal.
+ using boost::multiprecision::cpp_bin_float_50; // binary.
+#ifndef _MSC_VER // Not supported by Microsoft compiler.
+ using boost::multiprecision::float128; // Requires libquadmath
+#endif
+ try
+ { // Always use try'n'catch blocks with Boost.Math to get any error messages.
+
+//[root_finding_n_example_1
+ double r1 = nth_2deriv<5, double>(2); // Integral value converted to double.
+
+ // double r2 = nth_2deriv<5>(2); // Only floating-point type types can be used!
+
+//] [/root_finding_n_example_1
+
+ //show_nth_root<5, float>(2); // Integral value converted to float.
+ //show_nth_root<5, float>(2.F); // 'initializing' : conversion from 'double' to 'float', possible loss of data
+
+//[root_finding_n_example_2
+
+
+ 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<5, float128>(2);
+#endif
+ show_nth_root<5, cpp_dec_float_50>(2); // dec
+ show_nth_root<5, cpp_bin_float_50>(2); // bin
+//] [/root_finding_n_example_2
+
+ // show_nth_root<1000000>(2.); // Type double value = 2, 555th root = 1.00124969405651
+ // Type double value = 2, 1000th root = 1.00069338746258
+ // Type double value = 2, 1000000th root = 1.00000069314783
+ }
+ 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.
+ // 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 <<
+ "\n""Message from thrown exception was:\n " << e.what() << std::endl;
+ }
+ return 0;
+} // int main()
+
+
+/*
+//[root_finding_example_output_1
+ Using MSVC 2013
+
+nth Root finding Example.
+Type double value = 2, 5th root = 1.14869835499704
+Type long double value = 2, 5th root = 1.14869835499704
+Type class boost::multiprecision::number<class boost::multiprecision::backends::cpp_dec_float<50,int,void>,1> value = 2,
+ 5th root = 1.1486983549970350067986269467779275894438508890978
+Type class boost::multiprecision::number<class boost::multiprecision::backends::cpp_bin_float<50,10,void,int,0,0>,0> value = 2,
+ 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 :-(
+
+ */
diff --git a/src/boost/libs/math/example/root_finding_start_locations.cpp b/src/boost/libs/math/example/root_finding_start_locations.cpp
new file mode 100644
index 000000000..ba1e437af
--- /dev/null
+++ b/src/boost/libs/math/example/root_finding_start_locations.cpp
@@ -0,0 +1,449 @@
+// Copyright John Maddock 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 & Schroder 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!
+// 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/math/tools/roots.hpp>
+#include <boost/math/special_functions/ellint_1.hpp>
+#include <boost/math/special_functions/ellint_2.hpp>
+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'.
+};
+//] [/root_finding_noderiv_1
+
+template <class T>
+boost::uintmax_t cbrt_noderiv(T x, T guess)
+{
+ // return cube root of x using bracket_and_solve (no derivatives).
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For bracket_and_solve_root.
+
+ T factor = 2; // How big steps to take when searching.
+
+ const boost::uintmax_t maxit = 20; // Limit to maximum iterations.
+ boost::uintmax_t it = maxit; // Initially 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 = digits - 3; // We have to have a non-zero interval at each step, so
+ // maximum accuracy is digits - 1. But we also have to
+ // allow for inaccuracy in f(x), otherwise the last few
+ // iterations just thrash around.
+ eps_tolerance<T> tol(get_digits); // Set the tolerance.
+ bracket_and_solve_root(cbrt_functor_noderiv<T>(x), guess, factor, is_rising, tol, it);
+ return it;
+}
+
+template <class T>
+struct cbrt_functor_deriv
+{ // 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>(a) to use to get cube root of a.
+ }
+ 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; // Store value to be 'cube_rooted'.
+};
+
+template <class T>
+boost::uintmax_t cbrt_deriv(T x, T guess)
+{
+ // return cube root of x using 1st derivative and Newton_Raphson.
+ using namespace boost::math::tools;
+ T min = guess / 100; // We don't really know what this should be!
+ T max = guess * 100; // We don't really know what this should be!
+ const int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
+ int get_digits = static_cast<int>(digits * 0.6); // Accuracy doubles with each step, so stop when we have
+ // just over half the digits correct.
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ newton_raphson_iterate(cbrt_functor_deriv<T>(x), guess, min, max, get_digits, it);
+ return it;
+}
+
+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,
+ }
+ 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).
+ 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.
+ }
+private:
+ T a; // to be 'cube_rooted'.
+};
+
+template <class T>
+boost::uintmax_t cbrt_2deriv(T x, T guess)
+{
+ // 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;
+ T min = guess / 100; // We don't really know what this should be!
+ T max = guess * 100; // We don't really know what this should be!
+ 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 * 0.4); // Accuracy triples with each step, so stop when just
+ // over one third of the digits are correct.
+ boost::uintmax_t maxit = 20;
+ halley_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, maxit);
+ return maxit;
+}
+
+template <class T>
+boost::uintmax_t cbrt_2deriv_s(T x, T guess)
+{
+ // 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;
+ T min = guess / 100; // We don't really know what this should be!
+ T max = guess * 100; // We don't really know what this should be!
+ 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 * 0.4); // Accuracy triples with each step, so stop when just
+ // over one third of the digits are correct.
+ boost::uintmax_t maxit = 20;
+ schroder_iterate(cbrt_functor_2deriv<T>(x), guess, min, max, get_digits, maxit);
+ return maxit;
+}
+
+template <typename T = double>
+struct elliptic_root_functor_noderiv
+{
+ elliptic_root_functor_noderiv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius)
+ { // Constructor just stores value a to find root of.
+ }
+ T operator()(T const& x)
+ {
+ // return the difference between required arc-length, and the calculated arc-length for an
+ // ellipse with radii m_radius and x:
+ T a = (std::max)(m_radius, x);
+ T b = (std::min)(m_radius, x);
+ T k = sqrt(1 - b * b / (a * a));
+ return 4 * a * boost::math::ellint_2(k) - m_arc;
+ }
+private:
+ T m_arc; // length of arc.
+ T m_radius; // one of the two radii of the ellipse
+}; // template <class T> struct elliptic_root_functor_noderiv
+
+template <class T = double>
+boost::uintmax_t elliptic_root_noderiv(T radius, T arc, T guess)
+{ // return the other radius of an ellipse, given one radii and the arc-length
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For bracket_and_solve_root.
+
+ 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; // Initially our chosen max iterations, but updated with actual.
+ bool is_rising = true; // arc-length increases if one radii increases, so function is rising
+ // Define a termination condition, stop when nearly all digits are correct, but allow for
+ // the fact that we are returning a range, and must have some inaccuracy in the elliptic integral:
+ eps_tolerance<T> tol(std::numeric_limits<T>::digits - 2);
+ // Call bracket_and_solve_root to find the solution, note that this is a rising function:
+ bracket_and_solve_root(elliptic_root_functor_noderiv<T>(arc, radius), guess, factor, is_rising, tol, it);
+ return it;
+}
+
+template <class T = double>
+struct elliptic_root_functor_1deriv
+{ // Functor also returning 1st derivative.
+ BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
+
+ elliptic_root_functor_1deriv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius)
+ { // Constructor just stores value a to find root of.
+ }
+ std::pair<T, T> operator()(T const& x)
+ {
+ // Return the difference between required arc-length, and the calculated arc-length for an
+ // ellipse with radii m_radius and x, plus it's derivative.
+ // See http://www.wolframalpha.com/input/?i=d%2Fda+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]
+ // We require two elliptic integral calls, but from these we can calculate both
+ // the function and it's derivative:
+ T a = (std::max)(m_radius, x);
+ T b = (std::min)(m_radius, x);
+ T a2 = a * a;
+ T b2 = b * b;
+ T k = sqrt(1 - b2 / a2);
+ T Ek = boost::math::ellint_2(k);
+ T Kk = boost::math::ellint_1(k);
+ T fx = 4 * a * Ek - m_arc;
+ T dfx = 4 * (a2 * Ek - b2 * Kk) / (a2 - b2);
+ return std::make_pair(fx, dfx);
+ }
+private:
+ T m_arc; // length of arc.
+ T m_radius; // one of the two radii of the ellipse
+}; // struct elliptic_root__functor_1deriv
+
+template <class T = double>
+boost::uintmax_t elliptic_root_1deriv(T radius, T arc, T guess)
+{
+ 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!");
+
+ T min = 0; // Minimum possible value is zero.
+ T max = arc; // Maximum possible value is the arc length.
+
+ // Accuracy doubles at each step, so stop when just over half of the digits are
+ // correct, and rely on that step to polish off the remainder:
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.6);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ newton_raphson_iterate(elliptic_root_functor_1deriv<T>(arc, radius), guess, min, max, get_digits, it);
+ return it;
+}
+
+template <class T = double>
+struct elliptic_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!");
+
+ elliptic_root_functor_2deriv(T const& arc, T const& radius) : m_arc(arc), m_radius(radius) {}
+ std::tuple<T, T, T> operator()(T const& x)
+ {
+ // Return the difference between required arc-length, and the calculated arc-length for an
+ // ellipse with radii m_radius and x, plus it's derivative.
+ // See http://www.wolframalpha.com/input/?i=d^2%2Fda^2+[4+*+a+*+EllipticE%281+-+b^2%2Fa^2%29]
+ // for the second derivative.
+ T a = (std::max)(m_radius, x);
+ T b = (std::min)(m_radius, x);
+ T a2 = a * a;
+ T b2 = b * b;
+ T k = sqrt(1 - b2 / a2);
+ T Ek = boost::math::ellint_2(k);
+ T Kk = boost::math::ellint_1(k);
+ T fx = 4 * a * Ek - m_arc;
+ T dfx = 4 * (a2 * Ek - b2 * Kk) / (a2 - b2);
+ T dfx2 = 4 * b2 * ((a2 + b2) * Kk - 2 * a2 * Ek) / (a * (a2 - b2) * (a2 - b2));
+ return std::make_tuple(fx, dfx, dfx2);
+ }
+private:
+ T m_arc; // length of arc.
+ T m_radius; // one of the two radii of the ellipse
+};
+
+template <class T = double>
+boost::uintmax_t elliptic_root_2deriv(T radius, T arc, T guess)
+{
+ 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!");
+
+ T min = 0; // Minimum possible value is zero.
+ T max = arc; // radius can't be larger than the arc length.
+
+ // Accuracy triples at each step, so stop when just over one-third of the digits
+ // are correct, and the last iteration will polish off the remaining digits:
+ int get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ halley_iterate(elliptic_root_functor_2deriv<T>(arc, radius), guess, min, max, get_digits, it);
+ return it;
+} // nth_2deriv Halley
+//]
+// Using 1st and 2nd derivatives using Schroder algorithm.
+
+template <class T = double>
+boost::uintmax_t elliptic_root_2deriv_s(T radius, T arc, T guess)
+{ // return nth root of x using 1st and 2nd derivatives and Schroder.
+
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For schroder_iterate.
+
+ BOOST_STATIC_ASSERT_MSG(boost::is_integral<T>::value == false, "Only floating-point type types can be used!");
+
+ T min = 0; // Minimum possible value is zero.
+ T max = arc; // radius can't be larger than the arc length.
+
+ int digits = std::numeric_limits<T>::digits; // Maximum possible binary digits accuracy for type T.
+ int get_digits = static_cast<int>(digits * 0.4);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ schroder_iterate(elliptic_root_functor_2deriv<T>(arc, radius), guess, min, max, get_digits, it);
+ return it;
+} // T elliptic_root_2deriv_s Schroder
+
+
+int main()
+{
+ try
+ {
+ double to_root = 500;
+ double answer = 7.93700525984;
+
+ std::cout << "[table\n"
+ << "[[Initial Guess=][-500% ([approx]1.323)][-100% ([approx]3.97)][-50% ([approx]3.96)][-20% ([approx]6.35)][-10% ([approx]7.14)][-5% ([approx]7.54)]"
+ "[5% ([approx]8.33)][10% ([approx]8.73)][20% ([approx]9.52)][50% ([approx]11.91)][100% ([approx]15.87)][500 ([approx]47.6)]]\n";
+ std::cout << "[[bracket_and_solve_root]["
+ << cbrt_noderiv(to_root, answer / 6)
+ << "][" << cbrt_noderiv(to_root, answer / 2)
+ << "][" << cbrt_noderiv(to_root, answer - answer * 0.5)
+ << "][" << cbrt_noderiv(to_root, answer - answer * 0.2)
+ << "][" << cbrt_noderiv(to_root, answer - answer * 0.1)
+ << "][" << cbrt_noderiv(to_root, answer - answer * 0.05)
+ << "][" << cbrt_noderiv(to_root, answer + answer * 0.05)
+ << "][" << cbrt_noderiv(to_root, answer + answer * 0.1)
+ << "][" << cbrt_noderiv(to_root, answer + answer * 0.2)
+ << "][" << cbrt_noderiv(to_root, answer + answer * 0.5)
+ << "][" << cbrt_noderiv(to_root, answer + answer)
+ << "][" << cbrt_noderiv(to_root, answer + answer * 5) << "]]\n";
+
+ std::cout << "[[newton_iterate]["
+ << cbrt_deriv(to_root, answer / 6)
+ << "][" << cbrt_deriv(to_root, answer / 2)
+ << "][" << cbrt_deriv(to_root, answer - answer * 0.5)
+ << "][" << cbrt_deriv(to_root, answer - answer * 0.2)
+ << "][" << cbrt_deriv(to_root, answer - answer * 0.1)
+ << "][" << cbrt_deriv(to_root, answer - answer * 0.05)
+ << "][" << cbrt_deriv(to_root, answer + answer * 0.05)
+ << "][" << cbrt_deriv(to_root, answer + answer * 0.1)
+ << "][" << cbrt_deriv(to_root, answer + answer * 0.2)
+ << "][" << cbrt_deriv(to_root, answer + answer * 0.5)
+ << "][" << cbrt_deriv(to_root, answer + answer)
+ << "][" << cbrt_deriv(to_root, answer + answer * 5) << "]]\n";
+
+ std::cout << "[[halley_iterate]["
+ << cbrt_2deriv(to_root, answer / 6)
+ << "][" << cbrt_2deriv(to_root, answer / 2)
+ << "][" << cbrt_2deriv(to_root, answer - answer * 0.5)
+ << "][" << cbrt_2deriv(to_root, answer - answer * 0.2)
+ << "][" << cbrt_2deriv(to_root, answer - answer * 0.1)
+ << "][" << cbrt_2deriv(to_root, answer - answer * 0.05)
+ << "][" << cbrt_2deriv(to_root, answer + answer * 0.05)
+ << "][" << cbrt_2deriv(to_root, answer + answer * 0.1)
+ << "][" << cbrt_2deriv(to_root, answer + answer * 0.2)
+ << "][" << cbrt_2deriv(to_root, answer + answer * 0.5)
+ << "][" << cbrt_2deriv(to_root, answer + answer)
+ << "][" << cbrt_2deriv(to_root, answer + answer * 5) << "]]\n";
+
+ std::cout << "[[schr'''&#xf6;'''der_iterate]["
+ << cbrt_2deriv_s(to_root, answer / 6)
+ << "][" << cbrt_2deriv_s(to_root, answer / 2)
+ << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.5)
+ << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.2)
+ << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.1)
+ << "][" << cbrt_2deriv_s(to_root, answer - answer * 0.05)
+ << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.05)
+ << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.1)
+ << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.2)
+ << "][" << cbrt_2deriv_s(to_root, answer + answer * 0.5)
+ << "][" << cbrt_2deriv_s(to_root, answer + answer)
+ << "][" << cbrt_2deriv_s(to_root, answer + answer * 5) << "]]\n]\n\n";
+
+
+ double radius_a = 10;
+ double arc_length = 500;
+ double radius_b = 123.6216507967705;
+
+ std::cout << std::setprecision(4) << "[table\n"
+ << "[[Initial Guess=][-500% ([approx]" << radius_b / 6 << ")][-100% ([approx]" << radius_b / 2 << ")][-50% ([approx]"
+ << radius_b - radius_b * 0.5 << ")][-20% ([approx]" << radius_b - radius_b * 0.2 << ")][-10% ([approx]" << radius_b - radius_b * 0.1 << ")][-5% ([approx]" << radius_b - radius_b * 0.05 << ")]"
+ "[5% ([approx]" << radius_b + radius_b * 0.05 << ")][10% ([approx]" << radius_b + radius_b * 0.1 << ")][20% ([approx]" << radius_b + radius_b * 0.2 << ")][50% ([approx]" << radius_b + radius_b * 0.5
+ << ")][100% ([approx]" << radius_b + radius_b << ")][500 ([approx]" << radius_b + radius_b * 5 << ")]]\n";
+ std::cout << "[[bracket_and_solve_root]["
+ << elliptic_root_noderiv(radius_a, arc_length, radius_b / 6)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b / 2)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.5)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.2)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.1)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b - radius_b * 0.05)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.05)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.1)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.2)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 0.5)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b)
+ << "][" << elliptic_root_noderiv(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n";
+
+ std::cout << "[[newton_iterate]["
+ << elliptic_root_1deriv(radius_a, arc_length, radius_b / 6)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b / 2)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.5)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.2)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.1)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b - radius_b * 0.05)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.05)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.1)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.2)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 0.5)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b)
+ << "][" << elliptic_root_1deriv(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n";
+
+ std::cout << "[[halley_iterate]["
+ << elliptic_root_2deriv(radius_a, arc_length, radius_b / 6)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b / 2)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.5)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.2)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.1)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b - radius_b * 0.05)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.05)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.1)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.2)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 0.5)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b)
+ << "][" << elliptic_root_2deriv(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n";
+
+ std::cout << "[[schr'''&#xf6;'''der_iterate]["
+ << elliptic_root_2deriv_s(radius_a, arc_length, radius_b / 6)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b / 2)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.5)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.2)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.1)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b - radius_b * 0.05)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.05)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.1)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.2)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 0.5)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b)
+ << "][" << elliptic_root_2deriv_s(radius_a, arc_length, radius_b + radius_b * 5) << "]]\n]\n\n";
+
+ return boost::exit_success;
+ }
+ catch(std::exception ex)
+ {
+ std::cout << "exception thrown: " << ex.what() << std::endl;
+ return boost::exit_failure;
+ }
+} // int main()
+
diff --git a/src/boost/libs/math/example/root_n_finding_algorithms.cpp b/src/boost/libs/math/example/root_n_finding_algorithms.cpp
new file mode 100644
index 000000000..70f017923
--- /dev/null
+++ b/src/boost/libs/math/example/root_n_finding_algorithms.cpp
@@ -0,0 +1,870 @@
+// 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 & Schroder 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/concepts/real_concept.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::schroder_iterate;
+
+#include <boost/math/special_functions/next.hpp> // For float_distance.
+#include <boost/math/special_functions/pow.hpp> // For pow<N>.
+#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/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
+
+ std::string chop_last(std::string s)
+ {
+ std::string::size_type pos = s.find_last_of("\\/");
+ if(pos != std::string::npos)
+ s.erase(pos);
+ else if(s.empty())
+ abort();
+ else
+ s.erase();
+ return s;
+ }
+
+ std::string make_root()
+ {
+ std::string result;
+ if(sourcefilename.find_first_of(":") != std::string::npos)
+ {
+ result = chop_last(sourcefilename); // lose filename part
+ result = chop_last(result); // lose /example/
+ result = chop_last(result); // lose /math/
+ result = chop_last(result); // lose /libs/
+ }
+ else
+ {
+ result = chop_last(sourcefilename); // lose filename part
+ if(result.empty())
+ result = ".";
+ result += "/../../..";
+ }
+ return result;
+ }
+
+ std::string short_file_name(std::string s)
+ {
+ std::string::size_type pos = s.find_last_of("\\/");
+ if(pos != std::string::npos)
+ s.erase(0, pos + 1);
+ return s;
+ }
+
+ std::string boost_root = make_root();
+
+
+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;
+
+double digits_accuracy = 1.0; // 1 == maximum possible accuracy.
+
+std::stringstream ss;
+
+std::ofstream fout;
+
+std::vector<std::string> algo_names =
+{
+ "TOMS748", "Newton", "Halley", "Schr'''&#xf6;'''der"
+};
+
+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 & Schroder.
+ //std::vector< boost::int_least64_t> times; converted to int.
+ std::vector<int> times; // arbitrary 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;
+#if defined(_DEBUG) || !defined(NDEBUG)
+ result += "|";
+ result += " debug";
+#else
+ result += "|";
+ result += " release";
+#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; // Initially 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.
+ // Some fraction of digits is used to control how accurate to try to make the result.
+ int get_digits = std::numeric_limits<T>::digits - 2;
+ 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 derivative.
+ 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 p = pow<N - 1>(x);
+ return std::make_pair(p * x - a, N * p); // '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 * 0.6);
+ 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 p = pow<N - 2>(x);
+
+ return std::make_tuple(p * x * x - a, p * x * N, p * N * (N - 1)); // '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 * 0.4);
+ 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
+
+template <int N, class T = double>
+T nth_root_2deriv_s(T x)
+{ // return nth root of x using 1st and 2nd derivatives and Schroder.
+
+ using namespace std; // Help ADL of std functions.
+ using namespace boost::math::tools; // For schroder_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 get_digits = static_cast<int>(std::numeric_limits<T>::digits * 0.4);
+ const boost::uintmax_t maxit = 20;
+ boost::uintmax_t it = maxit;
+ T result = schroder_iterate(nth_root_functor_2deriv<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 sum = 0;
+ T ans = static_cast<T>(answer);
+
+ using boost::timer::nanosecond_type;
+ using boost::timer::cpu_times;
+ using boost::timer::cpu_timer;
+
+ int eval_count = boost::is_floating_point<T>::value ? 10000000 : 100000; // 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); //
+ sum += result;
+ }
+ 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); //
+ sum += result;
+ }
+ 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); //
+ sum += result;
+ }
+ 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("Schroder"); // 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); //
+ sum += result;
+ }
+ 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);
+ }
+
+ std::cout << "Accumulated result was: " << sum << std::endl;
+
+ return 4; // eval_count of how many algorithms used.
+} // test_root
+
+/*! Fill array of times, iterations, 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)
+{
+ using std::abs;
+ std::cout << nooftypes << " floating-point types tested:" << std::endl;
+#if defined(_DEBUG) || !defined(NDEBUG)
+ std::cout << "Compiled in debug mode." << std::endl;
+#else
+ std::cout << "Compiled in optimise mode." << std::endl;
+#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);
+
+ root_infos.clear(); // Erase any previous data.
+ // Fill the elements of the array for each floating-point type.
+
+ test_root<N, float>(full_value, full_answer, "float", 0);
+ test_root<N, double>(full_value, full_answer, "double", 1);
+ test_root<N, long double>(full_value, full_answer, "long double", 2);
+ 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 :-(
+
+#if defined(_DEBUG) || !defined(NDEBUG)
+ std::string debug_or_optimize("Compiled in debug mode.");
+#else
+ std::string debug_or_optimize("Compiled in optimise mode.");
+#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))
+#ifndef _M_X64
+# define _M_X64
+#endif
+#ifndef __SSE2__
+# define __SSE2__
+#endif
+#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 const& ex)
+ {
+ std::cout << "exception thrown: " << ex.what() << std::endl;
+ return boost::exit_failure;
+ }
+} // int main()
+
+/*
+
+*/
diff --git a/src/boost/libs/math/example/series.cpp b/src/boost/libs/math/example/series.cpp
new file mode 100644
index 000000000..8bfce824f
--- /dev/null
+++ b/src/boost/libs/math/example/series.cpp
@@ -0,0 +1,107 @@
+// (C) Copyright John Maddock 2018.
+// 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)
+
+#include <boost/math/tools/series.hpp>
+#include <boost/assert.hpp>
+
+#include <iostream>
+#include <complex>
+#include <cassert>
+
+//[series_log1p
+template <class T>
+struct log1p_series
+{
+ // we must define a result_type typedef:
+ typedef T result_type;
+
+ log1p_series(T x)
+ : k(0), m_mult(-x), m_prod(-1) {}
+
+ T operator()()
+ {
+ // This is the function operator invoked by the summation
+ // algorithm, the first call to this operator should return
+ // the first term of the series, the second call the second
+ // term and so on.
+ m_prod *= m_mult;
+ return m_prod / ++k;
+ }
+
+private:
+ int k;
+ const T m_mult;
+ T m_prod;
+};
+//]
+
+//[series_log1p_func
+template <class T>
+T log1p(T x)
+{
+ // We really should add some error checking on x here!
+ BOOST_ASSERT(std::fabs(x) < 1);
+
+ // Construct the series functor:
+ log1p_series<T> s(x);
+ // Set a limit on how many iterations we permit:
+ boost::uintmax_t max_iter = 1000;
+ // Add it up, with enough precision for full machine precision:
+ return boost::math::tools::sum_series(s, std::numeric_limits<T>::epsilon(), max_iter);
+}
+//]
+
+//[series_clog1p_func
+template <class T>
+struct log1p_series<std::complex<T> >
+{
+ // we must define a result_type typedef:
+ typedef std::complex<T> result_type;
+
+ log1p_series(std::complex<T> x)
+ : k(0), m_mult(-x), m_prod(-1) {}
+
+ std::complex<T> operator()()
+ {
+ // This is the function operator invoked by the summation
+ // algorithm, the first call to this operator should return
+ // the first term of the series, the second call the second
+ // term and so on.
+ m_prod *= m_mult;
+ return m_prod / T(++k);
+ }
+
+private:
+ int k;
+ const std::complex<T> m_mult;
+ std::complex<T> m_prod;
+};
+
+
+template <class T>
+std::complex<T> log1p(std::complex<T> x)
+{
+ // We really should add some error checking on x here!
+ BOOST_ASSERT(abs(x) < 1);
+
+ // Construct the series functor:
+ log1p_series<std::complex<T> > s(x);
+ // Set a limit on how many iterations we permit:
+ boost::uintmax_t max_iter = 1000;
+ // Add it up, with enough precision for full machine precision:
+ return boost::math::tools::sum_series(s, std::complex<T>(std::numeric_limits<T>::epsilon()), max_iter);
+}
+//]
+
+int main()
+{
+ using namespace boost::math::tools;
+
+ std::cout << log1p(0.25) << std::endl;
+
+ std::cout << log1p(std::complex<double>(0.25, 0.25)) << std::endl;
+
+ return 0;
+}
diff --git a/src/boost/libs/math/example/sines.hpp b/src/boost/libs/math/example/sines.hpp
new file mode 100644
index 000000000..d4cbbbbf3
--- /dev/null
+++ b/src/boost/libs/math/example/sines.hpp
@@ -0,0 +1,47 @@
+// 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)
+
+// Copyright A N Other, 2019.
+
+// Table of 32 values with 50 decimal digits precision,
+// generated by program fft_sines_table.cpp.
+
+#include <array> // std::array
+
+static const std::array<double, 32> sines =
+{{
+ 1,
+ 0.70710678118654752440084436210484903928483593768847,
+ 0.38268343236508977172845998403039886676134456248563,
+ 0.19509032201612826784828486847702224092769161775195,
+ 0.098017140329560601994195563888641845861136673167501,
+ 0.049067674327418014254954976942682658314745363025753,
+ 0.024541228522912288031734529459282925065466119239452,
+ 0.012271538285719926079408261951003212140372319591769,
+ 0.0061358846491544753596402345903725809170578863173913,
+ 0.003067956762965976270145365490919842518944610213452,
+ 0.0015339801862847656123036971502640790799548645752374,
+ 0.00076699031874270452693856835794857664314091945206328,
+ 0.00038349518757139558907246168118138126339502603496474,
+ 0.00019174759731070330743990956198900093346887403385916,
+ 9.5873799095977345870517210976476351187065612851145e-05,
+ 4.7936899603066884549003990494658872746866687685767e-05,
+ 2.3968449808418218729186577165021820094761474895673e-05,
+ 1.1984224905069706421521561596988984804731977538387e-05,
+ 5.9921124526424278428797118088908617299871778780951e-06,
+ 2.9960562263346607504548128083570598118251878683408e-06,
+ 1.4980281131690112288542788461553611206917585861527e-06,
+ 7.4901405658471572113049856673065563715595930217207e-07,
+ 3.7450702829238412390316917908463317739740476297248e-07,
+ 1.8725351414619534486882457659356361712045272098286e-07,
+ 9.3626757073098082799067286680885620193236507169473e-08,
+ 4.681337853654909269511551813854009695950362701667e-08,
+ 2.3406689268274552759505493419034844037886207223779e-08,
+ 1.1703344634137277181246213503238103798093456639976e-08,
+ 5.8516723170686386908097901008341396943900085051756e-09,
+ 2.9258361585343193579282304690689559020175857150074e-09,
+ 1.4629180792671596805295321618659637103742615227834e-09,
+ 7.3145903963357984046044319684941757518633453150407e-10
+}}; // array sines
diff --git a/src/boost/libs/math/example/skew_normal_example.cpp b/src/boost/libs/math/example/skew_normal_example.cpp
new file mode 100644
index 000000000..5858aff35
--- /dev/null
+++ b/src/boost/libs/math/example/skew_normal_example.cpp
@@ -0,0 +1,275 @@
+// Copyright Benjamin Sobotta 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)
+
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512) // assignment operator could not be generated
+# pragma warning (disable : 4127) // conditional expression is constant.
+#endif
+
+#include <boost/math/distributions/skew_normal.hpp>
+using boost::math::skew_normal_distribution;
+using boost::math::skew_normal;
+#include <iostream>
+#include <cmath>
+#include <utility>
+
+void check(const double loc, const double sc, const double sh,
+ const double * const cumulants, const std::pair<double, double> qu,
+ const double x, const double tpdf, const double tcdf)
+{
+ using namespace boost::math;
+
+ skew_normal D(loc, sc, sh);
+
+ const double sk = cumulants[2] / (std::pow(cumulants[1], 1.5));
+ const double kt = cumulants[3] / (cumulants[1] * cumulants[1]);
+
+ // checks against tabulated values
+ std::cout << "mean: table=" << cumulants[0] << "\tcompute=" << mean(D) << "\tdiff=" << fabs(cumulants[0]-mean(D)) << std::endl;
+ std::cout << "var: table=" << cumulants[1] << "\tcompute=" << variance(D) << "\tdiff=" << fabs(cumulants[1]-variance(D)) << std::endl;
+ std::cout << "skew: table=" << sk << "\tcompute=" << skewness(D) << "\tdiff=" << fabs(sk-skewness(D)) << std::endl;
+ std::cout << "kur.: table=" << kt << "\tcompute=" << kurtosis_excess(D) << "\tdiff=" << fabs(kt-kurtosis_excess(D)) << std::endl;
+ std::cout << "mode: table=" << "N/A" << "\tcompute=" << mode(D) << "\tdiff=" << "N/A" << std::endl;
+
+ const double q = quantile(D, qu.first);
+ const double cq = quantile(complement(D, qu.first));
+
+ std::cout << "quantile(" << qu.first << "): table=" << qu.second << "\tcompute=" << q << "\tdiff=" << fabs(qu.second-q) << std::endl;
+
+ // consistency
+ std::cout << "cdf(quantile)=" << cdf(D, q) << "\tp=" << qu.first << "\tdiff=" << fabs(qu.first-cdf(D, q)) << std::endl;
+ std::cout << "ccdf(cquantile)=" << cdf(complement(D,cq)) << "\tp=" << qu.first << "\tdiff=" << fabs(qu.first-cdf(complement(D,cq))) << std::endl;
+
+ // PDF & CDF
+ std::cout << "pdf(" << x << "): table=" << tpdf << "\tcompute=" << pdf(D,x) << "\tdiff=" << fabs(tpdf-pdf(D,x)) << std::endl;
+ std::cout << "cdf(" << x << "): table=" << tcdf << "\tcompute=" << cdf(D,x) << "\tdiff=" << fabs(tcdf-cdf(D,x)) << std::endl;
+ std::cout << "================================\n";
+}
+
+int main()
+{
+ using namespace boost::math;
+
+ double sc = 0.0,loc,sh,x,dsn,qsn,psn,p;
+ std::cout << std::setprecision(20);
+
+ double cumulants[4];
+
+
+ /* R:
+ > install.packages("sn")
+ Warning in install.packages("sn") :
+ 'lib = "/usr/lib64/R/library"' is not writable
+ Would you like to create a personal library
+ '~/R/x86_64-unknown-linux-gnu-library/2.12'
+ to install packages into? (y/n) y
+ --- Please select a CRAN mirror for use in this session ---
+ Loading Tcl/Tk interface ... done
+ also installing the dependency mnormt
+
+ trying URL 'http://mirrors.dotsrc.org/cran/src/contrib/mnormt_1.4-5.tar.gz'
+ Content type 'application/x-gzip' length 34049 bytes (33 Kb)
+ opened URL
+ ==================================================
+ downloaded 33 Kb
+
+ trying URL 'http://mirrors.dotsrc.org/cran/src/contrib/sn_0.4-17.tar.gz'
+ Content type 'application/x-gzip' length 65451 bytes (63 Kb)
+ opened URL
+ ==================================================
+ downloaded 63 Kb
+
+
+ > library(sn)
+ > options(digits=22)
+
+
+ > sn.cumulants(1.1, 2.2, -3.3)
+ [1] -0.5799089925398568 2.0179057767837230 -2.0347951542374196
+ [4] 2.2553488991015072
+ > qsn(0.3, 1.1, 2.2, -3.3)
+ [1] -1.180104068086876
+ > psn(0.4, 1.1, 2.2, -3.3)
+ [1] 0.733918618927874
+ > dsn(0.4, 1.1, 2.2, -3.3)
+ [1] 0.2941401101565995
+
+ */
+
+ //1 st
+ loc = 1.1; sc = 2.2; sh = -3.3;
+ std::cout << "location: " << loc << "\tscale: " << sc << "\tshape: " << sh << std::endl;
+ cumulants[0] = -0.5799089925398568;
+ cumulants[1] = 2.0179057767837230;
+ cumulants[2] = -2.0347951542374196;
+ cumulants[3] = 2.2553488991015072;
+ x = 0.4;
+ p = 0.3;
+ qsn = -1.180104068086876;
+ psn = 0.733918618927874;
+ dsn = 0.2941401101565995;
+
+ check(loc, sc, sh, cumulants, std::make_pair(p,qsn), x, dsn, psn);
+
+ /* R:
+
+ > sn.cumulants(1.1, .02, .03)
+ [1] 1.1004785154529559e+00 3.9977102296128255e-04 4.7027439329779991e-11
+ [4] 1.4847542790693825e-14
+ > qsn(0.01, 1.1, .02, .03)
+ [1] 1.053964962950150
+ > psn(1.3, 1.1, .02, .03)
+ [1] 1
+ > dsn(1.3, 1.1, .02, .03)
+ [1] 4.754580380601393e-21
+
+ */
+
+ // 2nd
+ loc = 1.1; sc = .02; sh = .03;
+ std::cout << "location: " << loc << "\tscale: " << sc << "\tshape: " << sh << std::endl;
+ cumulants[0] = 1.1004785154529559e+00;
+ cumulants[1] = 3.9977102296128255e-04;
+ cumulants[2] = 4.7027439329779991e-11;
+ cumulants[3] = 1.4847542790693825e-14;
+ x = 1.3;
+ p = 0.01;
+ qsn = 1.053964962950150;
+ psn = 1;
+ dsn = 4.754580380601393e-21;
+
+ check(loc, sc, sh, cumulants, std::make_pair(p,qsn), x, dsn, psn);
+
+ /* R:
+
+ > sn.cumulants(10.1, 5, -.03)
+ [1] 9.980371136761052e+00 2.498568893508016e+01 -7.348037395278123e-04
+ [4] 5.799821402614775e-05
+ > qsn(.8, 10.1, 5, -.03)
+ [1] 14.18727407491953
+ > psn(-1.3, 10.1, 5, -.03)
+ [1] 0.01201290665838824
+ > dsn(-1.3, 10.1, 5, -.03)
+ [1] 0.006254346348897927
+
+
+ */
+
+ // 3rd
+ loc = 10.1; sc = 5; sh = -.03;
+ std::cout << "location: " << loc << "\tscale: " << sc << "\tshape: " << sh << std::endl;
+ cumulants[0] = 9.980371136761052e+00;
+ cumulants[1] = 2.498568893508016e+01;
+ cumulants[2] = -7.348037395278123e-04;
+ cumulants[3] = 5.799821402614775e-05;
+ x = -1.3;
+ p = 0.8;
+ qsn = 14.18727407491953;
+ psn = 0.01201290665838824;
+ dsn = 0.006254346348897927;
+
+ check(loc, sc, sh, cumulants, std::make_pair(p,qsn), x, dsn, psn);
+
+
+ /* R:
+
+ > sn.cumulants(-10.1, 5, 30)
+ [1] -6.112791696741384 9.102169946425548 27.206345266148194 71.572537838642916
+ > qsn(.8, -10.1, 5, 30)
+ [1] -3.692242172277
+ > psn(-1.3, -10.1, 5, 30)
+ [1] 0.921592193425035
+ > dsn(-1.3, -10.1, 5, 30)
+ [1] 0.0339105445232089
+
+ */
+
+ // 4th
+ loc = -10.1; sc = 5; sh = 30;
+ std::cout << "location: " << loc << "\tscale: " << sc << "\tshape: " << sh << std::endl;
+ cumulants[0] = -6.112791696741384;
+ cumulants[1] = 9.102169946425548;
+ cumulants[2] = 27.206345266148194;
+ cumulants[3] = 71.572537838642916;
+ x = -1.3;
+ p = 0.8;
+ qsn = -3.692242172277;
+ psn = 0.921592193425035;
+ dsn = 0.0339105445232089;
+
+ check(loc, sc, sh, cumulants, std::make_pair(p,qsn), x, dsn, psn);
+
+
+ /* R:
+
+ > sn.cumulants(0,1,5)
+ [1] 0.7823901817554269 0.3878656034927102 0.2055576317962637 0.1061119471655128
+ > qsn(0.5,0,1,5)
+ [1] 0.674471117502844
+ > psn(-0.5, 0,1,5)
+ [1] 0.0002731513884140924
+ > dsn(-0.5, 0,1,5)
+ [1] 0.00437241570403263
+
+ */
+
+ // 5th
+ loc = 0; sc = 1; sh = 5;
+ std::cout << "location: " << loc << "\tscale: " << sc << "\tshape: " << sh << std::endl;
+ cumulants[0] = 0.7823901817554269;
+ cumulants[1] = 0.3878656034927102;
+ cumulants[2] = 0.2055576317962637;
+ cumulants[3] = 0.1061119471655128;
+ x = -0.5;
+ p = 0.5;
+ qsn = 0.674471117502844;
+ psn = 0.0002731513884140924;
+ dsn = 0.00437241570403263;
+
+ check(loc, sc, sh, cumulants, std::make_pair(p,qsn), x, dsn, psn);
+
+ /* R:
+
+ > sn.cumulants(0,1,1e5)
+ [1] 0.7978845607629713 0.3633802276960805 0.2180136141122883 0.1147706820312645
+ > qsn(0.5,0,1,1e5)
+ [1] 0.6744897501960818
+ > psn(-0.5, 0,1,1e5)
+ [1] 0
+ > dsn(-0.5, 0,1,1e5)
+ [1] 0
+
+ */
+
+ // 6th
+ loc = 0; sc = 1; sh = 1e5;
+ std::cout << "location: " << loc << "\tscale: " << sc << "\tshape: " << sh << std::endl;
+ cumulants[0] = 0.7978845607629713;
+ cumulants[1] = 0.3633802276960805;
+ cumulants[2] = 0.2180136141122883;
+ cumulants[3] = 0.1147706820312645;
+ x = -0.5;
+ p = 0.5;
+ qsn = 0.6744897501960818;
+ psn = 0.;
+ dsn = 0.;
+
+ check(loc, sc, sh, cumulants, std::make_pair(p,qsn), x, dsn, psn);
+
+ return 0;
+}
+
+
+// EOF
+
+
+
+
+
+
+
+
diff --git a/src/boost/libs/math/example/special_data.cpp b/src/boost/libs/math/example/special_data.cpp
new file mode 100644
index 000000000..2e101b409
--- /dev/null
+++ b/src/boost/libs/math/example/special_data.cpp
@@ -0,0 +1,84 @@
+// Copyright John Maddock 2006.
+// 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)
+
+//[special_data_example
+
+#include <boost/multiprecision/cpp_dec_float.hpp>
+#include <boost/math/tools/test_data.hpp>
+#include <boost/test/included/prg_exec_monitor.hpp>
+#include <fstream>
+
+using namespace boost::math::tools;
+using namespace boost::math;
+using namespace std;
+using namespace boost::multiprecision;
+
+template <class T>
+T my_special(T a, T b)
+{
+ // Implementation of my_special here...
+ return a + b;
+}
+
+int cpp_main(int argc, char*argv [])
+{
+ //
+ // We'll use so many digits of precision that any
+ // calculation errors will still leave us with
+ // 40-50 good digits. We'll only run this program
+ // once so it doesn't matter too much how long this takes!
+ //
+ typedef number<cpp_dec_float<500> > bignum;
+
+ parameter_info<bignum> arg1, arg2;
+ test_data<bignum> data;
+
+ bool cont;
+ std::string line;
+
+ if(argc < 1)
+ return 1;
+
+ do{
+ //
+ // User interface which prompts for
+ // range of input parameters:
+ //
+ if(0 == get_user_parameter_info(arg1, "a"))
+ return 1;
+ if(0 == get_user_parameter_info(arg2, "b"))
+ return 1;
+
+ //
+ // Get a pointer to the function and call
+ // test_data::insert to actually generate
+ // the values.
+ //
+ bignum (*fp)(bignum, bignum) = &my_special;
+ data.insert(fp, arg2, arg1);
+
+ std::cout << "Any more data [y/n]?";
+ std::getline(std::cin, line);
+ boost::algorithm::trim(line);
+ cont = (line == "y");
+ }while(cont);
+ //
+ // Just need to write the results to a file:
+ //
+ std::cout << "Enter name of test data file [default=my_special.ipp]";
+ std::getline(std::cin, line);
+ boost::algorithm::trim(line);
+ if(line == "")
+ line = "my_special.ipp";
+ std::ofstream ofs(line.c_str());
+ line.erase(line.find('.'));
+ ofs << std::scientific << std::setprecision(50);
+ write_code(ofs, data, line.c_str());
+
+ return 0;
+}
+
+//]
diff --git a/src/boost/libs/math/example/students_t_example1.cpp b/src/boost/libs/math/example/students_t_example1.cpp
new file mode 100644
index 000000000..c86b89d5d
--- /dev/null
+++ b/src/boost/libs/math/example/students_t_example1.cpp
@@ -0,0 +1,101 @@
+// students_t_example1.cpp
+
+// Copyright Paul A. Bristow 2006, 2007.
+
+// 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)
+
+// Example 1 of using Student's t
+
+// http://en.wikipedia.org/wiki/Student's_t-test says:
+// The t statistic was invented by William Sealy Gosset
+// for cheaply monitoring the quality of beer brews.
+// "Student" was his pen name.
+// WS Gosset was statistician for Guinness brewery in Dublin, Ireland,
+// hired due to Claude Guinness's innovative policy of recruiting the
+// best graduates from Oxford and Cambridge for applying biochemistry
+// and statistics to Guinness's industrial processes.
+// Gosset published the t test in Biometrika in 1908,
+// but was forced to use a pen name by his employer who regarded the fact
+// that they were using statistics as a trade secret.
+// In fact, Gosset's identity was unknown not only to fellow statisticians
+// but to his employer - the company insisted on the pseudonym
+// so that it could turn a blind eye to the breach of its rules.
+
+// Data for this example from:
+// P.K.Hou, O. W. Lau & M.C. Wong, Analyst (1983) vol. 108, p 64.
+// from Statistics for Analytical Chemistry, 3rd ed. (1994), pp 54-55
+// J. C. Miller and J. N. Miller, Ellis Horwood ISBN 0 13 0309907
+
+// Determination of mercury by cold-vapour atomic absorption,
+// the following values were obtained fusing a trusted
+// Standard Reference Material containing 38.9% mercury,
+// which we assume is correct or 'true'.
+double standard = 38.9;
+
+const int values = 3;
+double value[values] = {38.9, 37.4, 37.1};
+
+// Is there any evidence for systematic error?
+
+// The Students't distribution function is described at
+// http://en.wikipedia.org/wiki/Student%27s_t_distribution
+#include <boost/math/distributions/students_t.hpp>
+ using boost::math::students_t; // Probability of students_t(df, t).
+
+#include <iostream>
+ using std::cout; using std::endl;
+#include <iomanip>
+ using std::setprecision;
+#include <cmath>
+ using std::sqrt;
+
+int main()
+{
+ cout << "Example 1 using Student's t function. " << endl;
+
+ // Example/test using tabulated value
+ // (deliberately coded as naively as possible).
+
+ // Null hypothesis is that there is no difference (greater or less)
+ // between measured and standard.
+
+ double degrees_of_freedom = values-1; // 3-1 = 2
+ cout << "Measurement 1 = " << value[0] << ", measurement 2 = " << value[1] << ", measurement 3 = " << value[2] << endl;
+ double mean = (value[0] + value[1] + value[2]) / static_cast<double>(values);
+ cout << "Standard = " << standard << ", mean = " << mean << ", (mean - standard) = " << mean - standard << endl;
+ double sd = sqrt(((value[0] - mean) * (value[0] - mean) + (value[1] - mean) * (value[1] - mean) + (value[2] - mean) * (value[2] - mean))/ static_cast<double>(values-1));
+ cout << "Standard deviation = " << sd << endl;
+ if (sd == 0.)
+ {
+ cout << "Measured mean is identical to SRM value," << endl;
+ cout << "so probability of no difference between measured and standard (the 'null hypothesis') is unity." << endl;
+ return 0;
+ }
+
+ double t = (mean - standard) * std::sqrt(static_cast<double>(values)) / sd;
+ cout << "Student's t = " << t << endl;
+ cout.precision(2); // Useful accuracy is only a few decimal digits.
+ cout << "Probability of Student's t is " << cdf(students_t(degrees_of_freedom), std::abs(t)) << endl;
+ // 0.91, is 1 tailed.
+ // So there is insufficient evidence of a difference to meet a 95% (1 in 20) criterion.
+
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+Example 1 using Student's t function.
+Measurement 1 = 38.9, measurement 2 = 37.4, measurement 3 = 37.1
+Standard = 38.9, mean = 37.8, (mean - standard) = -1.1
+Standard deviation = 0.964365
+Student's t = -1.97566
+Probability of Student's t is 0.91
+
+*/
+
+
diff --git a/src/boost/libs/math/example/students_t_example2.cpp b/src/boost/libs/math/example/students_t_example2.cpp
new file mode 100644
index 000000000..bbd423162
--- /dev/null
+++ b/src/boost/libs/math/example/students_t_example2.cpp
@@ -0,0 +1,126 @@
+// students_t_example2.cpp
+
+// Copyright Paul A. Bristow 2006.
+// 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)
+
+// Example 2 of using Student's t
+
+// A general guide to Student's t is at
+// http://en.wikipedia.org/wiki/Student's_t-test
+// (and many other elementary and advanced statistics texts).
+// It says:
+// The t statistic was invented by William Sealy Gosset
+// for cheaply monitoring the quality of beer brews.
+// "Student" was his pen name.
+// Gosset was statistician for Guinness brewery in Dublin, Ireland,
+// hired due to Claude Guinness's innovative policy of recruiting the
+// best graduates from Oxford and Cambridge for applying biochemistry
+// and statistics to Guinness's industrial processes.
+// Gosset published the t test in Biometrika in 1908,
+// but was forced to use a pen name by his employer who regarded the fact
+// that they were using statistics as a trade secret.
+// In fact, Gosset's identity was unknown not only to fellow statisticians
+// but to his employer - the company insisted on the pseudonym
+// so that it could turn a blind eye to the breach of its rules.
+
+// The Students't distribution function is described at
+// http://en.wikipedia.org/wiki/Student%27s_t_distribution
+
+#include <boost/math/distributions/students_t.hpp>
+ using boost::math::students_t; // Probability of students_t(df, t).
+
+#include <iostream>
+ using std::cout;
+ using std::endl;
+#include <iomanip>
+ using std::setprecision;
+ using std::setw;
+#include <cmath>
+ using std::sqrt;
+
+// This example of a one-sided test is from:
+//
+// from Statistics for Analytical Chemistry, 3rd ed. (1994), pp 59-60
+// J. C. Miller and J. N. Miller, Ellis Horwood ISBN 0 13 0309907.
+
+// An acid-base titrimetric method has a significant indicator error and
+// thus tends to give results with a positive systematic error (+bias).
+// To test this an exactly 0.1 M solution of acid is used to titrate
+// 25.00 ml of exactly 0.1 M solution of alkali,
+// with the following results (ml):
+
+double reference = 25.00; // 'True' result.
+const int values = 6; // titrations.
+double data [values] = {25.06, 25.18, 24.87, 25.51, 25.34, 25.41};
+
+int main()
+{
+ cout << "Example2 using Student's t function. ";
+#if defined(__FILE__) && defined(__TIMESTAMP__) && defined(_MSC_FULL_VER)
+ cout << " " << __FILE__ << ' ' << __TIMESTAMP__ << ' '<< _MSC_FULL_VER;
+#endif
+ cout << endl;
+
+ double sum = 0.;
+ for (int value = 0; value < values; value++)
+ { // Echo data and calculate mean.
+ sum += data[value];
+ cout << setw(4) << value << ' ' << setw(14) << data[value] << endl;
+ }
+ double mean = sum /static_cast<double>(values);
+ cout << "Mean = " << mean << endl; // 25.2283
+
+ double sd = 0.;
+ for (int value = 0; value < values; value++)
+ { // Calculate standard deviation.
+ sd +=(data[value] - mean) * (data[value] - mean);
+ }
+ int degrees_of_freedom = values - 1; // Use the n-1 formula.
+ sd /= degrees_of_freedom; // == variance.
+ sd= sqrt(sd);
+ cout << "Standard deviation = " << sd<< endl; // = 0.238279
+
+ double t = (mean - reference) * sqrt(static_cast<double>(values))/ sd; //
+ cout << "Student's t = " << t << ", with " << degrees_of_freedom << " degrees of freedom." << endl; // = 2.34725
+
+ cout << "Probability of positive bias is " << cdf(students_t(degrees_of_freedom), t) << "."<< endl; // = 0.967108.
+ // A 1-sided test because only testing for a positive bias.
+ // If > 0.95 then greater than 1 in 20 conventional (arbitrary) requirement.
+
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+------ Build started: Project: students_t_example2, Configuration: Debug Win32 ------
+Compiling...
+students_t_example2.cpp
+Linking...
+Autorun "i:\boost-06-05-03-1300\libs\math\test\Math_test\debug\students_t_example2.exe"
+Example2 using Student's t function. ..\..\..\..\..\..\boost-sandbox\libs\math_functions\example\students_t_example2.cpp Sat Aug 12 16:55:59 2006 140050727
+ 0 25.06
+ 1 25.18
+ 2 24.87
+ 3 25.51
+ 4 25.34
+ 5 25.41
+Mean = 25.2283
+Standard deviation = 0.238279
+Student's t = 2.34725, with 5 degrees of freedom.
+Probability of positive bias is 0.967108.
+Build Time 0:03
+Build log was saved at "file://i:\boost-06-05-03-1300\libs\math\test\Math_test\students_t_example2\Debug\BuildLog.htm"
+students_t_example2 - 0 error(s), 0 warning(s)
+========== Build: 1 succeeded, 0 failed, 0 up-to-date, 0 skipped ==========
+
+*/
+
+
+
+
+
diff --git a/src/boost/libs/math/example/students_t_example3.cpp b/src/boost/libs/math/example/students_t_example3.cpp
new file mode 100644
index 000000000..289daec09
--- /dev/null
+++ b/src/boost/libs/math/example/students_t_example3.cpp
@@ -0,0 +1,120 @@
+// students_t_example3.cpp
+// Copyright Paul A. Bristow 2006, 2007.
+
+// 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)
+
+// Example 3 of using Student's t.
+
+// A general guide to Student's t is at
+// http://en.wikipedia.org/wiki/Student's_t-test
+// (and many other elementary and advanced statistics texts).
+// It says:
+// The t statistic was invented by William Sealy Gosset
+// for cheaply monitoring the quality of beer brews.
+// "Student" was his pen name.
+// Gosset was statistician for Guinness brewery in Dublin, Ireland,
+// hired due to Claude Guinness's innovative policy of recruiting the
+// best graduates from Oxford and Cambridge for applying biochemistry
+// and statistics to Guinness's industrial processes.
+// Gosset published the t test in Biometrika in 1908,
+// but was forced to use a pen name by his employer who regarded the fact
+// that they were using statistics as a trade secret.
+// In fact, Gosset's identity was unknown not only to fellow statisticians
+// but to his employer - the company insisted on the pseudonym
+// so that it could turn a blind eye to the breach of its rules.
+
+// The Students't distribution function is described at
+// http://en.wikipedia.org/wiki/Student%27s_t_distribution
+
+#include <boost/math/distributions/students_t.hpp>
+ using boost::math::students_t; // Probability of students_t(df, t).
+
+#include <iostream>
+ using std::cout; using std::endl;
+#include <iomanip>
+ using std::setprecision; using std::setw;
+#include <cmath>
+ using std::sqrt;
+
+// This example of a two-sided test is from:
+// B. M. Smith & M. B. Griffiths, Analyst, 1982, 107, 253,
+// from Statistics for Analytical Chemistry, 3rd ed. (1994), pp 58-59
+// J. C. Miller and J. N. Miller, Ellis Horwood ISBN 0 13 0309907
+
+// Concentrations of lead (ug/l) determined by two different methods
+// for each of four test portions,
+// the concentration of each portion is significantly different,
+// the values may NOT be pooled.
+// (Called a 'paired test' by Miller and Miller
+// because each portion analysed has a different concentration.)
+
+// Portion Wet oxidation Direct Extraction
+// 1 71 76
+// 2 61 68
+// 3 50 48
+// 4 60 57
+
+const int portions = 4;
+const int methods = 2;
+float data [portions][methods] = {{71, 76}, {61,68}, {50, 48}, {60, 57}};
+float diffs[portions];
+
+int main()
+{
+ cout << "Example3 using Student's t function. " << endl;
+ float mean_diff = 0.f;
+ cout << "\n""Portion wet_oxidation Direct_extraction difference" << endl;
+ for (int portion = 0; portion < portions; portion++)
+ { // Echo data and differences.
+ diffs[portion] = data[portion][0] - data[portion][1];
+ mean_diff += diffs[portion];
+ cout << setw(4) << portion << ' ' << setw(14) << data[portion][0] << ' ' << setw(18)<< data[portion][1] << ' ' << setw(9) << diffs[portion] << endl;
+ }
+ mean_diff /= portions;
+ cout << "Mean difference = " << mean_diff << endl; // -1.75
+
+ float sd_diffs = 0.f;
+ for (int portion = 0; portion < portions; portion++)
+ { // Calculate standard deviation of differences.
+ sd_diffs +=(diffs[portion] - mean_diff) * (diffs[portion] - mean_diff);
+ }
+ int degrees_of_freedom = portions-1; // Use the n-1 formula.
+ sd_diffs /= degrees_of_freedom;
+ sd_diffs = sqrt(sd_diffs);
+ cout << "Standard deviation of differences = " << sd_diffs << endl; // 4.99166
+ // Standard deviation of differences = 4.99166
+ double t = mean_diff * sqrt(static_cast<double>(portions))/ sd_diffs; // -0.70117
+ cout << "Student's t = " << t << ", if " << degrees_of_freedom << " degrees of freedom." << endl;
+ // Student's t = -0.70117, if 3 degrees of freedom.
+ cout << "Probability of the means being different is "
+ << 2.F * cdf(students_t(degrees_of_freedom), t) << "."<< endl; // 0.266846 * 2 = 0.533692
+ // Double the probability because using a 'two-sided test' because
+ // mean for 'Wet oxidation' could be either
+ // greater OR LESS THAN for 'Direct extraction'.
+
+ return 0;
+} // int main()
+
+/*
+
+Output is:
+
+Example3 using Student's t function.
+Portion wet_oxidation Direct_extraction difference
+ 0 71 76 -5
+ 1 61 68 -7
+ 2 50 48 2
+ 3 60 57 3
+Mean difference = -1.75
+Standard deviation of differences = 4.99166
+Student's t = -0.70117, if 3 degrees of freedom.
+Probability of the means being different is 0.533692.
+
+*/
+
+
+
+
diff --git a/src/boost/libs/math/example/students_t_single_sample.cpp b/src/boost/libs/math/example/students_t_single_sample.cpp
new file mode 100644
index 000000000..591466ae5
--- /dev/null
+++ b/src/boost/libs/math/example/students_t_single_sample.cpp
@@ -0,0 +1,424 @@
+// Copyright John Maddock 2006
+// Copyright Paul A. Bristow 2007, 2010
+
+// 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)
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4512) // assignment operator could not be generated.
+# pragma warning(disable: 4510) // default constructor could not be generated.
+# pragma warning(disable: 4610) // can never be instantiated - user defined constructor required.
+#endif
+
+#include <boost/math/distributions/students_t.hpp>
+
+// avoid "using namespace std;" and "using namespace boost::math;"
+// to avoid potential ambiguity with names in std random.
+#include <iostream>
+using std::cout; using std::endl;
+using std::left; using std::fixed; using std::right; using std::scientific;
+#include <iomanip>
+using std::setw;
+using std::setprecision;
+
+void confidence_limits_on_mean(double Sm, double Sd, unsigned Sn)
+{
+ //
+ // Sm = Sample Mean.
+ // Sd = Sample Standard Deviation.
+ // Sn = Sample Size.
+ //
+ // Calculate confidence intervals for the mean.
+ // For example if we set the confidence limit to
+ // 0.95, we know that if we repeat the sampling
+ // 100 times, then we expect that the true mean
+ // will be between out limits on 95 occasions.
+ // Note: this is not the same as saying a 95%
+ // confidence interval means that there is a 95%
+ // probability that the interval contains the true mean.
+ // The interval computed from a given sample either
+ // contains the true mean or it does not.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda352.htm
+
+ using boost::math::students_t;
+
+ // Print out general info:
+ cout <<
+ "__________________________________\n"
+ "2-Sided Confidence Limits For Mean\n"
+ "__________________________________\n\n";
+ cout << setprecision(7);
+ cout << setw(40) << left << "Number of Observations" << "= " << Sn << "\n";
+ cout << setw(40) << left << "Mean" << "= " << Sm << "\n";
+ cout << setw(40) << left << "Standard Deviation" << "= " << Sd << "\n";
+ //
+ // Define a table of significance/risk levels:
+ //
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+ //
+ // Start by declaring the distribution we'll need:
+ //
+ students_t dist(Sn - 1);
+ //
+ // Print table header:
+ //
+ cout << "\n\n"
+ "_______________________________________________________________\n"
+ "Confidence T Interval Lower Upper\n"
+ " Value (%) Value Width Limit Limit\n"
+ "_______________________________________________________________\n";
+ //
+ // Now print out the data for the table rows.
+ //
+ for(unsigned i = 0; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // calculate T:
+ double T = quantile(complement(dist, alpha[i] / 2));
+ // Print T:
+ cout << fixed << setprecision(3) << setw(10) << right << T;
+ // Calculate width of interval (one sided):
+ double w = T * Sd / sqrt(double(Sn));
+ // Print width:
+ if(w < 0.01)
+ cout << scientific << setprecision(3) << setw(17) << right << w;
+ else
+ cout << fixed << setprecision(3) << setw(17) << right << w;
+ // Print Limits:
+ cout << fixed << setprecision(5) << setw(15) << right << Sm - w;
+ cout << fixed << setprecision(5) << setw(15) << right << Sm + w << endl;
+ }
+ cout << endl;
+} // void confidence_limits_on_mean
+
+void single_sample_t_test(double M, double Sm, double Sd, unsigned Sn, double alpha)
+{
+ //
+ // M = true mean.
+ // Sm = Sample Mean.
+ // Sd = Sample Standard Deviation.
+ // Sn = Sample Size.
+ // alpha = Significance Level.
+ //
+ // A Students t test applied to a single set of data.
+ // We are testing the null hypothesis that the true
+ // mean of the sample is M, and that any variation is down
+ // to chance. We can also test the alternative hypothesis
+ // that any difference is not down to chance.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda352.htm
+
+ using boost::math::students_t;
+
+ // Print header:
+ cout <<
+ "__________________________________\n"
+ "Student t test for a single sample\n"
+ "__________________________________\n\n";
+ cout << setprecision(5);
+ cout << setw(55) << left << "Number of Observations" << "= " << Sn << "\n";
+ cout << setw(55) << left << "Sample Mean" << "= " << Sm << "\n";
+ cout << setw(55) << left << "Sample Standard Deviation" << "= " << Sd << "\n";
+ cout << setw(55) << left << "Expected True Mean" << "= " << M << "\n\n";
+ //
+ // Now we can calculate and output some stats:
+ //
+ // Difference in means:
+ double diff = Sm - M;
+ cout << setw(55) << left << "Sample Mean - Expected Test Mean" << "= " << diff << "\n";
+ // Degrees of freedom:
+ unsigned v = Sn - 1;
+ cout << setw(55) << left << "Degrees of Freedom" << "= " << v << "\n";
+ // t-statistic:
+ double t_stat = diff * sqrt(double(Sn)) / Sd;
+ cout << setw(55) << left << "T Statistic" << "= " << t_stat << "\n";
+ //
+ // Finally define our distribution, and get the probability:
+ //
+ students_t dist(v);
+ double q = cdf(complement(dist, fabs(t_stat)));
+ cout << setw(55) << left << "Probability that difference is due to chance" << "= "
+ << setprecision(3) << scientific << 2 * q << "\n\n";
+ //
+ // Finally print out results of alternative hypothesis:
+ //
+ cout << setw(55) << left <<
+ "Results for Alternative Hypothesis and alpha" << "= "
+ << setprecision(4) << fixed << alpha << "\n\n";
+ cout << "Alternative Hypothesis Conclusion\n";
+ cout << "Mean != " << setprecision(3) << fixed << M << " ";
+ if(q < alpha / 2)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Mean < " << setprecision(3) << fixed << M << " ";
+ if(cdf(complement(dist, t_stat)) > alpha)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Mean > " << setprecision(3) << fixed << M << " ";
+ if(cdf(dist, t_stat) > alpha)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << endl << endl;
+} // void single_sample_t_test(
+
+void single_sample_find_df(double M, double Sm, double Sd)
+{
+ //
+ // M = true mean.
+ // Sm = Sample Mean.
+ // Sd = Sample Standard Deviation.
+ //
+
+ using boost::math::students_t;
+
+ // Print out general info:
+ cout <<
+ "_____________________________________________________________\n"
+ "Estimated sample sizes required for various confidence levels\n"
+ "_____________________________________________________________\n\n";
+ cout << setprecision(5);
+ cout << setw(40) << left << "True Mean" << "= " << M << "\n";
+ cout << setw(40) << left << "Sample Mean" << "= " << Sm << "\n";
+ cout << setw(40) << left << "Sample Standard Deviation" << "= " << Sd << "\n";
+ //
+ // Define a table of significance intervals:
+ //
+ double alpha[] = { 0.5, 0.25, 0.1, 0.05, 0.01, 0.001, 0.0001, 0.00001 };
+ //
+ // Print table header:
+ //
+ cout << "\n\n"
+ "_______________________________________________________________\n"
+ "Confidence Estimated Estimated\n"
+ " Value (%) Sample Size Sample Size\n"
+ " (one sided test) (two sided test)\n"
+ "_______________________________________________________________\n";
+ //
+ // Now print out the data for the table rows.
+ //
+ for(unsigned i = 1; i < sizeof(alpha)/sizeof(alpha[0]); ++i)
+ {
+ // Confidence value:
+ cout << fixed << setprecision(3) << setw(10) << right << 100 * (1-alpha[i]);
+ // calculate df for single sided test:
+ double df = students_t::find_degrees_of_freedom(
+ fabs(M - Sm), alpha[i], alpha[i], Sd);
+ // convert to sample size, always one more than the degrees of freedom:
+ double size = ceil(df) + 1;
+ // Print size:
+ cout << fixed << setprecision(0) << setw(16) << right << size;
+ // calculate df for two sided test:
+ df = students_t::find_degrees_of_freedom(
+ fabs(M - Sm), alpha[i]/2, alpha[i], Sd);
+ // convert to sample size:
+ size = ceil(df) + 1;
+ // Print size:
+ cout << fixed << setprecision(0) << setw(16) << right << size << endl;
+ }
+ cout << endl;
+} // void single_sample_find_df
+
+int main()
+{
+ //
+ // Run tests for Heat Flow Meter data
+ // see http://www.itl.nist.gov/div898/handbook/eda/section4/eda428.htm
+ // The data was collected while calibrating a heat flow meter
+ // against a known value.
+ //
+ confidence_limits_on_mean(9.261460, 0.2278881e-01, 195);
+ single_sample_t_test(5, 9.261460, 0.2278881e-01, 195, 0.05);
+ single_sample_find_df(5, 9.261460, 0.2278881e-01);
+
+ //
+ // Data for this example from:
+ // P.K.Hou, O. W. Lau & M.C. Wong, Analyst (1983) vol. 108, p 64.
+ // from Statistics for Analytical Chemistry, 3rd ed. (1994), pp 54-55
+ // J. C. Miller and J. N. Miller, Ellis Horwood ISBN 0 13 0309907
+ //
+ // Determination of mercury by cold-vapour atomic absorption,
+ // the following values were obtained fusing a trusted
+ // Standard Reference Material containing 38.9% mercury,
+ // which we assume is correct or 'true'.
+ //
+ confidence_limits_on_mean(37.8, 0.964365, 3);
+ // 95% test:
+ single_sample_t_test(38.9, 37.8, 0.964365, 3, 0.05);
+ // 90% test:
+ single_sample_t_test(38.9, 37.8, 0.964365, 3, 0.1);
+ // parameter estimate:
+ single_sample_find_df(38.9, 37.8, 0.964365);
+
+ return 0;
+} // int main()
+
+/*
+
+Output:
+
+------ Rebuild All started: Project: students_t_single_sample, Configuration: Release Win32 ------
+ students_t_single_sample.cpp
+ Generating code
+ Finished generating code
+ students_t_single_sample.vcxproj -> J:\Cpp\MathToolkit\test\Math_test\Release\students_t_single_sample.exe
+__________________________________
+2-Sided Confidence Limits For Mean
+__________________________________
+
+Number of Observations = 195
+Mean = 9.26146
+Standard Deviation = 0.02278881
+
+
+_______________________________________________________________
+Confidence T Interval Lower Upper
+ Value (%) Value Width Limit Limit
+_______________________________________________________________
+ 50.000 0.676 1.103e-003 9.26036 9.26256
+ 75.000 1.154 1.883e-003 9.25958 9.26334
+ 90.000 1.653 2.697e-003 9.25876 9.26416
+ 95.000 1.972 3.219e-003 9.25824 9.26468
+ 99.000 2.601 4.245e-003 9.25721 9.26571
+ 99.900 3.341 5.453e-003 9.25601 9.26691
+ 99.990 3.973 6.484e-003 9.25498 9.26794
+ 99.999 4.537 7.404e-003 9.25406 9.26886
+
+__________________________________
+Student t test for a single sample
+__________________________________
+
+Number of Observations = 195
+Sample Mean = 9.26146
+Sample Standard Deviation = 0.02279
+Expected True Mean = 5.00000
+
+Sample Mean - Expected Test Mean = 4.26146
+Degrees of Freedom = 194
+T Statistic = 2611.28380
+Probability that difference is due to chance = 0.000e+000
+
+Results for Alternative Hypothesis and alpha = 0.0500
+
+Alternative Hypothesis Conclusion
+Mean != 5.000 NOT REJECTED
+Mean < 5.000 REJECTED
+Mean > 5.000 NOT REJECTED
+
+
+_____________________________________________________________
+Estimated sample sizes required for various confidence levels
+_____________________________________________________________
+
+True Mean = 5.00000
+Sample Mean = 9.26146
+Sample Standard Deviation = 0.02279
+
+
+_______________________________________________________________
+Confidence Estimated Estimated
+ Value (%) Sample Size Sample Size
+ (one sided test) (two sided test)
+_______________________________________________________________
+ 75.000 2 2
+ 90.000 2 2
+ 95.000 2 2
+ 99.000 2 2
+ 99.900 3 3
+ 99.990 3 3
+ 99.999 4 4
+
+__________________________________
+2-Sided Confidence Limits For Mean
+__________________________________
+
+Number of Observations = 3
+Mean = 37.8000000
+Standard Deviation = 0.9643650
+
+
+_______________________________________________________________
+Confidence T Interval Lower Upper
+ Value (%) Value Width Limit Limit
+_______________________________________________________________
+ 50.000 0.816 0.455 37.34539 38.25461
+ 75.000 1.604 0.893 36.90717 38.69283
+ 90.000 2.920 1.626 36.17422 39.42578
+ 95.000 4.303 2.396 35.40438 40.19562
+ 99.000 9.925 5.526 32.27408 43.32592
+ 99.900 31.599 17.594 20.20639 55.39361
+ 99.990 99.992 55.673 -17.87346 93.47346
+ 99.999 316.225 176.067 -138.26683 213.86683
+
+__________________________________
+Student t test for a single sample
+__________________________________
+
+Number of Observations = 3
+Sample Mean = 37.80000
+Sample Standard Deviation = 0.96437
+Expected True Mean = 38.90000
+
+Sample Mean - Expected Test Mean = -1.10000
+Degrees of Freedom = 2
+T Statistic = -1.97566
+Probability that difference is due to chance = 1.869e-001
+
+Results for Alternative Hypothesis and alpha = 0.0500
+
+Alternative Hypothesis Conclusion
+Mean != 38.900 REJECTED
+Mean < 38.900 NOT REJECTED
+Mean > 38.900 NOT REJECTED
+
+
+__________________________________
+Student t test for a single sample
+__________________________________
+
+Number of Observations = 3
+Sample Mean = 37.80000
+Sample Standard Deviation = 0.96437
+Expected True Mean = 38.90000
+
+Sample Mean - Expected Test Mean = -1.10000
+Degrees of Freedom = 2
+T Statistic = -1.97566
+Probability that difference is due to chance = 1.869e-001
+
+Results for Alternative Hypothesis and alpha = 0.1000
+
+Alternative Hypothesis Conclusion
+Mean != 38.900 REJECTED
+Mean < 38.900 NOT REJECTED
+Mean > 38.900 REJECTED
+
+
+_____________________________________________________________
+Estimated sample sizes required for various confidence levels
+_____________________________________________________________
+
+True Mean = 38.90000
+Sample Mean = 37.80000
+Sample Standard Deviation = 0.96437
+
+
+_______________________________________________________________
+Confidence Estimated Estimated
+ Value (%) Sample Size Sample Size
+ (one sided test) (two sided test)
+_______________________________________________________________
+ 75.000 3 4
+ 90.000 7 9
+ 95.000 11 13
+ 99.000 20 22
+ 99.900 35 37
+ 99.990 50 53
+ 99.999 66 68
+
+*/
+
diff --git a/src/boost/libs/math/example/students_t_two_samples.cpp b/src/boost/libs/math/example/students_t_two_samples.cpp
new file mode 100644
index 000000000..66a9e7036
--- /dev/null
+++ b/src/boost/libs/math/example/students_t_two_samples.cpp
@@ -0,0 +1,245 @@
+// Copyright John Maddock 2006.
+// Copyright Paul A. Bristow 2007, 2010
+
+// 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)
+
+#ifdef _MSC_VER
+# pragma warning(disable: 4512) // assignment operator could not be generated.
+# pragma warning(disable: 4510) // default constructor could not be generated.
+# pragma warning(disable: 4610) // can never be instantiated - user defined constructor required.
+#endif
+
+#include <iostream>
+using std::cout; using std::endl;
+using std::left; using std::fixed; using std::right; using std::scientific;
+#include <iomanip>
+using std::setw;
+using std::setprecision;
+
+#include <boost/math/distributions/students_t.hpp>
+ using boost::math::students_t;
+
+
+void two_samples_t_test_equal_sd(
+ double Sm1, // Sm1 = Sample Mean 1.
+ double Sd1, // Sd1 = Sample Standard Deviation 1.
+ unsigned Sn1, // Sn1 = Sample Size 1.
+ double Sm2, // Sm2 = Sample Mean 2.
+ double Sd2, // Sd2 = Sample Standard Deviation 2.
+ unsigned Sn2, // Sn2 = Sample Size 2.
+ double alpha) // alpha = Significance Level.
+{
+ // A Students t test applied to two sets of data.
+ // We are testing the null hypothesis that the two
+ // samples have the same mean and that any difference
+ // if due to chance.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm
+ //
+ using namespace std;
+ // using namespace boost::math;
+
+ using boost::math::students_t;
+
+ // Print header:
+ cout <<
+ "_______________________________________________\n"
+ "Student t test for two samples (equal variances)\n"
+ "_______________________________________________\n\n";
+ cout << setprecision(5);
+ cout << setw(55) << left << "Number of Observations (Sample 1)" << "= " << Sn1 << "\n";
+ cout << setw(55) << left << "Sample 1 Mean" << "= " << Sm1 << "\n";
+ cout << setw(55) << left << "Sample 1 Standard Deviation" << "= " << Sd1 << "\n";
+ cout << setw(55) << left << "Number of Observations (Sample 2)" << "= " << Sn2 << "\n";
+ cout << setw(55) << left << "Sample 2 Mean" << "= " << Sm2 << "\n";
+ cout << setw(55) << left << "Sample 2 Standard Deviation" << "= " << Sd2 << "\n";
+ //
+ // Now we can calculate and output some stats:
+ //
+ // Degrees of freedom:
+ double v = Sn1 + Sn2 - 2;
+ cout << setw(55) << left << "Degrees of Freedom" << "= " << v << "\n";
+ // Pooled variance and hence standard deviation:
+ double sp = sqrt(((Sn1-1) * Sd1 * Sd1 + (Sn2-1) * Sd2 * Sd2) / v);
+ cout << setw(55) << left << "Pooled Standard Deviation" << "= " << sp << "\n";
+ // t-statistic:
+ double t_stat = (Sm1 - Sm2) / (sp * sqrt(1.0 / Sn1 + 1.0 / Sn2));
+ cout << setw(55) << left << "T Statistic" << "= " << t_stat << "\n";
+ //
+ // Define our distribution, and get the probability:
+ //
+ students_t dist(v);
+ double q = cdf(complement(dist, fabs(t_stat)));
+ cout << setw(55) << left << "Probability that difference is due to chance" << "= "
+ << setprecision(3) << scientific << 2 * q << "\n\n";
+ //
+ // Finally print out results of alternative hypothesis:
+ //
+ cout << setw(55) << left <<
+ "Results for Alternative Hypothesis and alpha" << "= "
+ << setprecision(4) << fixed << alpha << "\n\n";
+ cout << "Alternative Hypothesis Conclusion\n";
+ cout << "Sample 1 Mean != Sample 2 Mean " ;
+ if(q < alpha / 2)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Sample 1 Mean < Sample 2 Mean ";
+ if(cdf(dist, t_stat) < alpha)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Sample 1 Mean > Sample 2 Mean ";
+ if(cdf(complement(dist, t_stat)) < alpha)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << endl << endl;
+}
+
+void two_samples_t_test_unequal_sd(
+ double Sm1, // Sm1 = Sample Mean 1.
+ double Sd1, // Sd1 = Sample Standard Deviation 1.
+ unsigned Sn1, // Sn1 = Sample Size 1.
+ double Sm2, // Sm2 = Sample Mean 2.
+ double Sd2, // Sd2 = Sample Standard Deviation 2.
+ unsigned Sn2, // Sn2 = Sample Size 2.
+ double alpha) // alpha = Significance Level.
+{
+ // A Students t test applied to two sets of data.
+ // We are testing the null hypothesis that the two
+ // samples have the same mean and
+ // that any difference is due to chance.
+ // See http://www.itl.nist.gov/div898/handbook/eda/section3/eda353.htm
+ //
+ using namespace std;
+ using boost::math::students_t;
+
+ // Print header:
+ cout <<
+ "_________________________________________________\n"
+ "Student t test for two samples (unequal variances)\n"
+ "_________________________________________________\n\n";
+ cout << setprecision(5);
+ cout << setw(55) << left << "Number of Observations (Sample 1)" << "= " << Sn1 << "\n";
+ cout << setw(55) << left << "Sample 1 Mean" << "= " << Sm1 << "\n";
+ cout << setw(55) << left << "Sample 1 Standard Deviation" << "= " << Sd1 << "\n";
+ cout << setw(55) << left << "Number of Observations (Sample 2)" << "= " << Sn2 << "\n";
+ cout << setw(55) << left << "Sample 2 Mean" << "= " << Sm2 << "\n";
+ cout << setw(55) << left << "Sample 2 Standard Deviation" << "= " << Sd2 << "\n";
+ //
+ // Now we can calculate and output some stats:
+ //
+ // Degrees of freedom:
+ double v = Sd1 * Sd1 / Sn1 + Sd2 * Sd2 / Sn2;
+ v *= v;
+ double t1 = Sd1 * Sd1 / Sn1;
+ t1 *= t1;
+ t1 /= (Sn1 - 1);
+ double t2 = Sd2 * Sd2 / Sn2;
+ t2 *= t2;
+ t2 /= (Sn2 - 1);
+ v /= (t1 + t2);
+ cout << setw(55) << left << "Degrees of Freedom" << "= " << v << "\n";
+ // t-statistic:
+ double t_stat = (Sm1 - Sm2) / sqrt(Sd1 * Sd1 / Sn1 + Sd2 * Sd2 / Sn2);
+ cout << setw(55) << left << "T Statistic" << "= " << t_stat << "\n";
+ //
+ // Define our distribution, and get the probability:
+ //
+ students_t dist(v);
+ double q = cdf(complement(dist, fabs(t_stat)));
+ cout << setw(55) << left << "Probability that difference is due to chance" << "= "
+ << setprecision(3) << scientific << 2 * q << "\n\n";
+ //
+ // Finally print out results of alternative hypothesis:
+ //
+ cout << setw(55) << left <<
+ "Results for Alternative Hypothesis and alpha" << "= "
+ << setprecision(4) << fixed << alpha << "\n\n";
+ cout << "Alternative Hypothesis Conclusion\n";
+ cout << "Sample 1 Mean != Sample 2 Mean " ;
+ if(q < alpha / 2)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Sample 1 Mean < Sample 2 Mean ";
+ if(cdf(dist, t_stat) < alpha)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << "Sample 1 Mean > Sample 2 Mean ";
+ if(cdf(complement(dist, t_stat)) < alpha)
+ cout << "NOT REJECTED\n";
+ else
+ cout << "REJECTED\n";
+ cout << endl << endl;
+}
+
+int main()
+{
+ //
+ // Run tests for Car Mileage sample data
+ // http://www.itl.nist.gov/div898/handbook/eda/section3/eda3531.htm
+ // from the NIST website http://www.itl.nist.gov. The data compares
+ // miles per gallon of US cars with miles per gallon of Japanese cars.
+ //
+ two_samples_t_test_equal_sd(20.14458, 6.414700, 249, 30.48101, 6.107710, 79, 0.05);
+ two_samples_t_test_unequal_sd(20.14458, 6.414700, 249, 30.48101, 6.107710, 79, 0.05);
+
+ return 0;
+} // int main()
+
+/*
+Output is:
+
+ _______________________________________________
+ Student t test for two samples (equal variances)
+ _______________________________________________
+
+ Number of Observations (Sample 1) = 249
+ Sample 1 Mean = 20.145
+ Sample 1 Standard Deviation = 6.4147
+ Number of Observations (Sample 2) = 79
+ Sample 2 Mean = 30.481
+ Sample 2 Standard Deviation = 6.1077
+ Degrees of Freedom = 326
+ Pooled Standard Deviation = 6.3426
+ T Statistic = -12.621
+ Probability that difference is due to chance = 5.273e-030
+
+ Results for Alternative Hypothesis and alpha = 0.0500
+
+ Alternative Hypothesis Conclusion
+ Sample 1 Mean != Sample 2 Mean NOT REJECTED
+ Sample 1 Mean < Sample 2 Mean NOT REJECTED
+ Sample 1 Mean > Sample 2 Mean REJECTED
+
+
+ _________________________________________________
+ Student t test for two samples (unequal variances)
+ _________________________________________________
+
+ Number of Observations (Sample 1) = 249
+ Sample 1 Mean = 20.14458
+ Sample 1 Standard Deviation = 6.41470
+ Number of Observations (Sample 2) = 79
+ Sample 2 Mean = 30.48101
+ Sample 2 Standard Deviation = 6.10771
+ Degrees of Freedom = 136.87499
+ T Statistic = -12.94627
+ Probability that difference is due to chance = 1.571e-025
+
+ Results for Alternative Hypothesis and alpha = 0.0500
+
+ Alternative Hypothesis Conclusion
+ Sample 1 Mean != Sample 2 Mean NOT REJECTED
+ Sample 1 Mean < Sample 2 Mean NOT REJECTED
+ Sample 1 Mean > Sample 2 Mean REJECTED
+
+
+
+*/
+
diff --git a/src/boost/libs/math/example/table_type.hpp b/src/boost/libs/math/example/table_type.hpp
new file mode 100644
index 000000000..b8f16cfdf
--- /dev/null
+++ b/src/boost/libs/math/example/table_type.hpp
@@ -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
diff --git a/src/boost/libs/math/example/test_cpp_float_close_fraction.cpp b/src/boost/libs/math/example/test_cpp_float_close_fraction.cpp
new file mode 100644
index 000000000..b4699fad8
--- /dev/null
+++ b/src/boost/libs/math/example/test_cpp_float_close_fraction.cpp
@@ -0,0 +1,119 @@
+// 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)
+
+// Copyright Paul A. Bristow 2013
+// Copyright Christopher Kormanyos 2013.
+// Copyright John Maddock 2013.
+
+#ifdef _MSC_VER
+# pragma warning (disable : 4512)
+# pragma warning (disable : 4996)
+#endif
+
+#define BOOST_TEST_MAIN
+#define BOOST_LIB_DIAGNOSTIC "on"// Show library file details.
+
+#include <boost/test/unit_test.hpp>
+#include <boost/test/tools/floating_point_comparison.hpp> // Extra test tool for FP comparison.
+
+#include <iostream>
+#include <limits>
+
+//[expression_template_1
+
+#include <boost/multiprecision/cpp_dec_float.hpp>
+
+/*`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:
+
+``
+typedef boost::multiprecision::cpp_dec_float<50> mp_backend;
+typedef boost::multiprecision::number<mp_backend, boost::multiprecision::et_off> cpp_dec_float_50_noet;
+``
+
+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>
+ cpp_dec_float_50_noet;
+
+You can reduce typing with a `using` directive `using namespace boost::multiprecision;`
+if desired, as shown below.
+*/
+
+using namespace boost::multiprecision;
+
+
+/*`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.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();
+
+ 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).
+
+
+
+} // 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)
+
+/*
+
+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
+
+
+*/
+
diff --git a/src/boost/libs/math/example/test_nonfinite_loopback.cpp b/src/boost/libs/math/example/test_nonfinite_loopback.cpp
new file mode 100644
index 000000000..c7b8e4204
--- /dev/null
+++ b/src/boost/libs/math/example/test_nonfinite_loopback.cpp
@@ -0,0 +1,97 @@
+// 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)
+
+// Copyright (c) 2006 Johan Rade
+// Copyright (c) 2011 Paul A. Bristow
+
+/*!
+\file
+\brief Basic tests of native nonfinite loopback.
+
+\detail Basic loopback test outputs using the platforms built-in facets
+and reads back in, and checks if loopback OK.
+
+Using MSVC this doesn't work OK:
+input produces just "1" instead of "1.#QNAN", 1.#SNAN" or 1.#IND"!
+
+*/
+
+#include <iostream>
+using std::cout;
+using std::endl;
+#include <locale>
+using std::locale;
+#include <string>
+using std::string;
+#include <sstream>
+ using std::stringstream;
+#include <limits>
+using std::numeric_limits;
+
+int main()
+{
+ locale default_locale; // Current global locale.
+ // Try to use the default locale first.
+ // On MSVC this doesn't work.
+
+ { // Try infinity.
+ stringstream ss; // Both input and output.
+ ss.imbue(default_locale); // Redundant, of course.
+ string infs;
+ if(numeric_limits<double>::has_infinity)
+ { // Make sure infinity is specialised for type double.
+ double inf = numeric_limits<double>::infinity();
+ ss << inf; // Output infinity.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for infinity.
+ infs = "1.#INF"; // Might suit MSVC?
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "infinity output was " << infs << endl; // "1.#INF"
+ cout << "infinity input was " << r << endl; // "1"
+ }
+
+ { // Try Quiet NaN
+ stringstream ss; // Both input and output.
+ ss.imbue(default_locale); // Redundant, of course.
+ string infs;
+ if(numeric_limits<double>::has_quiet_NaN)
+ { // Make sure quiet NaN is specialised for type double.
+ double qnan = numeric_limits<double>::quiet_NaN();
+ ss << qnan; // Output quiet_NaN.
+ infs = ss.str(); //
+ }
+ else
+ { // Need to provide a suitable string for quiet_NAN.
+ infs = "1.#QNAN";
+ ss << infs;
+ }
+ double r;
+ ss >> r; // Read back in.
+
+ cout << "quiet_NaN output was " << infs << endl; // "1.#QNAN"
+ cout << "quiet_NaN input was " << r << endl; // "1#"
+ }
+
+
+} // int main()
+
+/*
+
+Output (MSVC Version 10.0):
+
+
+ infinity output was 1.#INF
+ infinity input was 1
+ quiet_NaN output was 1.#QNAN
+ quiet_NaN input was 1
+
+
+*/
+
diff --git a/src/boost/libs/math/example/trapezoidal_example.cpp b/src/boost/libs/math/example/trapezoidal_example.cpp
new file mode 100644
index 000000000..bbea64152
--- /dev/null
+++ b/src/boost/libs/math/example/trapezoidal_example.cpp
@@ -0,0 +1,29 @@
+/*
+ * Copyright Nick Thompson, 2017
+ * Use, modification and distribution are subject to the
+ * Boost Software License, Version 1.0. (See accompanying file
+ * LICENSE_1_0.txt or copy at http://www.boost.org/LICENSE_1_0.txt)
+ *
+ * This example shows to to numerically integrate a periodic function using the adaptive_trapezoidal routine provided by boost.
+ */
+
+#include <iostream>
+#include <cmath>
+#include <limits>
+#include <boost/math/quadrature/trapezoidal.hpp>
+
+int main()
+{
+ using boost::math::constants::two_pi;
+ using boost::math::constants::third;
+ using boost::math::quadrature::trapezoidal;
+ // This function has an analytic form for its integral over a period: 2pi/3.
+ auto f = [](double x) { return 1/(5 - 4*cos(x)); };
+
+ double Q = trapezoidal(f, (double) 0, two_pi<double>());
+
+ std::cout << std::setprecision(std::numeric_limits<double>::digits10);
+ std::cout << "The adaptive trapezoidal rule gives the integral of our function as " << Q << "\n";
+ std::cout << "The exact result is " << two_pi<double>()*third<double>() << "\n";
+
+}