]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
1 | [section:high_precision Using Boost.Math with High-Precision Floating-Point Libraries] |
2 | ||
3 | The special functions, distributions, constants and tools in this library | |
4 | can be used with a number of high-precision libraries, including: | |
5 | ||
6 | * __multiprecision | |
7 | * __e_float | |
8 | * __NTL | |
9 | * __GMP | |
10 | * __MPFR | |
11 | * __float128 | |
12 | ||
13 | The last four have some license restrictions; | |
14 | only __multiprecision when using the `cpp_float` backend | |
15 | can provide an unrestricted [@http://www.boost.org/LICENSE_1_0.txt Boost] license. | |
16 | ||
17 | At present, the price of a free license is slightly lower speed. | |
18 | ||
19 | Of course, the main cost of higher precision is very much decreased | |
20 | (usually at least hundred-fold) computation speed, and big increases in memory use. | |
21 | ||
22 | Some libraries offer true | |
23 | [@http://en.wikipedia.org/wiki/Arbitrary-precision_arithmetic arbitrary-precision arithmetic] | |
24 | where the precision is limited only by available memory and compute time, but most are used | |
25 | at some arbitrarily-fixed precision, say 100 decimal digits, like __multiprecision `cpp_dec_float_100`. | |
26 | ||
27 | __multiprecision can operate in both ways, but the most popular choice is likely to be about a hundred | |
28 | decimal digits, though examples of computing about a million digits have been demonstrated. | |
29 | ||
30 | [section:why_high_precision Why use a high-precision library rather than built-in floating-point types?] | |
31 | ||
32 | For nearly all applications, the built-in floating-point types, `double` | |
33 | (and `long double` if this offers higher precision than `double`) | |
34 | offer enough precision, typically a dozen decimal digits. | |
35 | ||
36 | Some reasons why one would want to use a higher precision: | |
37 | ||
38 | * A much more precise result (many more digits) is just a requirement. | |
39 | * The range of the computed value exceeds the range of the type: factorials are the textbook example. | |
40 | * Using `double` is (or may be) too inaccurate. | |
41 | * Using `long double` (or may be) is too inaccurate. | |
42 | * Using an extended-precision type implemented in software as | |
43 | [@http://en.wikipedia.org/wiki/Double-double_(arithmetic)#Double-double_arithmetic double-double] | |
44 | ([@http://en.wikipedia.org/wiki/Darwin_(operating_system) Darwin]) is sometimes unpredictably inaccurate. | |
45 | * Loss of precision or inaccuracy caused by extreme arguments or cancellation error. | |
46 | * An accuracy as good as possible for a chosen built-in floating-point type is required. | |
47 | * As a reference value, for example, to determine the inaccuracy | |
48 | of a value computed with a built-in floating point type, | |
49 | (perhaps even using some quick'n'dirty algorithm). | |
50 | The accuracy of many functions and distributions in Boost.Math has been measured in this way | |
51 | from tables of very high precision (up to 1000 decimal digits). | |
52 | ||
53 | Many functions and distributions have differences from exact values | |
54 | that are only a few least significant bits - computation noise. | |
55 | Others, often those for which analytical solutions are not available, | |
56 | require approximations and iteration: | |
57 | these may lose several decimal digits of precision. | |
58 | ||
59 | Much larger loss of precision can occur for [@http://en.wikipedia.org/wiki/Boundary_case boundary] | |
60 | or [@http://en.wikipedia.org/wiki/Corner_case corner cases], | |
61 | often caused by [@http://en.wikipedia.org/wiki/Loss_of_significance cancellation errors]. | |
62 | ||
63 | (Some of the worst and most common examples of | |
64 | [@http://en.wikipedia.org/wiki/Loss_of_significance cancellation error or loss of significance] | |
65 | can be avoided by using __complements: see __why_complements). | |
66 | ||
67 | If you require a value which is as accurate as can be represented in the floating-point type, | |
68 | and is thus the closest representable value and has an error less than 1/2 a | |
69 | [@http://en.wikipedia.org/wiki/Least_significant_bit least significant bit] or | |
70 | [@http://en.wikipedia.org/wiki/Unit_in_the_last_place ulp] | |
71 | it may be useful to use a higher-precision type, | |
72 | for example, `cpp_dec_float_50`, to generate this value. | |
73 | Conversion of this value to a built-in floating-point type ('float', `double` or `long double`) | |
74 | will not cause any further loss of precision. | |
75 | A decimal digit string will also be 'read' precisely by the compiler | |
76 | into a built-in floating-point type to the nearest representable value. | |
77 | ||
78 | [note In contrast, reading a value from an `std::istream` into a built-in floating-point type | |
79 | is [*not guaranteed by the C++ Standard] to give the nearest representable value.] | |
80 | ||
81 | William Kahan coined the term | |
82 | [@http://en.wikipedia.org/wiki/Rounding#The_table-maker.27s_dilemma Table-Maker's Dilemma] | |
83 | for the problem of correctly rounding functions. | |
84 | Using a much higher precision (50 or 100 decimal digits) | |
85 | is a practical way of generating (almost always) correctly rounded values. | |
86 | ||
87 | [endsect] [/section:why_high_precision Why use a high-precision library rather than built-in floating-point types?] | |
88 | ||
89 | [section:use_multiprecision Using Boost.Multiprecision] | |
90 | ||
91 | [*All new projects are recommended to use __multiprecision.] | |
92 | ||
93 | [import ../../example/big_seventh.cpp] | |
94 | ||
95 | [big_seventh_example_1] | |
96 | ||
97 | [import ../../example/fft_sines_table.cpp] | |
98 | ||
99 | [fft_sines_table_example_1] | |
100 | ||
101 | The table output is: | |
102 | ||
103 | [fft_sines_table_example_output] | |
104 | ||
105 | [fft_sines_table_example_check] | |
106 | ||
107 | ||
108 | [/TODO another example needed here] | |
109 | ||
110 | [/import ../../example/ibeta_mp_example.cpp] | |
111 | ||
112 | [/ibeta_mp_example_1] | |
113 | ||
114 | [/The program output is:] | |
115 | ||
116 | [/ibeta_mp_output_1] | |
117 | ||
118 | [endsect] [/section:use_multiprecision Using Boost.Multiprecision] | |
119 | ||
120 | [section:float128 Using with GCC's __float128 datatype] | |
121 | ||
122 | At present support for GCC's native `__float128` datatype is extremely limited: the numeric constants | |
123 | will all work with that type, and that's about it. If you want to use the distributions or special | |
124 | functions then you will need to provide your own wrapper header that: | |
125 | ||
126 | * Provides std::numeric_limits<__float128> support. | |
127 | * Provides overloads of the standard library math function for type `__float128`and which forward to the libquadmath equivalents. | |
128 | ||
129 | Ultimately these facilities should be provided by GCC and `libstdc++`. | |
130 | ||
131 | [endsect] | |
132 | ||
133 | [section:use_mpfr Using With MPFR or GMP - High-Precision Floating-Point Library] | |
134 | ||
135 | The special functions and tools in this library can be used with | |
136 | [@http://www.mpfr.org MPFR] (an arbitrary precision number type based on the __GMP), | |
137 | either via the bindings in [@../../../../boost/math/bindings/mpfr.hpp boost/math/bindings/mpfr.hpp], | |
138 | or via [@../../../../boost/math/bindings/mpfr.hpp boost/math/bindings/mpreal.hpp]. | |
139 | ||
140 | [*New projects are recommended to use __multiprecision with GMP/MPFR backend instead.] | |
141 | ||
142 | In order to use these bindings you will need to have installed [@http://www.mpfr.org MPFR] | |
143 | plus its dependency the [@http://gmplib.org GMP library]. You will also need one of the | |
144 | two supported C++ wrappers for MPFR: | |
145 | [@http://math.berkeley.edu/~wilken/code/gmpfrxx/ gmpfrxx (or mpfr_class)], | |
146 | or [@http://www.holoborodko.com/pavel/mpfr/ mpfr-C++ (mpreal)]. | |
147 | ||
148 | Unfortunately neither `mpfr_class` nor `mpreal` quite satisfy our conceptual requirements, | |
149 | so there is a very thin set of additional interfaces and some helper traits defined in | |
150 | [@../../../../boost/math/bindings/mpfr.hpp boost/math/bindings/mpfr.hpp] and | |
151 | [@../../../../boost/math/bindings/mpreal.hpp boost/math/bindings/mpreal.hpp] | |
152 | that you should use in place of including 'gmpfrxx.h' or 'mpreal.h' directly. | |
153 | The classes `mpfr_class` or `mpreal` are | |
154 | then usable unchanged once this header is included, so for example `mpfr_class`'s | |
155 | performance-enhancing expression templates are preserved and fully supported by this library: | |
156 | ||
157 | #include <boost/math/bindings/mpfr.hpp> | |
158 | #include <boost/math/special_functions/gamma.hpp> | |
159 | ||
160 | int main() | |
161 | { | |
162 | mpfr_class::set_dprec(500); // 500 bit precision | |
163 | // | |
164 | // Note that the argument to tgamma is | |
165 | // an expression template - that's just fine here. | |
166 | // | |
167 | mpfr_class v = boost::math::tgamma(sqrt(mpfr_class(2))); | |
168 | std::cout << std::setprecision(50) << v << std::endl; | |
169 | } | |
170 | ||
171 | Alternatively use with `mpreal` would look like: | |
172 | ||
173 | #include <boost/math/bindings/mpreal.hpp> | |
174 | #include <boost/math/special_functions/gamma.hpp> | |
175 | ||
176 | int main() | |
177 | { | |
178 | mpfr::mpreal::set_precision(500); // 500 bit precision | |
179 | mpfr::mpreal v = boost::math::tgamma(sqrt(mpfr::mpreal(2))); | |
180 | std::cout << std::setprecision(50) << v << std::endl; | |
181 | } | |
182 | ||
183 | For those functions that are based upon the __lanczos, the bindings | |
184 | defines a series of approximations with up to 61 terms and accuracy | |
185 | up to approximately 3e-113. This therefore sets the upper limit for accuracy | |
186 | to the majority of functions defined this library when used with either `mpfr_class` or `mpreal`. | |
187 | ||
188 | There is a concept checking test program for mpfr support | |
189 | [@../../../../libs/math/test/mpfr_concept_check.cpp here] and | |
190 | [@../../../../libs/math/test/mpreal_concept_check.cpp here]. | |
191 | ||
192 | [endsect] [/section:use_mpfr Using With MPFR / GMP - a High-Precision Floating-Point Library] | |
193 | ||
194 | [section:e_float Using e_float Library] | |
195 | ||
196 | __multiprecision was a development from the __e_float library by Christopher Kormanyos. | |
197 | ||
198 | e_float can still be used with Boost.Math library via the header: | |
199 | ||
200 | <boost/math/bindings/e_float.hpp> | |
201 | ||
202 | And the type `boost::math::ef::e_float`: | |
203 | this type is a thin wrapper class around ::e_float which provides the necessary | |
204 | syntactic sugar to make everything "just work". | |
205 | ||
206 | There is also a concept checking test program for e_float support | |
207 | [@../../../../libs/math/test/e_float_concept_check.cpp here]. | |
208 | ||
209 | [*New projects are recommended to use __multiprecision with `cpp_float` backend instead.] | |
210 | ||
211 | [endsect] [/section:e_float Using e_float Library] | |
212 | ||
213 | [section:use_ntl Using NTL Library] | |
214 | ||
215 | [@http://shoup.net/ntl/doc/RR.txt NTL::RR] | |
216 | (an arbitrarily-fixed precision floating-point number type), | |
217 | can be used via the bindings in | |
218 | [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp]. | |
219 | For details, see [@http://shoup.net/ntl/ NTL: A Library for doing Number Theory by | |
220 | Victor Shoup]. | |
221 | ||
222 | [*New projects are recommended to use __multiprecision instead.] | |
223 | ||
224 | Unfortunately `NTL::RR` doesn't quite satisfy our conceptual requirements, | |
225 | so there is a very thin wrapper class `boost::math::ntl::RR` defined in | |
226 | [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp] that you | |
227 | should use in place of `NTL::RR`. The class is intended to be a drop-in | |
228 | replacement for the "real" NTL::RR that adds some syntactic sugar to keep | |
229 | this library happy, plus some of the standard library functions not implemented | |
230 | in NTL. | |
231 | ||
232 | For those functions that are based upon the __lanczos, the bindings | |
233 | defines a series of approximations with up to 61 terms and accuracy | |
234 | up to approximately 3e-113. This therefore sets the upper limit for accuracy | |
235 | to the majority of functions defined this library when used with `NTL::RR`. | |
236 | ||
237 | There is a concept checking test program for NTL support | |
238 | [@../../../../libs/math/test/ntl_concept_check.cpp here]. | |
239 | ||
240 | [endsect] [/section:use_ntl Using With NTL - a High-Precision Floating-Point Library] | |
241 | ||
242 | [section:using_test Using without expression templates for Boost.Test and others] | |
243 | ||
244 | As noted in the __multiprecision documentation, certain program constructs will not compile | |
245 | when using expression templates. One example that many users may encounter | |
246 | is Boost.Test (1.54 and earlier) when using macro BOOST_CHECK_CLOSE and BOOST_CHECK_CLOSE_FRACTION. | |
247 | ||
248 | If, for example, you wish to use any multiprecision type like `cpp_dec_float_50` | |
249 | in place of `double` to give more precision, | |
250 | you will need to override the default `boost::multiprecision::et_on` with | |
251 | `boost::multiprecision::et_off`. | |
252 | ||
253 | [import ../../example/test_cpp_float_close_fraction.cpp] | |
254 | ||
255 | [expression_template_1] | |
256 | ||
257 | A full example code is at [@../../example/test_cpp_float_close_fraction.cpp test_cpp_float_close_fraction.cpp] | |
258 | ||
259 | [endsect] [/section:using_test Using without expression templates for Boost.Test and others] | |
260 | [endsect] [/section:high_precision Using With High-Precision Floating-Point Libraries] | |
261 | ||
262 | [section:real_concepts Conceptual Requirements for Real Number Types] | |
263 | ||
264 | The functions and statistical distributions in this library can be used with | |
265 | any type ['RealType] that meets the conceptual requirements given below. All | |
266 | the built-in floating-point types like `double` will meet these requirements. | |
267 | (Built-in types are also called __fundamental_types). | |
268 | ||
269 | User-defined types that meet the conceptual requirements can also be used. | |
270 | For example, with [link math_toolkit.high_precision.use_ntl a thin wrapper class] | |
271 | one of the types provided with [@http://shoup.net/ntl/ NTL (RR)] can be used. | |
272 | But now that __multiprecision library is available, | |
273 | this has become the preferred real-number type, | |
274 | typically __cpp_dec_float or __cpp_bin_float. | |
275 | ||
276 | Submissions of binding to other extended precision types would also still be welcome. | |
277 | ||
278 | The guiding principal behind these requirements is that a ['RealType] | |
279 | behaves just like a built-in floating-point type. | |
280 | ||
281 | [h4 Basic Arithmetic Requirements] | |
282 | ||
283 | These requirements are common to all of the functions in this library. | |
284 | ||
285 | In the following table /r/ is an object of type `RealType`, /cr/ and | |
286 | /cr2/ are objects | |
287 | of type `const RealType`, and /ca/ is an object of type `const arithmetic-type` | |
288 | (arithmetic types include all the built in integers and floating point types). | |
289 | ||
290 | [table | |
291 | [[Expression][Result Type][Notes]] | |
292 | [[`RealType(cr)`][RealType] | |
293 | [RealType is copy constructible.]] | |
294 | [[`RealType(ca)`][RealType] | |
295 | [RealType is copy constructible from the arithmetic types.]] | |
296 | [[`r = cr`][RealType&][Assignment operator.]] | |
297 | [[`r = ca`][RealType&][Assignment operator from the arithmetic types.]] | |
298 | [[`r += cr`][RealType&][Adds cr to r.]] | |
299 | [[`r += ca`][RealType&][Adds ar to r.]] | |
300 | [[`r -= cr`][RealType&][Subtracts cr from r.]] | |
301 | [[`r -= ca`][RealType&][Subtracts ca from r.]] | |
302 | [[`r *= cr`][RealType&][Multiplies r by cr.]] | |
303 | [[`r *= ca`][RealType&][Multiplies r by ca.]] | |
304 | [[`r /= cr`][RealType&][Divides r by cr.]] | |
305 | [[`r /= ca`][RealType&][Divides r by ca.]] | |
306 | [[`-r`][RealType][Unary Negation.]] | |
307 | [[`+r`][RealType&][Identity Operation.]] | |
308 | [[`cr + cr2`][RealType][Binary Addition]] | |
309 | [[`cr + ca`][RealType][Binary Addition]] | |
310 | [[`ca + cr`][RealType][Binary Addition]] | |
311 | [[`cr - cr2`][RealType][Binary Subtraction]] | |
312 | [[`cr - ca`][RealType][Binary Subtraction]] | |
313 | [[`ca - cr`][RealType][Binary Subtraction]] | |
314 | [[`cr * cr2`][RealType][Binary Multiplication]] | |
315 | [[`cr * ca`][RealType][Binary Multiplication]] | |
316 | [[`ca * cr`][RealType][Binary Multiplication]] | |
317 | [[`cr / cr2`][RealType][Binary Subtraction]] | |
318 | [[`cr / ca`][RealType][Binary Subtraction]] | |
319 | [[`ca / cr`][RealType][Binary Subtraction]] | |
320 | [[`cr == cr2`][bool][Equality Comparison]] | |
321 | [[`cr == ca`][bool][Equality Comparison]] | |
322 | [[`ca == cr`][bool][Equality Comparison]] | |
323 | [[`cr != cr2`][bool][Inequality Comparison]] | |
324 | [[`cr != ca`][bool][Inequality Comparison]] | |
325 | [[`ca != cr`][bool][Inequality Comparison]] | |
326 | [[`cr <= cr2`][bool][Less than equal to.]] | |
327 | [[`cr <= ca`][bool][Less than equal to.]] | |
328 | [[`ca <= cr`][bool][Less than equal to.]] | |
329 | [[`cr >= cr2`][bool][Greater than equal to.]] | |
330 | [[`cr >= ca`][bool][Greater than equal to.]] | |
331 | [[`ca >= cr`][bool][Greater than equal to.]] | |
332 | [[`cr < cr2`][bool][Less than comparison.]] | |
333 | [[`cr < ca`][bool][Less than comparison.]] | |
334 | [[`ca < cr`][bool][Less than comparison.]] | |
335 | [[`cr > cr2`][bool][Greater than comparison.]] | |
336 | [[`cr > ca`][bool][Greater than comparison.]] | |
337 | [[`ca > cr`][bool][Greater than comparison.]] | |
338 | [[`boost::math::tools::digits<RealType>()`][int] | |
339 | [The number of digits in the significand of RealType.]] | |
340 | [[`boost::math::tools::max_value<RealType>()`][RealType] | |
341 | [The largest representable number by type RealType.]] | |
342 | [[`boost::math::tools::min_value<RealType>()`][RealType] | |
343 | [The smallest representable number by type RealType.]] | |
344 | [[`boost::math::tools::log_max_value<RealType>()`][RealType] | |
345 | [The natural logarithm of the largest representable number by type RealType.]] | |
346 | [[`boost::math::tools::log_min_value<RealType>()`][RealType] | |
347 | [The natural logarithm of the smallest representable number by type RealType.]] | |
348 | [[`boost::math::tools::epsilon<RealType>()`][RealType] | |
349 | [The machine epsilon of RealType.]] | |
350 | ] | |
351 | ||
352 | Note that: | |
353 | ||
354 | # The functions `log_max_value` and `log_min_value` can be | |
355 | synthesised from the others, and so no explicit specialisation is required. | |
356 | # The function `epsilon` can be synthesised from the others, so no | |
357 | explicit specialisation is required provided the precision | |
358 | of RealType does not vary at runtime (see the header | |
359 | [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp] | |
360 | for an example where the precision does vary at runtime). | |
361 | # The functions `digits`, `max_value` and `min_value`, all get synthesised | |
362 | automatically from `std::numeric_limits`. However, if `numeric_limits` | |
363 | is not specialised for type RealType, then you will get a compiler error | |
364 | when code tries to use these functions, /unless/ you explicitly specialise them. | |
365 | For example if the precision of RealType varies at runtime, then | |
366 | `numeric_limits` support may not be appropriate, see | |
367 | [@../../../../boost/math/bindings/rr.hpp boost/math/bindings/rr.hpp] for examples. | |
368 | ||
369 | [warning | |
370 | If `std::numeric_limits<>` is *not specialized* | |
371 | for type /RealType/ then the default float precision of 6 decimal digits | |
372 | will be used by other Boost programs including: | |
373 | ||
374 | Boost.Test: giving misleading error messages like | |
375 | ||
376 | ['"difference between {9.79796} and {9.79796} exceeds 5.42101e-19%".] | |
377 | ||
378 | Boost.LexicalCast and Boost.Serialization when converting the number | |
379 | to a string, causing potentially serious loss of accuracy on output. | |
380 | ||
381 | Although it might seem obvious that RealType should require `std::numeric_limits` | |
382 | to be specialized, this is not sensible for | |
383 | `NTL::RR` and similar classes where the [*number of digits is a runtime parameter] | |
384 | (whereas for `numeric_limits` everything has to be fixed at compile time). | |
385 | ] | |
386 | ||
387 | [h4 Standard Library Support Requirements] | |
388 | ||
389 | Many (though not all) of the functions in this library make calls | |
390 | to standard library functions, the following table summarises the | |
391 | requirements. Note that most of the functions in this library | |
392 | will only call a small subset of the functions listed here, so if in | |
393 | doubt whether a user-defined type has enough standard library | |
394 | support to be useable the best advise is to try it and see! | |
395 | ||
396 | In the following table /r/ is an object of type `RealType`, | |
397 | /cr1/ and /cr2/ are objects of type `const RealType`, and | |
398 | /i/ is an object of type `int`. | |
399 | ||
400 | [table | |
401 | [[Expression][Result Type]] | |
402 | [[`fabs(cr1)`][RealType]] | |
403 | [[`abs(cr1)`][RealType]] | |
404 | [[`ceil(cr1)`][RealType]] | |
405 | [[`floor(cr1)`][RealType]] | |
406 | [[`exp(cr1)`][RealType]] | |
407 | [[`pow(cr1, cr2)`][RealType]] | |
408 | [[`sqrt(cr1)`][RealType]] | |
409 | [[`log(cr1)`][RealType]] | |
410 | [[`frexp(cr1, &i)`][RealType]] | |
411 | [[`ldexp(cr1, i)`][RealType]] | |
412 | [[`cos(cr1)`][RealType]] | |
413 | [[`sin(cr1)`][RealType]] | |
414 | [[`asin(cr1)`][RealType]] | |
415 | [[`tan(cr1)`][RealType]] | |
416 | [[`atan(cr1)`][RealType]] | |
417 | [[`fmod(cr1)`][RealType]] | |
418 | [[`round(cr1)`][RealType]] | |
419 | [[`iround(cr1)`][int]] | |
420 | [[`trunc(cr1)`][RealType]] | |
421 | [[`itrunc(cr1)`][int]] | |
422 | ] | |
423 | ||
424 | Note that the table above lists only those standard library functions known to | |
425 | be used (or likely to be used in the near future) by this library. | |
426 | The following functions: `acos`, `atan2`, `fmod`, `cosh`, `sinh`, `tanh`, `log10`, | |
427 | `lround`, `llround`, `ltrunc`, `lltrunc` and `modf` | |
428 | are not currently used, but may be if further special functions are added. | |
429 | ||
430 | Note that the `round`, `trunc` and `modf` functions are not part of the | |
431 | current C++ standard: they are part of the additions added to C99 which will | |
432 | likely be in the next C++ standard. There are Boost versions of these provided | |
433 | as a backup, and the functions are always called unqualified so that | |
434 | argument-dependent-lookup can take place. | |
435 | ||
436 | In addition, for efficient and accurate results, a __lanczos is highly desirable. | |
437 | You may be able to adapt an existing approximation from | |
438 | [@../../../../boost/math/special_functions/lanczos.hpp | |
439 | boost/math/special_functions/lanczos.hpp] or | |
440 | [@../../../../boost/math/bindings/detail/big_lanczos.hpp | |
441 | boost/math/bindings/detail/big_lanczos.hpp]: | |
442 | in the former case you will need change | |
443 | `static_cast`'s to `lexical_cast`'s, and the constants to /strings/ | |
444 | (in order to ensure the coefficients aren't truncated to `long doubl`e) | |
445 | and then specialise `lanczos_traits` for type T. Otherwise you may have to hack | |
446 | [@../../tools/lanczos_generator.cpp | |
447 | libs/math/tools/lanczos_generator.cpp] to find a suitable | |
448 | approximation for your RealType. The code will still compile if you don't do | |
449 | this, but both accuracy and efficiency will be greatly compromised in any | |
450 | function that makes use of the gamma\/beta\/erf family of functions. | |
451 | ||
452 | [endsect] [/section:real_concepts Conceptual Requirements for Real Number Types] | |
453 | ||
454 | [section:dist_concept Conceptual Requirements for Distribution Types] | |
455 | ||
456 | A ['DistributionType] is a type that implements the following conceptual | |
457 | requirements, and encapsulates a statistical distribution. | |
458 | ||
459 | Please note that this documentation should not be used as a substitute | |
460 | for the | |
461 | [link math_toolkit.dist_ref reference documentation], and | |
462 | [link math_toolkit.stat_tut tutorial] of the statistical | |
463 | distributions. | |
464 | ||
465 | In the following table, ['d] is an object of type `DistributionType`, | |
466 | ['cd] is an object of type `const DistributionType` and ['cr] is an | |
467 | object of a type convertible to `RealType`. | |
468 | ||
469 | [table | |
470 | [[Expression][Result Type][Notes]] | |
471 | [[DistributionType::value_type][RealType] | |
472 | [The real-number type /RealType/ upon which the distribution operates.]] | |
473 | [[DistributionType::policy_type][RealType] | |
474 | [The __Policy to use when evaluating functions that depend on this distribution.]] | |
475 | [[d = cd][Distribution&][Distribution types are assignable.]] | |
476 | [[Distribution(cd)][Distribution][Distribution types are copy constructible.]] | |
477 | [[pdf(cd, cr)][RealType][Returns the PDF of the distribution.]] | |
478 | [[cdf(cd, cr)][RealType][Returns the CDF of the distribution.]] | |
479 | [[cdf(complement(cd, cr))][RealType] | |
480 | [Returns the complement of the CDF of the distribution, | |
481 | the same as: `1-cdf(cd, cr)`]] | |
482 | [[quantile(cd, cr)][RealType][Returns the quantile (or percentile) of the distribution.]] | |
483 | [[quantile(complement(cd, cr))][RealType] | |
484 | [Returns the quantile (or percentile) of the distribution, starting from | |
485 | the complement of the probability, the same as: `quantile(cd, 1-cr)`]] | |
486 | [[chf(cd, cr)][RealType][Returns the cumulative hazard function of the distribution.]] | |
487 | [[hazard(cd, cr)][RealType][Returns the hazard function of the distribution.]] | |
488 | [[kurtosis(cd)][RealType][Returns the kurtosis of the distribution.]] | |
489 | [[kurtosis_excess(cd)][RealType][Returns the kurtosis excess of the distribution.]] | |
490 | [[mean(cd)][RealType][Returns the mean of the distribution.]] | |
491 | [[mode(cd)][RealType][Returns the mode of the distribution.]] | |
492 | [[skewness(cd)][RealType][Returns the skewness of the distribution.]] | |
493 | [[standard_deviation(cd)][RealType][Returns the standard deviation of the distribution.]] | |
494 | [[variance(cd)][RealType][Returns the variance of the distribution.]] | |
495 | ] | |
496 | ||
497 | [endsect] [/ section:dist_concept Conceptual Requirements for Distribution Types] | |
498 | ||
499 | [section:archetypes Conceptual Archetypes for Reals and Distributions] | |
500 | ||
501 | There are a few concept archetypes available: | |
502 | ||
503 | * Real concept for floating-point types. | |
504 | * Distribution concept for statistical distributions. | |
505 | ||
506 | [h5:real_concept Real concept] | |
507 | ||
508 | `std_real_concept` is an archetype for theReal types, | |
509 | including the built-in float, double, long double. | |
510 | ||
511 | ``#include <boost/concepts/std_real_concept.hpp>`` | |
512 | ||
513 | namespace boost{ | |
514 | namespace math{ | |
515 | namespace concepts | |
516 | { | |
517 | class std_real_concept; | |
518 | } | |
519 | }} // namespaces | |
520 | ||
521 | ||
522 | The main purpose in providing this type is to verify | |
523 | that standard library functions are found via a using declaration - | |
524 | bringing those functions into the current scope - | |
525 | and not just because they happen to be in global scope. | |
526 | ||
527 | In order to ensure that a call to say `pow` can be found | |
528 | either via argument dependent lookup, or failing that then | |
529 | in the std namespace: all calls to standard library functions | |
530 | are unqualified, with the std:: versions found via a `using` declaration | |
531 | to make them visible in the current scope. Unfortunately it's all | |
532 | to easy to forget the `using` declaration, and call the double version of | |
533 | the function that happens to be in the global scope by mistake. | |
534 | ||
535 | For example if the code calls ::pow rather than std::pow, | |
536 | the code will cleanly compile, but truncation of long doubles to | |
537 | double will cause a significant loss of precision. | |
538 | In contrast a template instantiated with std_real_concept will *only* | |
539 | compile if the all the standard library functions used have | |
540 | been brought into the current scope with a using declaration. | |
541 | ||
542 | [h6 Testing the real concept] | |
543 | ||
544 | There is a test program | |
545 | [@../../test/std_real_concept_check.cpp libs/math/test/std_real_concept_check.cpp] | |
546 | that instantiates every template in this library with type | |
547 | `std_real_concept` to verify its usage of standard library functions. | |
548 | ||
549 | ``#include <boost/math/concepts/real_concept.hpp>`` | |
550 | ||
551 | namespace boost{ | |
552 | namespace math{ | |
553 | namespace concepts{ | |
554 | ||
555 | class real_concept; | |
556 | ||
557 | }}} // namespaces | |
558 | ||
559 | `real_concept` is an archetype for | |
560 | [link math_toolkit.real_concepts user defined real types], | |
561 | it declares its standard library functions in its own | |
562 | namespace: these will only be found if they are called unqualified | |
563 | allowing argument dependent lookup to locate them. In addition | |
564 | this type is useable at runtime: | |
565 | this allows code that would not otherwise be exercised by the built-in | |
566 | floating point types to be tested. There is no std::numeric_limits<> | |
567 | support for this type, since numeric_limits is not a conceptual requirement | |
568 | for [link math_toolkit.real_concepts RealType]s. | |
569 | ||
570 | NTL RR is an example of a type meeting the requirements that this type | |
571 | models, but note that use of a thin wrapper class is required: refer to | |
572 | [link math_toolkit.high_precision.use_ntl "Using With NTL - a High-Precision Floating-Point Library"]. | |
573 | ||
574 | There is no specific test case for type `real_concept`, instead, since this | |
575 | type is usable at runtime, each individual test case as well as testing | |
576 | `float`, `double` and `long double`, also tests `real_concept`. | |
577 | ||
578 | [h6:distribution_concept Distribution Concept] | |
579 | ||
580 | Distribution Concept models statistical distributions. | |
581 | ||
582 | ``#include <boost/math/concepts/distribution.hpp>`` | |
583 | ||
584 | namespace boost{ | |
585 | namespace math{ | |
586 | namespace concepts | |
587 | { | |
588 | template <class RealType> | |
589 | class distribution_archetype; | |
590 | ||
591 | template <class Distribution> | |
592 | struct DistributionConcept; | |
593 | ||
594 | }}} // namespaces | |
595 | ||
596 | The class template `distribution_archetype` is a model of the | |
597 | [link math_toolkit.dist_concept Distribution concept]. | |
598 | ||
599 | The class template `DistributionConcept` is a | |
600 | [@../../../../libs/concept_check/index.html concept checking class] | |
601 | for distribution types. | |
602 | ||
603 | [h6 Testing the distribution concept] | |
604 | ||
605 | The test program | |
606 | [@../../test/compile_test/distribution_concept_check.cpp distribution_concept_check.cpp] | |
607 | is responsible for using `DistributionConcept` to verify that all the | |
608 | distributions in this library conform to the | |
609 | [link math_toolkit.dist_concept Distribution concept]. | |
610 | ||
611 | The class template `DistributionConcept` verifies the existence | |
612 | (but not proper function) of the non-member accessors | |
613 | required by the [link math_toolkit.dist_concept Distribution concept]. | |
614 | These are checked by calls like | |
615 | ||
616 | v = pdf(dist, x); // (Result v is ignored). | |
617 | ||
618 | And in addition, those that accept two arguments do the right thing when the | |
619 | arguments are of different types (the result type is always the same as the | |
620 | distribution's value_type). (This is implemented by some additional | |
621 | forwarding-functions in derived_accessors.hpp, so that there is no need for | |
622 | any code changes. Likewise boilerplate versions of the | |
623 | hazard\/chf\/coefficient_of_variation functions are implemented in | |
624 | there too.) | |
625 | ||
626 | [endsect] [/section:archetypes Conceptual Archetypes for Reals and Distributions] | |
627 | [/ | |
628 | Copyright 2006, 2010, 2012 John Maddock and Paul A. Bristow. | |
629 | Distributed under the Boost Software License, Version 1.0. | |
630 | (See accompanying file LICENSE_1_0.txt or copy at | |
631 | http://www.boost.org/LICENSE_1_0.txt). | |
632 | ] | |
633 | ||
634 | ||
635 | ||
636 |