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
10
11// <random>
12
13// template<class RealType = double>
14// class lognormal_distribution
15
16// template<class _URNG> result_type operator()(_URNG& g, const param_type& parm);
17
18#include <random>
19#include <cassert>
20#include <cmath>
21#include <numeric>
22#include <vector>
23
24#include "test_macros.h"
25
26template <class T>
27inline
28T
29sqr(T x)
30{
31 return x * x;
32}
33
34void
35test1()
36{
37 typedef std::lognormal_distribution<> D;
38 typedef D::param_type P;
39 typedef std::mt19937 G;
40 G g;
41 D d;
42 P p(-1./8192, 0.015625);
43 const int N = 1000000;
44 std::vector<D::result_type> u;
45 for (int i = 0; i < N; ++i)
46 {
47 D::result_type v = d(g, p);
48 assert(v > 0);
49 u.push_back(v);
50 }
51 double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
52 double var = 0;
53 double skew = 0;
54 double kurtosis = 0;
55 for (unsigned i = 0; i < u.size(); ++i)
56 {
57 double dbl = (u[i] - mean);
58 double d2 = sqr(dbl);
59 var += d2;
60 skew += dbl * d2;
61 kurtosis += d2 * d2;
62 }
63 var /= u.size();
64 double dev = std::sqrt(x: var);
65 skew /= u.size() * dev * var;
66 kurtosis /= u.size() * var * var;
67 kurtosis -= 3;
68 double x_mean = std::exp(p.m() + sqr(p.s())/2);
69 double x_var = (std::exp(sqr(p.s())) - 1) * std::exp(2*p.m() + sqr(p.s()));
70 double x_skew = (std::exp(sqr(p.s())) + 2) *
71 std::sqrt((std::exp(sqr(p.s())) - 1));
72 double x_kurtosis = std::exp(4*sqr(p.s())) + 2*std::exp(3*sqr(p.s())) +
73 3*std::exp(2*sqr(p.s())) - 6;
74 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
75 assert(std::abs((var - x_var) / x_var) < 0.01);
76 assert(std::abs((skew - x_skew) / x_skew) < 0.1);
77 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 1.9);
78}
79
80void
81test2()
82{
83 typedef std::lognormal_distribution<> D;
84 typedef D::param_type P;
85 typedef std::mt19937 G;
86 G g;
87 D d;
88 P p(-1./32, 0.25);
89 const int N = 1000000;
90 std::vector<D::result_type> u;
91 for (int i = 0; i < N; ++i)
92 {
93 D::result_type v = d(g, p);
94 assert(v > 0);
95 u.push_back(x: v);
96 }
97 double mean = std::accumulate(first: u.begin(), last: u.end(), init: 0.0) / u.size();
98 double var = 0;
99 double skew = 0;
100 double kurtosis = 0;
101 for (unsigned i = 0; i < u.size(); ++i)
102 {
103 double dbl = (u[i] - mean);
104 double d2 = sqr(x: dbl);
105 var += d2;
106 skew += dbl * d2;
107 kurtosis += d2 * d2;
108 }
109 var /= u.size();
110 double dev = std::sqrt(x: var);
111 skew /= u.size() * dev * var;
112 kurtosis /= u.size() * var * var;
113 kurtosis -= 3;
114 double x_mean = std::exp(x: p.m() + sqr(x: p.s())/2);
115 double x_var = (std::exp(x: sqr(x: p.s())) - 1) * std::exp(x: 2*p.m() + sqr(x: p.s()));
116 double x_skew = (std::exp(x: sqr(x: p.s())) + 2) *
117 std::sqrt(x: (std::exp(x: sqr(x: p.s())) - 1));
118 double x_kurtosis = std::exp(x: 4*sqr(x: p.s())) + 2*std::exp(x: 3*sqr(x: p.s())) +
119 3*std::exp(x: 2*sqr(x: p.s())) - 6;
120 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
121 assert(std::abs((var - x_var) / x_var) < 0.01);
122 assert(std::abs((skew - x_skew) / x_skew) < 0.01);
123 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.04);
124}
125
126void
127test3()
128{
129 typedef std::lognormal_distribution<> D;
130 typedef D::param_type P;
131 typedef std::mt19937 G;
132 G g;
133 D d;
134 P p(-1./8, 0.5);
135 const int N = 1000000;
136 std::vector<D::result_type> u;
137 for (int i = 0; i < N; ++i)
138 {
139 D::result_type v = d(g, p);
140 assert(v > 0);
141 u.push_back(x: v);
142 }
143 double mean = std::accumulate(first: u.begin(), last: u.end(), init: 0.0) / u.size();
144 double var = 0;
145 double skew = 0;
146 double kurtosis = 0;
147 for (unsigned i = 0; i < u.size(); ++i)
148 {
149 double dbl = (u[i] - mean);
150 double d2 = sqr(x: dbl);
151 var += d2;
152 skew += dbl * d2;
153 kurtosis += d2 * d2;
154 }
155 var /= u.size();
156 double dev = std::sqrt(x: var);
157 skew /= u.size() * dev * var;
158 kurtosis /= u.size() * var * var;
159 kurtosis -= 3;
160 double x_mean = std::exp(x: p.m() + sqr(x: p.s())/2);
161 double x_var = (std::exp(x: sqr(x: p.s())) - 1) * std::exp(x: 2*p.m() + sqr(x: p.s()));
162 double x_skew = (std::exp(x: sqr(x: p.s())) + 2) *
163 std::sqrt(x: (std::exp(x: sqr(x: p.s())) - 1));
164 double x_kurtosis = std::exp(x: 4*sqr(x: p.s())) + 2*std::exp(x: 3*sqr(x: p.s())) +
165 3*std::exp(x: 2*sqr(x: p.s())) - 6;
166 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
167 assert(std::abs((var - x_var) / x_var) < 0.01);
168 assert(std::abs((skew - x_skew) / x_skew) < 0.02);
169 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.06);
170}
171
172void
173test4()
174{
175 typedef std::lognormal_distribution<> D;
176 typedef D::param_type P;
177 typedef std::mt19937 G;
178 G g;
179 D d(3, 4);
180 P p;
181 const int N = 1000000;
182 std::vector<D::result_type> u;
183 for (int i = 0; i < N; ++i)
184 {
185 D::result_type v = d(g, p);
186 assert(v > 0);
187 u.push_back(x: v);
188 }
189 double mean = std::accumulate(first: u.begin(), last: u.end(), init: 0.0) / u.size();
190 double var = 0;
191 double skew = 0;
192 double kurtosis = 0;
193 for (unsigned i = 0; i < u.size(); ++i)
194 {
195 double dbl = (u[i] - mean);
196 double d2 = sqr(x: dbl);
197 var += d2;
198 skew += dbl * d2;
199 kurtosis += d2 * d2;
200 }
201 var /= u.size();
202 double dev = std::sqrt(x: var);
203 skew /= u.size() * dev * var;
204 kurtosis /= u.size() * var * var;
205 kurtosis -= 3;
206 double x_mean = std::exp(x: p.m() + sqr(x: p.s())/2);
207 double x_var = (std::exp(x: sqr(x: p.s())) - 1) * std::exp(x: 2*p.m() + sqr(x: p.s()));
208 double x_skew = (std::exp(x: sqr(x: p.s())) + 2) *
209 std::sqrt(x: (std::exp(x: sqr(x: p.s())) - 1));
210 double x_kurtosis = std::exp(x: 4*sqr(x: p.s())) + 2*std::exp(x: 3*sqr(x: p.s())) +
211 3*std::exp(x: 2*sqr(x: p.s())) - 6;
212 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
213 assert(std::abs((var - x_var) / x_var) < 0.02);
214 assert(std::abs((skew - x_skew) / x_skew) < 0.1);
215 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.5);
216}
217
218void
219test5()
220{
221 typedef std::lognormal_distribution<> D;
222 typedef D::param_type P;
223 typedef std::mt19937 G;
224 G g;
225 D d;
226 P p(-0.78125, 1.25);
227 const int N = 1000000;
228 std::vector<D::result_type> u;
229 for (int i = 0; i < N; ++i)
230 {
231 D::result_type v = d(g, p);
232 assert(v > 0);
233 u.push_back(x: v);
234 }
235 double mean = std::accumulate(first: u.begin(), last: u.end(), init: 0.0) / u.size();
236 double var = 0;
237 double skew = 0;
238 double kurtosis = 0;
239 for (unsigned i = 0; i < u.size(); ++i)
240 {
241 double dbl = (u[i] - mean);
242 double d2 = sqr(x: dbl);
243 var += d2;
244 skew += dbl * d2;
245 kurtosis += d2 * d2;
246 }
247 var /= u.size();
248 double dev = std::sqrt(x: var);
249 skew /= u.size() * dev * var;
250 kurtosis /= u.size() * var * var;
251 kurtosis -= 3;
252 double x_mean = std::exp(x: p.m() + sqr(x: p.s())/2);
253 double x_var = (std::exp(x: sqr(x: p.s())) - 1) * std::exp(x: 2*p.m() + sqr(x: p.s()));
254 double x_skew = (std::exp(x: sqr(x: p.s())) + 2) *
255 std::sqrt(x: (std::exp(x: sqr(x: p.s())) - 1));
256 double x_kurtosis = std::exp(x: 4*sqr(x: p.s())) + 2*std::exp(x: 3*sqr(x: p.s())) +
257 3*std::exp(x: 2*sqr(x: p.s())) - 6;
258 assert(std::abs((mean - x_mean) / x_mean) < 0.01);
259 assert(std::abs((var - x_var) / x_var) < 0.05);
260 assert(std::abs((skew - x_skew) / x_skew) < 0.3);
261 assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 1.0);
262}
263
264int main(int, char**)
265{
266 test1();
267 test2();
268 test3();
269 test4();
270 test5();
271
272 return 0;
273}
274

source code of libcxx/test/std/numerics/rand/rand.dist/rand.dist.norm/rand.dist.norm.lognormal/eval_param.pass.cpp