• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 exponential_distribution
15 
16 // template<class _URNG> result_type operator()(_URNG& g);
17 
18 #include <random>
19 #include <cassert>
20 #include <vector>
21 #include <numeric>
22 #include <cstddef>
23 
24 #include "test_macros.h"
25 
26 template <class T>
27 inline
28 T
sqr(T x)29 sqr(T x)
30 {
31     return x * x;
32 }
33 
main(int,char **)34 int main(int, char**)
35 {
36     {
37         typedef std::exponential_distribution<> D;
38         typedef std::mt19937 G;
39         G g;
40         D d(.75);
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(d.min() < v);
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 (std::size_t 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(var);
63         skew /= u.size() * dev * var;
64         kurtosis /= u.size() * var * var;
65         kurtosis -= 3;
66         double x_mean = 1/d.lambda();
67         double x_var = 1/sqr(d.lambda());
68         double x_skew = 2;
69         double x_kurtosis = 6;
70         assert(std::abs((mean - x_mean) / x_mean) < 0.01);
71         assert(std::abs((var - x_var) / x_var) < 0.01);
72         assert(std::abs((skew - x_skew) / x_skew) < 0.01);
73         assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
74     }
75     {
76         typedef std::exponential_distribution<> D;
77         typedef std::mt19937 G;
78         G g;
79         D d(1);
80         const int N = 1000000;
81         std::vector<D::result_type> u;
82         for (int i = 0; i < N; ++i)
83         {
84             D::result_type v = d(g);
85             assert(d.min() < v);
86             u.push_back(v);
87         }
88         double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
89         double var = 0;
90         double skew = 0;
91         double kurtosis = 0;
92         for (std::size_t i = 0; i < u.size(); ++i)
93         {
94             double dbl = (u[i] - mean);
95             double d2 = sqr(dbl);
96             var += d2;
97             skew += dbl * d2;
98             kurtosis += d2 * d2;
99         }
100         var /= u.size();
101         double dev = std::sqrt(var);
102         skew /= u.size() * dev * var;
103         kurtosis /= u.size() * var * var;
104         kurtosis -= 3;
105         double x_mean = 1/d.lambda();
106         double x_var = 1/sqr(d.lambda());
107         double x_skew = 2;
108         double x_kurtosis = 6;
109         assert(std::abs((mean - x_mean) / x_mean) < 0.01);
110         assert(std::abs((var - x_var) / x_var) < 0.01);
111         assert(std::abs((skew - x_skew) / x_skew) < 0.01);
112         assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
113     }
114     {
115         typedef std::exponential_distribution<> D;
116         typedef std::mt19937 G;
117         G g;
118         D d(10);
119         const int N = 1000000;
120         std::vector<D::result_type> u;
121         for (int i = 0; i < N; ++i)
122         {
123             D::result_type v = d(g);
124             assert(d.min() < v);
125             u.push_back(v);
126         }
127         double mean = std::accumulate(u.begin(), u.end(), 0.0) / u.size();
128         double var = 0;
129         double skew = 0;
130         double kurtosis = 0;
131         for (std::size_t i = 0; i < u.size(); ++i)
132         {
133             double dbl = (u[i] - mean);
134             double d2 = sqr(dbl);
135             var += d2;
136             skew += dbl * d2;
137             kurtosis += d2 * d2;
138         }
139         var /= u.size();
140         double dev = std::sqrt(var);
141         skew /= u.size() * dev * var;
142         kurtosis /= u.size() * var * var;
143         kurtosis -= 3;
144         double x_mean = 1/d.lambda();
145         double x_var = 1/sqr(d.lambda());
146         double x_skew = 2;
147         double x_kurtosis = 6;
148         assert(std::abs((mean - x_mean) / x_mean) < 0.01);
149         assert(std::abs((var - x_var) / x_var) < 0.01);
150         assert(std::abs((skew - x_skew) / x_skew) < 0.01);
151         assert(std::abs((kurtosis - x_kurtosis) / x_kurtosis) < 0.01);
152     }
153 
154   return 0;
155 }
156