3 // Copyright (C) 2011-2018 Free Software Foundation, Inc.
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the terms
7 // of the GNU General Public License as published by the Free Software
8 // Foundation; either version 3, or (at your option) any later
11 // This library is distributed in the hope that it will be useful, but
12 // WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 // General Public License for more details.
16 // You should have received a copy of the GNU General Public License along
17 // with this library; see the file COPYING3. If not see
18 // <http://www.gnu.org/licenses/>.
21 * @file testsuite_random.h
24 #ifndef _GLIBCXX_TESTSUITE_RANDOM_H
25 #define _GLIBCXX_TESTSUITE_RANDOM_H
28 #include <initializer_list>
29 #include <testsuite_hooks.h>
33 // Adapted for libstdc++ from GNU gsl-1.14/randist/test.c
34 // Copyright (C) 1996, 1997, 1998, 1999, 2000, 2007, 2010
35 // James Theiler, Brian Gough
36 template<unsigned long BINS
= 100,
37 unsigned long N
= 100000,
38 typename Distribution
, typename Pdf
>
40 testDiscreteDist(Distribution
& f
, Pdf pdf
)
42 double count
[BINS
], p
[BINS
];
44 for (unsigned long i
= 0; i
< BINS
; i
++)
47 for (unsigned long i
= 0; i
< N
; i
++)
50 if (r
>= 0 && (unsigned long)r
< BINS
)
54 for (unsigned long i
= 0; i
< BINS
; i
++)
57 for (unsigned long i
= 0; i
< BINS
; i
++)
60 double d
= std::abs(count
[i
] - N
* p
[i
]);
64 double s
= d
/ std::sqrt(N
* p
[i
]);
65 status_i
= (s
> 5) && (d
> 1);
68 status_i
= (count
[i
] != 0);
75 bernoulli_pdf(int k
, double p
)
85 #ifdef _GLIBCXX_USE_C99_MATH_TR1
87 binomial_pdf(int k
, int n
, double p
)
96 q
= (k
== 0) ? 1.0 : 0.0;
98 q
= (k
== n
) ? 1.0 : 0.0;
101 double ln_Cnk
= (std::lgamma(n
+ 1.0) - std::lgamma(k
+ 1.0)
102 - std::lgamma(n
- k
+ 1.0));
103 q
= ln_Cnk
+ k
* std::log(p
) + (n
- k
) * std::log1p(-p
);
113 discrete_pdf(int k
, std::initializer_list
<double> wl
)
117 static std::initializer_list
<double> one
= { 1.0 };
121 if (k
< 0 || (std::size_t)k
>= wl
.size())
126 for (auto it
= wl
.begin(); it
!= wl
.end(); ++it
)
128 return wl
.begin()[k
] / sum
;
133 geometric_pdf(int k
, double p
)
140 return p
* std::pow(1 - p
, k
);
143 #ifdef _GLIBCXX_USE_C99_MATH_TR1
145 negative_binomial_pdf(int k
, int n
, double p
)
151 double f
= std::lgamma(k
+ (double)n
);
152 double a
= std::lgamma(n
);
153 double b
= std::lgamma(k
+ 1.0);
155 return std::exp(f
- a
- b
) * std::pow(p
, n
) * std::pow(1 - p
, k
);
160 poisson_pdf(int k
, double mu
)
166 double lf
= std::lgamma(k
+ 1.0);
167 return std::exp(std::log(mu
) * k
- lf
- mu
);
173 uniform_int_pdf(int k
, int a
, int b
)
175 if (k
< 0 || k
< a
|| k
> b
)
178 return 1.0 / (b
- a
+ 1.0);
181 #ifdef _GLIBCXX_USE_C99_MATH_TR1
183 lbincoef(int n
, int k
)
185 return std::lgamma(double(1 + n
))
186 - std::lgamma(double(1 + k
))
187 - std::lgamma(double(1 + n
- k
));
191 hypergeometric_pdf(int k
, int N
, int K
, int n
)
193 if (k
< 0 || k
< std::max(0, n
- (N
- K
)) || k
> std::min(K
, n
))
196 return lbincoef(K
, k
) + lbincoef(N
- K
, n
- k
) - lbincoef(N
, n
);
200 } // namespace __gnu_test
202 #endif // #ifndef _GLIBCXX_TESTSUITE_RANDOM_H