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