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

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