From c79fa7e686d3704c324d277d2af148e199968033 Mon Sep 17 00:00:00 2001 From: jzmaddock Date: Fri, 2 Mar 2018 18:08:34 +0000 Subject: [PATCH] Fix documentation typos. Fixes #13355 and #13403. --- doc/distributions/gamma.qbk | 2 +- doc/html/index.html | 2 +- doc/html/indexes/s01.html | 2 +- doc/html/indexes/s02.html | 2 +- doc/html/indexes/s03.html | 2 +- doc/html/indexes/s04.html | 2 +- doc/html/indexes/s05.html | 2 +- doc/html/math_toolkit/conventions.html | 2 +- .../dist_ref/dists/gamma_dist.html | 2 +- doc/html/math_toolkit/float_comparison.html | 7 +- doc/html/math_toolkit/naive_monte_carlo.html | 231 ++++++++++++++++++ doc/html/math_toolkit/navigation.html | 2 +- example/float_comparison_example.cpp | 2 +- 13 files changed, 245 insertions(+), 15 deletions(-) create mode 100644 doc/html/math_toolkit/naive_monte_carlo.html diff --git a/doc/distributions/gamma.qbk b/doc/distributions/gamma.qbk index 11b2be3e9..9d5faabd6 100644 --- a/doc/distributions/gamma.qbk +++ b/doc/distributions/gamma.qbk @@ -101,7 +101,7 @@ The domain of the random variable is \[0,+[infin]\]. [h4 Accuracy] -The lognormal distribution is implemented in terms of the +The gamma distribution is implemented in terms of the incomplete gamma functions __gamma_p and __gamma_q and their inverses __gamma_p_inv and __gamma_q_inv: refer to the accuracy data for those functions for more information. diff --git a/doc/html/index.html b/doc/html/index.html index 37a9b1dea..c43a3b3be 100644 --- a/doc/html/index.html +++ b/doc/html/index.html @@ -122,7 +122,7 @@ This manual is also available in -

Last revised: February 18, 2018 at 08:34:31 GMT

+

Last revised: March 02, 2018 at 18:04:21 GMT


diff --git a/doc/html/indexes/s01.html b/doc/html/indexes/s01.html index 42cbd4c28..8afa63366 100644 --- a/doc/html/indexes/s01.html +++ b/doc/html/indexes/s01.html @@ -24,7 +24,7 @@

-Function Index

+Function Index

1 2 4 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

diff --git a/doc/html/indexes/s02.html b/doc/html/indexes/s02.html index c813bcb9e..23735f595 100644 --- a/doc/html/indexes/s02.html +++ b/doc/html/indexes/s02.html @@ -24,7 +24,7 @@

-Class Index

+Class Index

A B C D E F G H I L M N O P Q R S T U W

diff --git a/doc/html/indexes/s03.html b/doc/html/indexes/s03.html index 42db0af15..4424fb5e3 100644 --- a/doc/html/indexes/s03.html +++ b/doc/html/indexes/s03.html @@ -24,7 +24,7 @@

-Typedef Index

+Typedef Index

A B C D E F G H I L N O P R S T U V W

diff --git a/doc/html/indexes/s04.html b/doc/html/indexes/s04.html index e8e05ed11..06df03560 100644 --- a/doc/html/indexes/s04.html +++ b/doc/html/indexes/s04.html @@ -24,7 +24,7 @@

-Macro Index

+Macro Index

B F

diff --git a/doc/html/indexes/s05.html b/doc/html/indexes/s05.html index 7164d3b66..688bd6d8d 100644 --- a/doc/html/indexes/s05.html +++ b/doc/html/indexes/s05.html @@ -23,7 +23,7 @@

-Index

+Index

1 2 4 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z

diff --git a/doc/html/math_toolkit/conventions.html b/doc/html/math_toolkit/conventions.html index 6e0a2ef97..4addb003d 100644 --- a/doc/html/math_toolkit/conventions.html +++ b/doc/html/math_toolkit/conventions.html @@ -27,7 +27,7 @@ Document Conventions

- +

This documentation aims to use of the following naming and formatting conventions. diff --git a/doc/html/math_toolkit/dist_ref/dists/gamma_dist.html b/doc/html/math_toolkit/dist_ref/dists/gamma_dist.html index 1ff6ce15b..328090d50 100644 --- a/doc/html/math_toolkit/dist_ref/dists/gamma_dist.html +++ b/doc/html/math_toolkit/dist_ref/dists/gamma_dist.html @@ -170,7 +170,7 @@ Accuracy

- The lognormal distribution is implemented in terms of the incomplete gamma + The gamma distribution is implemented in terms of the incomplete gamma functions gamma_p and gamma_q and their inverses gamma_p_inv and diff --git a/doc/html/math_toolkit/float_comparison.html b/doc/html/math_toolkit/float_comparison.html index a46ff54a1..e12bf7f6b 100644 --- a/doc/html/math_toolkit/float_comparison.html +++ b/doc/html/math_toolkit/float_comparison.html @@ -191,10 +191,9 @@

The following examples display values with all possibly significant digits. - Newer compilers should provide std::numeric_limitsFPT>::max_digits10 - for this purpose, and here we use float - precision where max_digits10 - = 9 to avoid displaying a distracting number of decimal 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.

diff --git a/doc/html/math_toolkit/naive_monte_carlo.html b/doc/html/math_toolkit/naive_monte_carlo.html new file mode 100644 index 000000000..fa0e2882f --- /dev/null +++ b/doc/html/math_toolkit/naive_monte_carlo.html @@ -0,0 +1,231 @@ + + + +Naive Monte Carlo Integration + + + + + + + + +
+ + + + + + +
Boost C++ LibrariesHomeLibrariesPeopleFAQMore
+
+
+PrevUpHomeNext +
+
+ +

+ + Synopsis +

+
#include <boost/math/quadrature/naive_monte_carlo.hpp>
+namespace boost { namespace math { namespace quadrature {
+
+template<class Real, class F, class RNG = std::mt19937_64, class Policy = boost::math::policies::policy<>>
+class naive_monte_carlo
+{
+public:
+    naive_monte_carlo(const F& integrand,
+                      std::vector<std::pair<Real, Real>> const & bounds,
+                      Real error_goal,
+                      bool singular = true,
+                      size_t threads = std::thread::hardware_concurrency());
+
+    std::future<Real> integrate();
+
+    void cancel();
+
+    Real current_error_estimate() const;
+
+    std::chrono::duration<Real> estimated_time_to_completion() const;
+
+    void update_target_error(Real new_target_error);
+
+    Real progress() const;
+
+    Real current_estimate() const;
+
+    size_t calls() const;
+};
+}}} // namespaces
+
+

+ + Description +

+

+ The class naive_monte_carlo + performs Monte-Carlo integration on a square integrable function f + on a domain Ω. The theoretical background of Monte-Carlo integration is nicely + discussed at Wikipedia, + and as such will not be discussed here. However, despite being "naive", + it is a mistake to assume that naive Monte-Carlo integration is not powerful, + as the simplicity of the method affords a robustness not easily provided by + more sophisticated tools. The multithreaded nature of the routine allows us + to compute a large number of sample points with great speed, and hence the + slow convergence is mitigated by exploiting the full power of modern hardware. +

+

+ The naive Monte-Carlo integration provided by Boost exemplifies the programming + techniques needed to cope with high-performance computing. For instance, since + the convergence is only 𝑶(N-1/2), the compute time is very sensitive to the + error goal. Users can easily specify an error goal which causes computation + to last months-or just a few seconds. Without progress reporting, this situation + is disorienting and causes the user to behave in a paranoid manner. Even with + progress reporting, a user might need to cancel a job due to shifting priorities + of the employing institution, and as such cancellation must be supported. A + cancelled job which returns no results is wasted, so the cancellation must + be graceful, returning the best estimate of the result thus far. In addition, + a task might finish, and the user may well decide to try for a lower error + bound. Hence restarting without loss of the preceding effort must be supported. + Finally, on an HPC system, we generally wish to use all available threads. + But if the computation is performed on a users workstation, employing every + thread will cause the browser, email, or music apps to become unresponsive, + so leaving a single thread available for other apps is appreciated. +

+

+ All these use cases are supported, so let's get to the code: +

+
// Define a function to integrate:
+auto g = [](std::vector<double> const & x)
+{
+  constexpr const double A = 1.0 / (M_PI * M_PI * M_PI);
+  return A / (1.0 - cos(x[0])*cos(x[1])*cos(x[2]));
+};
+std::vector<std::pair<double, double>> bounds{{0, M_PI}, {0, M_PI}, {0, M_PI}};
+double error_goal = 0.001
+naive_monte_carlo<double, decltype(g)> mc(g, bounds, error_goal);
+
+std::future<double> task = mc.integrate();
+while (task.wait_for(std::chrono::seconds(1)) != std::future_status::ready)
+{
+    // The user must decide on a reasonable way to display the progress depending on their environment:
+    display_progress(mc.progress(),
+                     mc.current_error_estimate(),
+                     mc.current_estimate(),
+                     mc.estimated_time_to_completion());
+    if (some_signal_heard())
+    {
+        mc.cancel();
+        std::cout << "\nCancelling because this is too slow!\n";
+    }
+}
+double y = task.get();
+
+

+ First off, we define the function we wish to integrate. This function must + accept a std::vector<Real> const &, + and return a Real. Next, we + define the domain of integration. Infinite domains are indicated by the bound + std::numeric_limits<Real>::infinity(). + The call +

+
naive_monte_carlo<double, decltype(g)> mc(g, bounds, error_goal);
+
+

+ creates an instance of the monte carlo integrator. This is also where the number + of threads can be set, for instance +

+
naive_monte_carlo<double, decltype(g)> mc(g, bounds, error_goal, true, std::thread::hardware_concurrency() - 1);
+
+

+ might be more appropriate for running on a user's hardware (the default taking + all the threads). The call to integrate() does not return the value of the integral, + but rather a std::future<Real>. + This allows us to do progress reporting from the master thread via +

+
while (task.wait_for(std::chrono::seconds(1)) != std::future_status::ready)
+{
+    // some reasonable method of displaying progress, based on the requirements of your app.
+    display_progress(mc.progress(),
+                     mc.current_error_estimate(),
+                     mc.current_estimate(),
+                     mc.estimated_time_to_completion());
+}
+
+

+ The file example/naive_monte_carlo_example.cpp has an implementation of display_progress which is reasonable for + command line apps. In addition, we can call mc.cancel() + in this loop to stop the integration. Progress reporting is especially useful + if you accidentally pass in an integrand which is not square integrable-the + variance increases without bound, and the progress decreases from some noisy + initial value down to zero with time. Calling task.get() + returns the current estimate. Once the future is ready, we can get the value + of the integral via +

+
double result = task.get();
+
+

+ At this point, the user may wish to reduce the error goal. This is achieved + by +

+
double new_target_error = 0.0005;
+mc.update_target_error(new_target_error);
+task = mc.integrate();
+y = task.get();
+
+

+ There is one additional "advanced" parameter: Whether or not the + integrand is singular on the boundary. If the integrand is not + singular on the boundary, then the integrand is evaluated over the closed set + ∏i [ ai, bi ]. + If the integrand is singular (the default) then the integrand is evaluated + over the closed set ∏i [ /a(1+ε)/, /b(1-ε)/ ]. (Note that there is sadly + no such thing as an open set in floating point arithmetic.) When does the difference + matter? Recall the stricture to never peel a high-dimensional orange, because + when you do, nothing is left. The same idea applied here. The fraction of the + volume within a distance ε of the boundary is approximately εd, + where d is the number of dimensions. If the number of + dimensions is large and the precision of the type is low, then it is possible + that no correct digits will be obtained. If the integrand is singular on the + boundary, you have no options; you simply must resort to higher precision computations. + If the integrand is not singular on the boundary, then you can tell this to + the integration routine via +

+
naive_monte_carlo<double, decltype(g)> mc(g, bounds, error_goal, /*singular = */ false);
+
+

+ and this problem will not be encountered. In practice, you will need ~1,000 + dimensions for this to be relevant in 16 bit floating point, ~100,000 dimensions + in 32 bit floating point, and an astronomical number of dimensions in double + precision. +

+

+ Finally, alternative random number generators may be provided to the class. + The default random number generator is the standard library std::mt19937_64. + However, here is an example which uses the 32-bit Mersenne twister random number + generator instead: +

+
naive_monte_carlo<Real, decltype(g), std::mt19937> mc(g, bounds, (Real) 0.001);
+
+
+ + + +
+
+
+PrevUpHomeNext +
+ + diff --git a/doc/html/math_toolkit/navigation.html b/doc/html/math_toolkit/navigation.html index 902f32da4..379847348 100644 --- a/doc/html/math_toolkit/navigation.html +++ b/doc/html/math_toolkit/navigation.html @@ -27,7 +27,7 @@ Navigation

- +

Boost.Math documentation is provided in both HTML and PDF formats. diff --git a/example/float_comparison_example.cpp b/example/float_comparison_example.cpp index ddb1324d8..f39e53781 100644 --- a/example/float_comparison_example.cpp +++ b/example/float_comparison_example.cpp @@ -40,7 +40,7 @@ int main() //[compare_floats_example_1 /*`The following examples display values with all possibly significant digits. -Newer compilers should provide `std::numeric_limitsFPT>::max_digits10` +Newer compilers should provide `std::numeric_limits::max_digits10` for this purpose, and here we use `float` precision where `max_digits10` = 9 to avoid displaying a distracting number of decimal digits.