root/trunk/special-functions/gamma.lisp

Revision 47, 11.1 kB (checked in by lhealy, 8 months ago)

Unification of errors and warnings using a single class
'gsl-condition. Each numbered GSL conditions is a subclass of this
condition, under the name given by GSL, e.g. 'EDOM.

  • Property svn:keywords set to Id
Line 
1;; Gamma functions
2;; Liam Healy, Thu Apr 27 2006 - 22:06
3;; Time-stamp: <2008-03-27 21:29:36EDT gamma.lisp>
4;; $Id$
5
6(in-package :gsl)
7
8;;; Need to handle incoming gsl-complex numbers correctly for log-gamma-complex.
9;;; Should functions returning sf-result and something else return the
10;;; error at the end?
11
12;;;;****************************************************************************
13;;;; Gamma functions
14;;;;****************************************************************************
15
16(defconstant +gamma-xmax+ 171.0d0)
17
18(defmfun gamma (x)
19  "gsl_sf_gamma_e" ((x :double) (ret sf-result))
20  :documentation                        ; FDL
21  "The Gamma function Gamma(x), subject to x
22   not being a negative integer.  The function is computed using the real
23   Lanczos method. The maximum value of x such that
24   Gamma(x) is not considered an overflow is given by +gamma-xmax+.")
25
26(defmfun log-gamma (x)
27  "gsl_sf_lngamma_e" ((x :double) (ret sf-result))
28  :documentation                        ; FDL
29  "The logarithm of the Gamma function,
30   log(Gamma(x)), subject to x not a being negative
31   integer.  For x<0 the real part of log(Gamma(x)) is
32   returned, which is equivalent to log(|Gamma(x)|).  The function
33   is computed using the real Lanczos method.")
34
35(defmfun log-gamma-sign (x)
36  "gsl_sf_lngamma_sgn_e" ((x :double) (ret sf-result) (sign :double))
37  :return ((val ret) (dcref sign) (err ret))
38  :documentation                        ; FDL
39  "Compute the sign of the gamma function and the logarithm of
40  its magnitude, subject to x not being a negative integer.  The
41  function is computed using the real Lanczos method.  The value of the
42  gamma function can be reconstructed using the relation Gamma(x) =
43  sgn * exp(resultlg)}.")
44
45(defmfun gamma* (x)
46  "gsl_sf_gammastar_e" ((x :double) (ret sf-result))
47  :documentation                        ; FDL
48  "The regulated Gamma Function Gamma^*(x)
49  for x > 0, given by
50  Gamma^*(x) = Gamma(x)/(sqrt{2\pi} x^{(x-1/2)} \exp(-x))
51            = (1 + {1 \over 12x} + ...)
52  for x to infinity.")
53
54(defmfun 1/gamma (x)
55  "gsl_sf_gammainv_e" ((x :double) (ret sf-result))
56  :documentation                        ; FDL
57  "The reciprocal of the gamma function,
58  1/\Gamma(x) using the real Lanczos method.")
59
60(defmfun log-gamma-complex (z)
61  "gsl_sf_lngamma_complex_e"
62  (((realpart z) :double) ((imagpart z) :double)
63   (lnr sf-result) (arg sf-result))
64  :documentation                        ; FDL
65  "Compute log(Gamma(z)) for complex z=z_r+i z_i
66  and z not a negative integer, using the complex Lanczos
67  method.  The returned parameters are lnr = log|\Gamma(z)| and
68  arg = arg(Gamma(z)) in (-pi,pi].  Note that the phase
69  part (arg) is not well-determined when |z| is very large,
70  due to inevitable roundoff in restricting to (-\pi,\pi].  This
71  will result in a :ELOSS error when it occurs.  The absolute
72  value part (lnr), however, never suffers from loss of precision."
73  :return
74  ((val lnr) (val arg) (err lnr) (err arg)))
75
76(defmfun taylor-coefficient (n x)
77  "gsl_sf_taylorcoeff_e" ((n :int) (x :double) (ret sf-result))
78  :documentation                        ; FDL
79  "Compute the Taylor coefficient x^n / n! for x >= 0, n >= 0.")
80
81(defmfun factorial (n)
82  "gsl_sf_fact_e" ((n size) (ret sf-result))
83  :documentation                        ; FDL
84  "The factorial n!, related to the Gamma function by n! = \Gamma(n+1).")
85
86(defmfun double-factorial (n)
87  "gsl_sf_doublefact_e" ((n size) (ret sf-result))
88  :documentation                        ; FDL
89  "The double factorial n!! = n(n-2)(n-4) \dots.")
90
91(defmfun log-factorial (n)
92  "gsl_sf_lnfact_e" ((n size) (ret sf-result))
93  :documentation                        ; FDL
94  "The logarithm of the factorial of n, log(n!).
95  The algorithm is faster than computing
96  ln(Gamma(n+1)) via #'log-gamma for n < 170, but defers for larger n.")
97
98(defmfun log-double-factorial (n)
99  "gsl_sf_lndoublefact_e" ((n size) (ret sf-result))
100  :documentation                        ; FDL
101  "Compute the logarithm of the double factorial of n, log(n!!).")
102
103(defmfun choose (n m)
104  "gsl_sf_choose_e" ((n size) (m size) (ret sf-result))
105  :documentation                        ; FDL
106  "The combinatorial factor (n choose m) = n!/(m!(n-m)!).")
107
108(defmfun log-choose (n m)
109  "gsl_sf_lnchoose_e" ((n size) (m size) (ret sf-result))
110  :documentation                        ; FDL
111  "The logarithm of (n choose m).  This is
112  equivalent to the sum log(n!) - log(m!) - log((n-m)!).")
113
114(defmfun pochammer (a x)
115  "gsl_sf_poch_e"  ((a :double) (x :double) (ret sf-result))
116  :documentation                        ; FDL
117  "The Pochhammer symbol (a)_x := Gamma(a +
118   x)/Gamma(a), subject to a and a+x not being negative
119   integers. The Pochhammer symbol is also known as the Apell symbol and
120   sometimes written as (a,x).")
121
122(defmfun log-pochammer (a x)
123  "gsl_sf_lnpoch_e" ((a :double) (x :double) (ret sf-result))
124  :documentation                        ; FDL
125  "The logarithm of the Pochhammer symbol,
126  log((a)_x) = log(Gamma(a + x)/Gamma(a)) for a > 0, a+x > 0.")
127
128(defmfun log-pochammer-sign (a x)
129  "gsl_sf_lnpoch_sgn_e"
130  ((a :double) (x :double) (ret sf-result) (sign :double))
131  :documentation                        ; FDL
132  "The logarithm of the Pochhammer symbol and its sign.
133  The computed parameters are result =
134  log(|(a)_x|) and sgn = sgn((a)_x) where (a)_x :=
135  Gamma(a + x)/Gamma(a), subject to a, a+x not being negative integers."
136  :return ((val ret) (dcref sign) (err ret)))
137
138(defmfun relative-pochammer (a x)
139  "gsl_sf_pochrel_e" ((a :double) (x :double) (ret sf-result))
140  :documentation                        ; FDL
141  "The relative Pochhammer symbol ((a)_x -
142  1)/x where (a)_x := Gamma(a + x)/Gamma(a)}.")
143
144(defmfun incomplete-gamma (a x)
145  "gsl_sf_gamma_inc_Q_e" ((a :double) (x :double) (ret sf-result))
146  :documentation                        ; FDL
147  "The normalized incomplete Gamma Function
148  Q(a,x) = 1/Gamma(a) \int_x^\infty dt t^{a-1} \exp(-t) for a > 0, x >= 0.")
149
150(defmfun complementary-incomplete-gamma (a x)
151  "gsl_sf_gamma_inc_P_e" ((a :double) (x :double) (ret sf-result))
152  :documentation                        ; FDL
153  "The complementary normalized incomplete Gamma Function
154  P(a,x) = 1/\Gamma(a) \int_0^x dt t^{a-1} \exp(-t)}
155  for a > 0, x >= 0.  Note that Abramowitz & Stegun
156  call P(a,x) the incomplete gamma function (section 6.5).")
157
158(defmfun nonnormalized-incomplete-gamma (a x)
159  "gsl_sf_gamma_inc_e" ((a :double) (x :double) (ret sf-result))
160  :documentation                        ; FDL
161  "The incomplete Gamma Function
162   Gamma(a,x), without the normalization factor
163   included in the previously defined functions:
164   Gamma(a,x) = \int_x^\infty dt t^{a-1} \exp(-t)
165   for a real and x >= 0.")
166
167(defmfun beta (a b)
168  "gsl_sf_beta_e" ((a :double) (b :double) (ret sf-result))
169  :documentation                        ; FDL
170  "The Beta Function, B(a,b) = Gamma(a)Gamma(b)/Gamma(a+b)} for a > 0, b > 0.")
171
172(defmfun log-beta (a b)
173  "gsl_sf_lnbeta_e" ((a :double) (b :double) (ret sf-result))
174  :documentation                        ; FDL
175  "The logarithm of the Beta Function, log(B(a,b)) for a > 0, b > 0.")
176
177(defmfun incomplete-beta (a b x)
178  "gsl_sf_beta_inc_e"
179  ((a :double) (b :double) (x :double) (ret sf-result))
180  :documentation                        ; FDL
181  "The normalized incomplete Beta function
182   B_x(a,b)/B(a,b) where
183   B_x(a,b) = \int_0^x t^{a-1} (1-t)^{b-1} dt
184   for a > 0, b > 0, and 0 <= x <= 1.")
185
186;;;;****************************************************************************
187;;;; Examples and unit test
188;;;;****************************************************************************
189
190#|
191(make-tests gamma
192  (gamma -1.0d0)
193  (gamma 6.0d0)
194  (log-gamma -100.0d0)
195  (log-gamma 100.0d0)
196  (log-gamma-sign 100.0d0)
197  (gamma* 24.0d0)
198  (1/gamma 8.0d0)
199  (log-gamma-complex #C(10.0d0 10.0d0))
200  (taylor-coefficient 12 3.0d0)
201  (factorial 12)
202  (double-factorial 12)
203  (log-factorial 199)
204  (log-double-factorial 199)
205  (choose 8 3)
206  (choose 3 8)
207  (log-choose 67 12)
208  (pochammer 3.0d0 2.0d0)
209  (log-pochammer 2.0d0 199.0d0)
210  (log-pochammer-sign 2.0d0 199.0d0)
211  (relative-pochammer 2.0d0 9.0d0)
212  (incomplete-gamma 2.0d0 2.0d0)
213  (complementary-incomplete-gamma 2.0d0 2.0d0)
214  (nonnormalized-incomplete-gamma 2.0d0 2.0d0)
215  (beta 5.50d0 1.0d0)
216  (log-beta 5.5d0 1.0d0)
217  (incomplete-beta 1.0d0 1.50d0 0.50d0))
218|#
219
220(LISP-UNIT:DEFINE-TEST GAMMA
221  (LISP-UNIT:ASSERT-ERROR 'GSL-CONDITION (GAMMA -1.0d0))
222  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
223   (LIST 120.0d0 2.6645352591003757d-14)
224   (MULTIPLE-VALUE-LIST (GAMMA 6.0d0)))
225  (LISP-UNIT:ASSERT-ERROR 'GSL-CONDITION (LOG-GAMMA -100.0d0))
226  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
227   (LIST 359.13420536957534d0 2.4544868717695813d-13)
228   (MULTIPLE-VALUE-LIST (LOG-GAMMA 100.0d0)))
229  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
230   (LIST 359.13420536957534d0 1.0d0
231         2.4544868717695813d-13)
232   (MULTIPLE-VALUE-LIST (LOG-GAMMA-SIGN 100.0d0)))
233  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
234   (LIST 1.0034780558311105d0 4.456337769159149d-16)
235   (MULTIPLE-VALUE-LIST (GAMMA* 24.0d0)))
236  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
237   (LIST 1.984126984126984d-4 1.3216940769347103d-19)
238   (MULTIPLE-VALUE-LIST (1/GAMMA 8.0d0)))
239  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
240   (LIST 8.236131750448724d0 -1.1840378149363078d0
241         7.315154482555574d-15 2.1796539969587586d-14)
242   (MULTIPLE-VALUE-LIST
243    (LOG-GAMMA-COMPLEX #C(10.0d0 10.0d0))))
244  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
245   (LIST 0.0011094764610389606d0 2.956239149580215d-18)
246   (MULTIPLE-VALUE-LIST (TAYLOR-COEFFICIENT 12 3.0d0)))
247  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
248   (LIST 4.790016d8 0.0d0)
249   (MULTIPLE-VALUE-LIST (FACTORIAL 12)))
250  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
251   (LIST 46080.0d0 0.0d0)
252   (MULTIPLE-VALUE-LIST (DOUBLE-FACTORIAL 12)))
253  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
254   (LIST 857.9336698258575d0 5.777158772429952d-13)
255   (MULTIPLE-VALUE-LIST (LOG-FACTORIAL 199)))
256  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
257   (LIST 430.17789358084747d0 1.9103736085528287d-13)
258   (MULTIPLE-VALUE-LIST (LOG-DOUBLE-FACTORIAL 199)))
259  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
260   (LIST 56.0d0 7.460698725481052d-14)
261   (MULTIPLE-VALUE-LIST (CHOOSE 8 3)))
262  (LISP-UNIT:ASSERT-ERROR 'GSL-CONDITION (CHOOSE 3 8))
263  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
264   (LIST 29.422274169864693d0 1.9338924605168215d-13)
265   (MULTIPLE-VALUE-LIST (LOG-CHOOSE 67 12)))
266  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
267   (LIST 12.0d0 6.927791673660977d-14)
268   (MULTIPLE-VALUE-LIST (POCHAMMER 3.0d0 2.0d0)))
269  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
270   (LIST 863.2319871924054d0 9.645972767118375d-13)
271   (MULTIPLE-VALUE-LIST (LOG-POCHAMMER 2.0d0 199.0d0)))
272  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
273   (LIST 863.2319871924054d0 1.0d0 9.645972767118375d-13)
274   (MULTIPLE-VALUE-LIST
275    (LOG-POCHAMMER-SIGN 2.0d0 199.0d0)))
276  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
277   (LIST 403199.88888888917d0 3.5998302729212807d-9)
278   (MULTIPLE-VALUE-LIST (RELATIVE-POCHAMMER 2.0d0 9.0d0)))
279  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
280   (LIST 0.40600584970983766d0 9.568405127077496d-16)
281   (MULTIPLE-VALUE-LIST (INCOMPLETE-GAMMA 2.0d0 2.0d0)))
282  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
283   (LIST 0.5939941502901611d0 3.510166705531295d-15)
284   (MULTIPLE-VALUE-LIST
285    (COMPLEMENTARY-INCOMPLETE-GAMMA 2.0d0 2.0d0)))
286  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
287   (LIST 0.40600584970983766d0 1.2272947381959672d-15)
288   (MULTIPLE-VALUE-LIST
289    (NONNORMALIZED-INCOMPLETE-GAMMA 2.0d0 2.0d0)))
290  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
291   (LIST 0.1818181818181818d0 1.0189782228738177d-15)
292   (MULTIPLE-VALUE-LIST (BETA 5.5d0 1.0d0)))
293  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
294   (LIST -1.7047480922384253d0 3.81791013808375d-15)
295   (MULTIPLE-VALUE-LIST (LOG-BETA 5.5d0 1.0d0)))
296  (LISP-UNIT::ASSERT-NUMERICAL-EQUAL
297   (LIST 0.6464466094067263d0 1.0178662453689468d-14)
298   (MULTIPLE-VALUE-LIST
299    (INCOMPLETE-BETA 1.0d0 1.5d0 0.5d0))))
Note: See TracBrowser for help on using the browser.