[RISCV] Fix mgather -> riscv.masked.strided.load combine not extending indices (...
[llvm-project.git] / libcxx / test / std / numerics / rand / rand.dist / rand.dist.pois / rand.dist.pois.poisson / eval.pass.cpp
blob5feb2e58022916a1ec8c0bbce0450bf70c2e0186
1 //===----------------------------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // REQUIRES: long_tests
11 // <random>
13 // template<class IntType = int>
14 // class poisson_distribution
16 // template<class _URNG> result_type operator()(_URNG& g);
18 #include <cassert>
19 #include <cmath>
20 #include <cstdint>
21 #include <limits>
22 #include <numeric>
23 #include <random>
24 #include <vector>
26 #include "test_macros.h"
28 template <class T>
29 T sqr(T x) {
30 return x * x;
33 void test_bad_ranges() {
34 // Test cases where the mean is around the largest representable integer for
35 // `result_type`. These cases don't generate valid poisson distributions, but
36 // at least they don't blow up.
37 std::mt19937 eng;
40 std::poisson_distribution<std::int16_t> distribution(32710.9);
41 for (int i=0; i < 1000; ++i) {
42 volatile std::int16_t res = distribution(eng);
43 ((void)res);
47 std::poisson_distribution<std::int16_t> distribution(std::numeric_limits<std::int16_t>::max());
48 for (int i=0; i < 1000; ++i) {
49 volatile std::int16_t res = distribution(eng);
50 ((void)res);
54 std::poisson_distribution<std::int16_t> distribution(
55 static_cast<double>(std::numeric_limits<std::int16_t>::max()) + 10);
56 for (int i=0; i < 1000; ++i) {
57 volatile std::int16_t res = distribution(eng);
58 ((void)res);
62 std::poisson_distribution<std::int16_t> distribution(
63 static_cast<double>(std::numeric_limits<std::int16_t>::max()) * 2);
64 for (int i=0; i < 1000; ++i) {
65 volatile std::int16_t res = distribution(eng);
66 ((void)res);
70 // We convert `INF` to `DBL_MAX` otherwise the distribution will hang.
71 std::poisson_distribution<std::int16_t> distribution(std::numeric_limits<double>::infinity());
72 for (int i=0; i < 1000; ++i) {
73 volatile std::int16_t res = distribution(eng);
74 ((void)res);
78 std::poisson_distribution<std::int16_t> distribution(0);
79 for (int i=0; i < 1000; ++i) {
80 volatile std::int16_t res = distribution(eng);
81 ((void)res);
85 // We convert `INF` to `DBL_MAX` otherwise the distribution will hang.
86 std::poisson_distribution<std::int16_t> distribution(-100);
87 for (int i=0; i < 1000; ++i) {
88 volatile std::int16_t res = distribution(eng);
89 ((void)res);
94 template <class T>
95 void tests() {
97 typedef std::poisson_distribution<T> D;
98 typedef std::minstd_rand G;
99 G g;
100 D d(2);
101 const int N = 100000;
102 std::vector<double> u;
103 for (int i = 0; i < N; ++i)
105 typename D::result_type v = d(g);
106 assert(d.min() <= v && v <= d.max());
107 u.push_back(v);
109 double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
110 double var = 0;
111 double skew = 0;
112 double kurtosis = 0;
113 for (unsigned i = 0; i < u.size(); ++i)
115 double dbl = (u[i] - mean);
116 double d2 = sqr(dbl);
117 var += d2;
118 skew += dbl * d2;
119 kurtosis += d2 * d2;
121 var /= u.size();
122 double dev = std::sqrt(var);
123 skew /= u.size() * dev * var;
124 kurtosis /= u.size() * var * var;
125 kurtosis -= 3;
126 double x_mean = d.mean();
127 double x_var = d.mean();
128 double x_skew = 1 / std::sqrt(x_var);
129 double x_kurtosis = 1 / x_var;
130 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
131 assert(std::abs((var - x_var) / x_var) < 0.01);
132 assert(std::abs((skew - x_skew) / x_skew) < 0.01);
133 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.03);
136 typedef std::poisson_distribution<T> D;
137 typedef std::minstd_rand G;
138 G g;
139 D d(0.75);
140 const int N = 100000;
141 std::vector<double> u;
142 for (int i = 0; i < N; ++i)
144 typename D::result_type v = d(g);
145 assert(d.min() <= v && v <= d.max());
146 u.push_back(v);
148 double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
149 double var = 0;
150 double skew = 0;
151 double kurtosis = 0;
152 for (unsigned i = 0; i < u.size(); ++i)
154 double dbl = (u[i] - mean);
155 double d2 = sqr(dbl);
156 var += d2;
157 skew += dbl * d2;
158 kurtosis += d2 * d2;
160 var /= u.size();
161 double dev = std::sqrt(var);
162 skew /= u.size() * dev * var;
163 kurtosis /= u.size() * var * var;
164 kurtosis -= 3;
165 double x_mean = d.mean();
166 double x_var = d.mean();
167 double x_skew = 1 / std::sqrt(x_var);
168 double x_kurtosis = 1 / x_var;
169 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
170 assert(std::abs((var - x_var) / x_var) < 0.01);
171 assert(std::abs((skew - x_skew) / x_skew) < 0.01);
172 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.04);
175 typedef std::poisson_distribution<T> D;
176 typedef std::mt19937 G;
177 G g;
178 D d(20);
179 const int N = 1000000;
180 std::vector<double> u;
181 for (int i = 0; i < N; ++i)
183 typename D::result_type v = d(g);
184 assert(d.min() <= v && v <= d.max());
185 u.push_back(v);
187 double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
188 double var = 0;
189 double skew = 0;
190 double kurtosis = 0;
191 for (unsigned i = 0; i < u.size(); ++i)
193 double dbl = (u[i] - mean);
194 double d2 = sqr(dbl);
195 var += d2;
196 skew += dbl * d2;
197 kurtosis += d2 * d2;
199 var /= u.size();
200 double dev = std::sqrt(var);
201 skew /= u.size() * dev * var;
202 kurtosis /= u.size() * var * var;
203 kurtosis -= 3;
204 double x_mean = d.mean();
205 double x_var = d.mean();
206 double x_skew = 1 / std::sqrt(x_var);
207 double x_kurtosis = 1 / x_var;
208 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
209 assert(std::abs((var - x_var) / x_var) < 0.01);
210 assert(std::abs((skew - x_skew) / x_skew) < 0.01);
211 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
215 int main(int, char**) {
216 test_bad_ranges();
218 tests<short>();
219 tests<int>();
220 tests<long>();
221 tests<long long>();
223 tests<unsigned short>();
224 tests<unsigned int>();
225 tests<unsigned long>();
226 tests<unsigned long long>();
228 #if defined(_LIBCPP_VERSION) // extension
229 // TODO: std::poisson_distribution currently doesn't work reliably with small types.
230 // tests<int8_t>();
231 // tests<uint8_t>();
232 #if !defined(TEST_HAS_NO_INT128)
233 tests<__int128_t>();
234 tests<__uint128_t>();
235 #endif
236 #endif
238 return 0;