]> git.proxmox.com Git - ceph.git/blame - ceph/src/boost/libs/math/doc/sf/factorials.qbk
bump version to 12.2.2-pve1
[ceph.git] / ceph / src / boost / libs / math / doc / sf / factorials.qbk
CommitLineData
7c673cae
FG
1[section:factorials Factorials and Binomial Coefficients]
2
3[section:sf_factorial Factorial]
4
5[h4 Synopsis]
6
7``
8#include <boost/math/special_functions/factorials.hpp>
9``
10
11 namespace boost{ namespace math{
12
13 template <class T>
14 T factorial(unsigned i);
15
16 template <class T, class ``__Policy``>
17 T factorial(unsigned i, const ``__Policy``&);
18
19 template <class T>
20 T unchecked_factorial(unsigned i);
21
22 template <class T>
23 struct max_factorial;
24
25 }} // namespaces
26
27[h4 Description]
28
29[important
30The functions described below are templates where the template argument T CANNOT be deduced from the
31arguments passed to the function. Therefore if you write something like:
32
33 `boost::math::factorial(2);`
34
35You will get a (perhaps perplexing) compiler error, ususally indicating that there is no such function to be found.
36Instead you need to specify the return type explicity and write:
37
38 `boost::math::factorial<double>(2);`
39
40So that the return type is known.
41
42Furthermore, the template argument must be a real-valued type such as `float` or `double`
43and not an integer type - that would overflow far too easily for quite small values of parameter `i`!
44
45The source code `static_assert` and comment just after the will be:
46
47``
48 BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
49 // factorial<unsigned int>(n) is not implemented
50 // because it would overflow integral type T for too small n
51 // to be useful. Use instead a floating-point type,
52 // and convert to an unsigned type if essential, for example:
53 // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
54 // See factorial documentation for more detail.
55``
56]
57
58 template <class T>
59 T factorial(unsigned i);
60
61 template <class T, class ``__Policy``>
62 T factorial(unsigned i, const ``__Policy``&);
63
64Returns [^i!].
65
66[optional_policy]
67
68For [^i <= max_factorial<T>::value] this is implemented by table lookup,
69for larger values of [^i], this function is implemented in terms of __tgamma.
70
71If [^i] is so large that the result can not be represented in type T, then
72calls __overflow_error.
73
74 template <class T>
75 T unchecked_factorial(unsigned i);
76
77Returns [^i!].
78
79Internally this function performs table lookup of the result. Further it performs
80no range checking on the value of i: it is up to the caller to ensure
81that [^i <= max_factorial<T>::value]. This function is intended to be used
82inside inner loops that require fast table lookup of factorials, but requires
83care to ensure that argument [^i] never grows too large.
84
85 template <class T>
86 struct max_factorial
87 {
88 static const unsigned value = X;
89 };
90
91This traits class defines the largest value that can be passed to
92[^unchecked_factorial]. The member `value` can be used where integral
93constant expressions are required: for example to define the size of
94further tables that depend on the factorials.
95
96[h4 Accuracy]
97
98For arguments smaller than `max_factorial<T>::value`
99the result should be
100correctly rounded. For larger arguments the accuracy will be the same
101as for __tgamma.
102
103[h4 Testing]
104
105Basic sanity checks and spot values to verify the data tables:
106the main tests for the __tgamma function handle those cases already.
107
108[h4 Implementation]
109
110The factorial function is table driven for small arguments, and is
111implemented in terms of __tgamma for larger arguments.
112
113[endsect]
114
115[section:sf_double_factorial Double Factorial]
116
117``
118#include <boost/math/special_functions/factorials.hpp>
119``
120
121 namespace boost{ namespace math{
122
123 template <class T>
124 T double_factorial(unsigned i);
125
126 template <class T, class ``__Policy``>
127 T double_factorial(unsigned i, const ``__Policy``&);
128
129 }} // namespaces
130
131Returns [^i!!].
132
133[optional_policy]
134
135May return the result of __overflow_error if the result is too large
136to represent in type T. The implementation is designed to be optimised
137for small /i/ where table lookup of i! is possible.
138
139[important
140The functions described above are templates where the template argument T can not be deduced from the
141arguments passed to the function. Therefore if you write something like:
142
143 `boost::math::double_factorial(2);`
144
145You will get a (possibly perplexing) compiler error, ususally indicating that there is no such function to be found. Instead you need to specifiy
146the return type explicity and write:
147
148 `boost::math::double_factorial<double>(2);`
149
150So that the return type is known. Further, the template argument must be a real-valued type such as `float` or `double`
151and not an integer type - that would overflow far too easily!
152
153The source code `static_assert` and comment just after the will be:
154
155``
156 BOOST_STATIC_ASSERT(!boost::is_integral<T>::value);
157 // factorial<unsigned int>(n) is not implemented
158 // because it would overflow integral type T for too small n
159 // to be useful. Use instead a floating-point type,
160 // and convert to an unsigned type if essential, for example:
161 // unsigned int nfac = static_cast<unsigned int>(factorial<double>(n));
162 // See factorial documentation for more detail.
163``
164]
165
166[note The argument to `double_factorial` is type `unsigned` even though technically -1!! is defined.]
167
168[h4 Accuracy]
169
170The implementation uses a trivial adaptation of
171the factorial function, so error rates should be no more than a couple
172of epsilon higher.
173
174[h4 Testing]
175
176The spot tests for the double factorial use data
177generated by functions.wolfram.com.
178
179[h4 Implementation]
180
181The double factorial is implemented in terms of the factorial and gamma
182functions using the relations:
183
184(2n)!! = 2[super n ] * n!
185
186(2n+1)!! = (2n+1)! / (2[super n ] n!)
187
188and
189
190(2n-1)!! = [Gamma]((2n+1)/2) * 2[super n ] / sqrt(pi)
191
192[endsect]
193
194[section:sf_rising_factorial Rising Factorial]
195
196``
197#include <boost/math/special_functions/factorials.hpp>
198``
199
200 namespace boost{ namespace math{
201
202 template <class T>
203 ``__sf_result`` rising_factorial(T x, int i);
204
205 template <class T, class ``__Policy``>
206 ``__sf_result`` rising_factorial(T x, int i, const ``__Policy``&);
207
208 }} // namespaces
209
210Returns the rising factorial of /x/ and /i/:
211
212rising_factorial(x, i) = [Gamma](x + i) / [Gamma](x);
213
214or
215
216rising_factorial(x, i) = x(x+1)(x+2)(x+3)...(x+i-1)
217
218Note that both /x/ and /i/ can be negative as well as positive.
219
220[optional_policy]
221
222May return the result of __overflow_error if the result is too large
223to represent in type T.
224
225The return type of these functions is computed using the __arg_promotion_rules:
226the type of the result is `double` if T is an integer type, otherwise the type
227of the result is T.
228
229[h4 Accuracy]
230
231The accuracy will be the same as
232the __tgamma_delta_ratio function.
233
234[h4 Testing]
235
236The spot tests for the rising factorials use data generated
237by functions.wolfram.com.
238
239[h4 Implementation]
240
241Rising and falling factorials are implemented as ratios of gamma functions
242using __tgamma_delta_ratio. Optimisations for
243small integer arguments are handled internally by that function.
244
245[endsect]
246
247[section:sf_falling_factorial Falling Factorial]
248
249``
250#include <boost/math/special_functions/factorials.hpp>
251``
252
253 namespace boost{ namespace math{
254
255 template <class T>
256 ``__sf_result`` falling_factorial(T x, unsigned i);
257
258 template <class T, class ``__Policy``>
259 ``__sf_result`` falling_factorial(T x, unsigned i, const ``__Policy``&);
260
261 }} // namespaces
262
263Returns the falling factorial of /x/ and /i/:
264
265falling_factorial(x, i) = x(x-1)(x-2)(x-3)...(x-i+1)
266
267Note that this function is only defined for positive /i/, hence the
268`unsigned` second argument. Argument /x/ can be either positive or
269negative however.
270
271[optional_policy]
272
273May return the result of __overflow_error if the result is too large
274to represent in type T.
275
276The return type of these functions is computed using the __arg_promotion_rules:
277the type of the result is `double` if T is an integer type, otherwise the type
278of the result is T.
279
280[h4 Accuracy]
281
282The accuracy will be the same as
283the __tgamma_delta_ratio function.
284
285[h4 Testing]
286
287The spot tests for the falling factorials use data generated by
288functions.wolfram.com.
289
290[h4 Implementation]
291
292Rising and falling factorials are implemented as ratios of gamma functions
293using __tgamma_delta_ratio. Optimisations for
294small integer arguments are handled internally by that function.
295
296[endsect]
297
298[section:sf_binomial Binomial Coefficients]
299
300``
301#include <boost/math/special_functions/binomial.hpp>
302``
303
304 namespace boost{ namespace math{
305
306 template <class T>
307 T binomial_coefficient(unsigned n, unsigned k);
308
309 template <class T, class ``__Policy``>
310 T binomial_coefficient(unsigned n, unsigned k, const ``__Policy``&);
311
312 }} // namespaces
313
314Returns the binomial coefficient: [sub n]C[sub k].
315
316Requires k <= n.
317
318[optional_policy]
319
320May return the result of __overflow_error if the result is too large
321to represent in type T.
322
323[important
324The functions described above are templates where the template argument T can not be deduced from the
325arguments passed to the function. Therefore if you write something like:
326
327 `boost::math::binomial_coefficient(10, 2);`
328
329You will get a compiler error, ususally indicating that there is no such function to be found. Instead you need to specifiy
330the return type explicity and write:
331
332 `boost::math::binomial_coefficient<double>(10, 2);`
333
334So that the return type is known. Further, the template argument must be a real-valued type such as `float` or `double`
335and not an integer type - that would overflow far too easily!
336]
337
338[h4 Accuracy]
339
340The accuracy will be the same as for the
341factorials for small arguments (i.e. no more than one or two epsilon),
342and the __beta function for larger arguments.
343
344[h4 Testing]
345
346The spot tests for the binomial coefficients use data
347generated by functions.wolfram.com.
348
349[h4 Implementation]
350
351Binomial coefficients are calculated using table lookup of factorials
352where possible using:
353
354[sub n]C[sub k] = n! / (k!(n-k)!)
355
356Otherwise it is implemented in terms of the beta function using the relations:
357
358[sub n]C[sub k] = 1 / (k * __beta(k, n-k+1))
359
360and
361
362[sub n]C[sub k] = 1 / ((n-k) * __beta(k+1, n-k))
363
364[endsect]
365
366
367[endsect][/section:factorials Factorials]
368
369[/
370 Copyright 2006, 2010 John Maddock and Paul A. Bristow.
371 Distributed under the Boost Software License, Version 1.0.
372 (See accompanying file LICENSE_1_0.txt or copy at
373 http://www.boost.org/LICENSE_1_0.txt).
374]