| 144 | |
| 145 | template<typename T> |
| 146 | bool testRandomEngineNormalChi2(randomEngineType type) |
| 147 | |
| 148 | { |
| 149 | af::dtype ty = (af::dtype)af::dtype_traits<T>::af_type; |
| 150 | |
| 151 | int elem = 256 * 1024 * 1024; |
| 152 | int steps = 64; // 256 * 32; |
| 153 | int bins = 100; |
| 154 | |
| 155 | T lower_edge(-7.0); |
| 156 | T upper_edge(7.0); |
| 157 | |
| 158 | array total_hist = af::constant(0.0, 2 * bins, f32); |
| 159 | array edges = af::seq(bins + 1) / bins * lower_edge; |
| 160 | array expected = -af::diff1(cnd(edges)); |
| 161 | |
| 162 | expected = |
| 163 | af::join(0, expected(af::seq(bins - 1, 0, -1)), expected).as(f32); |
| 164 | |
| 165 | af::randomEngine r(type, 0); |
| 166 | |
| 167 | // NOTE(@rstub): In the chi^2 test one computes the test statistic and |
| 168 | // compares the value with the chi^2 distribution with appropriate number of |
| 169 | // degrees of freedom. For the uniform distribution one has "number of bins |
| 170 | // minus 1" degrees of freedom. For the normal distribution it is "number of |
| 171 | // bins minus 3", since there are two parameters mu and sigma. Here I used |
| 172 | // the qchisq() function from R to compute "suitable" values from the chi^2 |
| 173 | // distribution. |
| 174 | // |
| 175 | // R> qchisq(c(5e-6, 1 - 5e-6), 197) |
| 176 | // [1] 121.3197 297.2989 |
| 177 | float lower(121.3197); |
| 178 | float upper(297.2989); |
| 179 | |
| 180 | bool prev_step = true; |
| 181 | bool prev_total = true; |
| 182 | |
| 183 | af::setSeed(0x76fa214467690e3c); |
| 184 | |
| 185 | // std::cout << std::setw(4) << "step" << std::setw(7) << "chi2_i" |
| 186 | // << std::setw(7) << "chi2_t" << std::setprecision(2) << |
| 187 | // std::fixed |
| 188 | // << std::endl; |
| 189 | |
| 190 | for (int i = 0; i < steps; ++i) { |
| 191 | array rn_numbers = randn(elem, ty, r); |
| 192 | array step_hist = |
| 193 | af::histogram(rn_numbers, 2 * bins, lower_edge, upper_edge); |
| 194 | step_hist = step_hist.as(f32); |
| 195 | |
| 196 | float step_chi2 = chi2_statistic<float>(step_hist, expected); |
| 197 | |
| 198 | // if (step_chi2 > 10000) af_print(rn_numbers); |
| 199 | // std::cout << std::setprecision(2) << std::fixed << std::setw(4) << i |
| 200 | // << std::setw(9) << step_chi2; |
| 201 | |
| 202 | bool step = step_chi2 > lower && step_chi2 < upper; |
| 203 | |