Mercurial > hg > octave-nkf
annotate liboctave/numeric/randgamma.c @ 20685:7fa1970a655d
pkg.m: drop check of nargout value, the interpreter already does that.
* scripts/pkg/pkg.m: the interpreter already checks if there was any variable
that got no value assigned, there's no need to make the code more
complicated to cover that. Also, there's no point in calling describe()
with different nargout since it doesn't check nargout.
author | Carnë Draug <carandraug@octave.org> |
---|---|
date | Thu, 03 Sep 2015 16:21:08 +0100 |
parents | 4197fc428c7d |
children |
rev | line source |
---|---|
7019 | 1 /* |
2 | |
19898
4197fc428c7d
maint: Update copyright notices for 2015.
John W. Eaton <jwe@octave.org>
parents:
17769
diff
changeset
|
3 Copyright (C) 2006-2015 John W. Eaton |
7019 | 4 |
5 This file is part of Octave. | |
6 | |
7 Octave is free software; you can redistribute it and/or modify it | |
8 under the terms of the GNU General Public License as published by the | |
9 Free Software Foundation; either version 3 of the License, or (at your | |
10 option) any later version. | |
11 | |
12 Octave is distributed in the hope that it will be useful, but WITHOUT | |
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or | |
14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License | |
15 for more details. | |
16 | |
17 You should have received a copy of the GNU General Public License | |
18 along with Octave; see the file COPYING. If not, see | |
19 <http://www.gnu.org/licenses/>. | |
20 | |
21 */ | |
22 | |
23 /* Original version written by Paul Kienzle distributed as free | |
24 software in the in the public domain. */ | |
5742 | 25 |
26 /* | |
27 | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
28 double randg (a) |
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
29 void fill_randg (a,n,x) |
5742 | 30 |
31 Generate a series of standard gamma distributions. | |
32 | |
33 See: Marsaglia G and Tsang W (2000), "A simple method for generating | |
34 gamma variables", ACM Transactions on Mathematical Software 26(3) 363-372 | |
35 | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
36 Needs the following defines: |
5742 | 37 * NAN: value to return for Not-A-Number |
38 * RUNI: uniform generator on (0,1) | |
39 * RNOR: normal generator | |
40 * REXP: exponential generator, or -log(RUNI) if one isn't available | |
41 * INFINITE: function to test whether a value is infinite | |
42 | |
43 Test using: | |
44 mean = a | |
45 variance = a | |
46 skewness = 2/sqrt(a) | |
47 kurtosis = 3 + 6/sqrt(a) | |
48 | |
49 Note that randg can be used to generate many distributions: | |
50 | |
51 gamma(a,b) for a>0, b>0 (from R) | |
52 r = b*randg(a) | |
53 beta(a,b) for a>0, b>0 | |
54 r1 = randg(a,1) | |
55 r = r1 / (r1 + randg(b,1)) | |
56 Erlang(a,n) | |
57 r = a*randg(n) | |
58 chisq(df) for df>0 | |
59 r = 2*randg(df/2) | |
60 t(df) for 0<df<inf (use randn if df is infinite) | |
14846
460a3c6d8bf1
maint: Use Octave coding convention for cuddled parenthis in function calls with empty argument lists.
Rik <octave@nomad.inbox5.com>
parents:
14655
diff
changeset
|
61 r = randn () / sqrt(2*randg(df/2)/df) |
5742 | 62 F(n1,n2) for 0<n1, 0<n2 |
63 r1 = 2*randg(n1/2)/n1 or 1 if n1 is infinite | |
64 r2 = 2*randg(n2/2)/n2 or 1 if n2 is infinite | |
65 r = r1 / r2 | |
66 negative binonial (n, p) for n>0, 0<p<=1 | |
67 r = randp((1-p)/p * randg(n)) | |
68 (from R, citing Devroye(1986), Non-Uniform Random Variate Generation) | |
69 non-central chisq(df,L), for df>=0 and L>0 (use chisq if L=0) | |
70 r = randp(L/2) | |
71 r(r>0) = 2*randg(r(r>0)) | |
72 r(df>0) += 2*randg(df(df>0)/2) | |
73 (from R, citing formula 29.5b-c in Johnson, Kotz, Balkrishnan(1995)) | |
74 Dirichlet(a1,...,ak) for ai > 0 | |
75 r = (randg(a1),...,randg(ak)) | |
76 r = r / sum(r) | |
77 (from GSL, citing Law & Kelton(1991), Simulation Modeling and Analysis) | |
78 */ | |
79 | |
80 #if defined (HAVE_CONFIG_H) | |
81 #include <config.h> | |
82 #endif | |
83 | |
84 #include <stdio.h> | |
85 | |
86 #include "lo-ieee.h" | |
7231 | 87 #include "lo-math.h" |
5742 | 88 #include "randmtzig.h" |
89 #include "randgamma.h" | |
90 | |
91 #undef NAN | |
92 #define NAN octave_NaN | |
93 #define INFINITE lo_ieee_isinf | |
94 #define RUNI oct_randu() | |
95 #define RNOR oct_randn() | |
96 #define REXP oct_rande() | |
97 | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
98 void |
5742 | 99 oct_fill_randg (double a, octave_idx_type n, double *r) |
100 { | |
101 octave_idx_type i; | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
102 /* If a < 1, start by generating gamma (1+a) */ |
5742 | 103 const double d = (a < 1. ? 1.+a : a) - 1./3.; |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
104 const double c = 1./sqrt (9.*d); |
5742 | 105 |
106 /* Handle invalid cases */ | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
107 if (a <= 0 || INFINITE(a)) |
5742 | 108 { |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
109 for (i=0; i < n; i++) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
110 r[i] = NAN; |
5742 | 111 return; |
112 } | |
113 | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
114 for (i=0; i < n; i++) |
5742 | 115 { |
116 double x, xsq, v, u; | |
117 restart: | |
118 x = RNOR; | |
119 v = (1+c*x); | |
120 v *= v*v; | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
121 if (v <= 0) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
122 goto restart; /* rare, so don't bother moving up */ |
5742 | 123 u = RUNI; |
124 xsq = x*x; | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
125 if (u >= 1.-0.0331*xsq*xsq && log (u) >= 0.5*xsq + d*(1-v+log (v))) |
10317
42d098307c30
untabify additional source files
John W. Eaton <jwe@octave.org>
parents:
10158
diff
changeset
|
126 goto restart; |
5742 | 127 r[i] = d*v; |
128 } | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
129 if (a < 1) |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
130 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
131 /* Use gamma(a) = gamma(1+a)*U^(1/a) */ |
5742 | 132 /* Given REXP = -log(U) then U^(1/a) = exp(-REXP/a) */ |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
133 for (i = 0; i < n; i++) |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
134 r[i] *= exp (-REXP/a); |
5742 | 135 } |
136 } | |
137 | |
11586
12df7854fa7c
strip trailing whitespace from source files
John W. Eaton <jwe@octave.org>
parents:
11523
diff
changeset
|
138 double |
5742 | 139 oct_randg (double a) |
140 { | |
141 double ret; | |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
142 oct_fill_randg (a,1,&ret); |
5742 | 143 return ret; |
144 } | |
14655
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
145 |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
146 #undef NAN |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
147 #undef RUNI |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
148 #undef RNOR |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
149 #undef REXP |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
150 #define NAN octave_Float_NaN |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
151 #define RUNI oct_float_randu() |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
152 #define RNOR oct_float_randn() |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
153 #define REXP oct_float_rande() |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
154 |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
155 void |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
156 oct_fill_float_randg (float a, octave_idx_type n, float *r) |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
157 { |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
158 octave_idx_type i; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
159 /* If a < 1, start by generating gamma(1+a) */ |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
160 const float d = (a < 1. ? 1.+a : a) - 1./3.; |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
161 const float c = 1./sqrt (9.*d); |
14655
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
162 |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
163 /* Handle invalid cases */ |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
164 if (a <= 0 || INFINITE(a)) |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
165 { |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
166 for (i=0; i < n; i++) |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
167 r[i] = NAN; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
168 return; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
169 } |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
170 |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
171 for (i=0; i < n; i++) |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
172 { |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
173 float x, xsq, v, u; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
174 frestart: |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
175 x = RNOR; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
176 v = (1+c*x); |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
177 v *= v*v; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
178 if (v <= 0) |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
179 goto frestart; /* rare, so don't bother moving up */ |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
180 u = RUNI; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
181 xsq = x*x; |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
182 if (u >= 1.-0.0331*xsq*xsq && log (u) >= 0.5*xsq + d*(1-v+log (v))) |
14655
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
183 goto frestart; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
184 r[i] = d*v; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
185 } |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
186 if (a < 1) |
17769
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
187 { |
49a5a4be04a1
maint: Use GNU style coding conventions for code in liboctave/
Rik <rik@octave.org>
parents:
17744
diff
changeset
|
188 /* Use gamma(a) = gamma(1+a)*U^(1/a) */ |
14655
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
189 /* Given REXP = -log(U) then U^(1/a) = exp(-REXP/a) */ |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
190 for (i = 0; i < n; i++) |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
191 r[i] *= exp (-REXP/a); |
14655
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
192 } |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
193 } |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
194 |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
195 float |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
196 oct_float_randg (float a) |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
197 { |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
198 float ret; |
15018
3d8ace26c5b4
maint: Use Octave coding conventions for cuddled parentheses in liboctave/.
Rik <rik@octave.org>
parents:
14846
diff
changeset
|
199 oct_fill_float_randg (a,1,&ret); |
14655
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
200 return ret; |
43db83eff9db
Implement single precision rand, randn, rande, randg and randp generators (bug #34351, #36293)
David Bateman <dbateman@free.fr>
parents:
14138
diff
changeset
|
201 } |