1 /*************************************************************************** 2 * Copyright (c) Johan Mabille, Sylvain Corlay and Wolf Vollprecht * 3 * Copyright (c) QuantStack * 4 * * 5 * Distributed under the terms of the BSD 3-Clause License. * 6 * * 7 * The full license is in the file LICENSE, distributed with this software. * 8 ****************************************************************************/ 9 10 #include <type_traits> 11 12 #include "test_common_macros.hpp" 13 #include "test_common_macros.hpp" 14 #if (defined(__GNUC__) && !defined(__clang__)) 15 #pragma GCC diagnostic push 16 #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" 17 #include "xtensor/xrandom.hpp" 18 #pragma GCC diagnostic pop 19 #else 20 #include "xtensor/xrandom.hpp" 21 #endif 22 #include "xtensor/xarray.hpp" 23 #include "xtensor/xview.hpp" 24 #include "xtensor/xset_operation.hpp" 25 26 namespace xt 27 { TEST(xrandom,random)28 TEST(xrandom, random) 29 { 30 auto r = random::rand<double>({3, 3}); 31 xarray<double> a = r; 32 xarray<double> b = r; 33 xarray<double> c = r; 34 35 ASSERT_NE(a(0, 0), a(0, 1)); 36 ASSERT_NE(a, b); 37 ASSERT_NE(a, c); 38 39 xarray<double> other_rand = random::rand<double>({3, 3}); 40 ASSERT_NE(a, other_rand); 41 42 random::seed(0); 43 auto same_d_a = random::rand<double>({3, 3}); 44 xarray<double> same_a = same_d_a; 45 46 random::seed(0); 47 auto same_d_b = random::rand<double>({3, 3}); 48 xarray<double> same_b = same_d_b; 49 50 ASSERT_EQ(same_a, same_b); 51 52 // check that it compiles and generates same random numbers for the same seed 53 random::seed(0); 54 xarray<int> q = random::randint<int>({3, 3}); 55 random::seed(0); 56 xarray<int> same_q = random::randint<int>({3, 3}); 57 ASSERT_EQ(q, same_q); 58 59 random::seed(0); 60 xarray<int> binom = random::binomial<int>({3, 3}); 61 random::seed(0); 62 xarray<int> same_binom = random::binomial<int>({3, 3}); 63 ASSERT_EQ(binom, same_binom); 64 65 random::seed(0); 66 xarray<int> geom = random::geometric<int>({3, 3}); 67 random::seed(0); 68 xarray<int> same_geom = random::geometric<int>({3, 3}); 69 ASSERT_EQ(geom, same_geom); 70 71 random::seed(0); 72 xarray<int> neg_binom = random::negative_binomial<int>({3, 3}); 73 random::seed(0); 74 xarray<int> same_neg_binom = random::negative_binomial<int>({3, 3}); 75 ASSERT_EQ(neg_binom, same_neg_binom); 76 77 random::seed(0); 78 xarray<int> poisson = random::poisson<int>({3, 3}); 79 random::seed(0); 80 xarray<int> same_poisson = random::poisson<int>({3, 3}); 81 ASSERT_EQ(poisson, same_poisson); 82 83 random::seed(0); 84 xarray<double> exp = random::exponential<double>({3, 3}); 85 random::seed(0); 86 xarray<double> same_exp = random::exponential<double>({3, 3}); 87 ASSERT_EQ(exp, same_exp); 88 89 random::seed(0); 90 xarray<double> gamma = random::gamma<double>({3, 3}); 91 random::seed(0); 92 xarray<double> same_gamma = random::gamma<double>({3, 3}); 93 ASSERT_EQ(gamma, same_gamma); 94 95 random::seed(0); 96 xarray<double> weibull = random::weibull<double>({3, 3}); 97 random::seed(0); 98 xarray<double> same_weibull = random::weibull<double>({3, 3}); 99 ASSERT_EQ(weibull, same_weibull); 100 101 random::seed(0); 102 xarray<double> extreme_val = random::extreme_value<double>({3, 3}); 103 random::seed(0); 104 xarray<double> same_extreme_val = random::extreme_value<double>({3, 3}); 105 ASSERT_EQ(extreme_val, same_extreme_val); 106 107 random::seed(0); 108 xarray<double> lnormal = random::lognormal<double>({3, 3}); 109 random::seed(0); 110 xarray<double> same_lnormal = random::lognormal<double>({3, 3}); 111 ASSERT_EQ(lnormal, same_lnormal); 112 113 random::seed(0); 114 xarray<double> xsqr = random::chi_squared<double>({3, 3}); 115 random::seed(0); 116 xarray<double> same_xsqr = random::chi_squared<double>({3, 3}); 117 ASSERT_EQ(xsqr, same_xsqr); 118 119 random::seed(0); 120 xarray<double> cauchy = random::cauchy<double>({3, 3}); 121 random::seed(0); 122 xarray<double> same_cauchy = random::cauchy<double>({3, 3}); 123 ASSERT_EQ(cauchy, same_cauchy); 124 125 random::seed(0); 126 xarray<double> fisher_f = random::fisher_f<double>({3, 3}); 127 random::seed(0); 128 xarray<double> same_fisher_f = random::fisher_f<double>({3, 3}); 129 ASSERT_EQ(fisher_f, same_fisher_f); 130 131 random::seed(0); 132 xarray<double> student_t = random::student_t<double>({3, 3}); 133 random::seed(0); 134 xarray<double> same_student_t = random::student_t<double>({3, 3}); 135 ASSERT_EQ(student_t, same_student_t); 136 137 // checking if internal state needs reset 138 auto n_dist = random::randn<double>({3, 3}); 139 xarray<double> p1 = n_dist; 140 xarray<double> p2 = n_dist; 141 xarray<double> p3 = n_dist; 142 ASSERT_NE(p1, p2); 143 ASSERT_NE(p1, p3); 144 } 145 TEST(xrandom,choice)146 TEST(xrandom, choice) 147 { 148 xarray<double> a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 149 xt::random::seed(42); 150 auto ac1 = xt::random::choice(a, 5, false); 151 auto ac2 = xt::random::choice(a, 5, false); 152 xt::random::seed(42); 153 auto ac3 = xt::random::choice(a, 5, false); 154 ASSERT_EQ(ac1, ac3); 155 ASSERT_NE(ac1, ac2); 156 157 xt::random::seed(42); 158 auto acr1 = xt::random::choice(a, 5, true); 159 auto acr2 = xt::random::choice(a, 5, true); 160 xt::random::seed(42); 161 auto acr3 = xt::random::choice(a, 5, true); 162 ASSERT_EQ(acr1, acr3); 163 ASSERT_NE(acr1, acr2); 164 } 165 TEST(xrandom,weighted_choice)166 TEST(xrandom, weighted_choice) 167 { 168 xarray<int> a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 169 xarray<double> w = {1, 0, 2, 0, 1, 0, 1, 0, 2, 0, 1, 0}; 170 171 for(bool replace : {true, false}) { 172 xt::random::seed(42); 173 auto ac1 = xt::random::choice(a, 6, w, replace); 174 auto ac2 = xt::random::choice(a, 6, w, replace); 175 xt::random::seed(42); 176 auto ac3 = xt::random::choice(a, 6, w, replace); 177 static_assert(std::is_same<decltype(a)::value_type, decltype(ac1)::value_type>::value, 178 "Elements must be same type"); 179 ASSERT_EQ(ac1, ac3); 180 ASSERT_NE(ac1, ac2); 181 ASSERT_TRUE(all(isin(ac1, a))); 182 ASSERT_TRUE(all(equal(ac1 % 2, 1))); 183 } 184 } 185 TEST(xrandom,shuffle)186 TEST(xrandom, shuffle) 187 { 188 xarray<double> a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 189 xt::random::shuffle(a); 190 EXPECT_FALSE(std::is_sorted(a.begin(), a.end())); 191 192 xarray<double> b = a; 193 b.resize({b.size(), 1}); 194 xt::random::seed(42); 195 xt::random::shuffle(a); 196 xt::random::seed(42); 197 xt::random::shuffle(b); 198 b.resize({b.size()}); 199 EXPECT_EQ(a, b); 200 201 a = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12}; 202 a.reshape({3, 4}); 203 auto ar = a; 204 205 xt::random::seed(123); 206 // Unfortunately MSVC, OS X, and Clang on Linux seem to produce different 207 // shuffles even though the generated integer sequence should be the same ... 208 #if defined(__linux__) && (!defined(__clang__) || (__clang_major__ < 11)) 209 xt::random::shuffle(a); 210 EXPECT_EQ(xt::view(ar, keep(0, 1, 2)), a); 211 xt::random::shuffle(a); 212 EXPECT_EQ(xt::view(ar, keep(1, 2, 0)), a); 213 xt::random::shuffle(a); 214 EXPECT_EQ(xt::view(ar, keep(0, 2, 1)), a); 215 xt::random::shuffle(a); 216 EXPECT_EQ(xt::view(ar, keep(0, 1, 2)), a); 217 xt::random::shuffle(a); 218 EXPECT_EQ(xt::view(ar, keep(1, 0, 2)), a); 219 xt::random::shuffle(a); 220 EXPECT_EQ(xt::view(ar, keep(1, 2, 0)), a); 221 xt::random::shuffle(a); 222 EXPECT_EQ(xt::view(ar, keep(2, 1, 0)), a); 223 xt::random::shuffle(a); 224 xt::random::shuffle(a); 225 xt::random::shuffle(a); 226 xt::random::shuffle(a); 227 xt::random::shuffle(a); 228 xt::random::shuffle(a); 229 EXPECT_EQ(xt::view(ar, keep(0, 2, 1)), a); 230 #else 231 xt::random::shuffle(a); 232 xt::random::shuffle(a); 233 EXPECT_FALSE(std::is_sorted(a.begin(), a.end())); 234 #endif 235 236 } 237 TEST(xrandom,permutation)238 TEST(xrandom, permutation) 239 { 240 xt::random::seed(123); 241 auto r1 = xt::random::permutation(12); 242 xt::random::seed(123); 243 xtensor<int, 1> a1 = arange<int>(12); 244 xtensor<int, 1> ac1 = a1; 245 xt::random::shuffle(a1); 246 EXPECT_EQ(a1, r1); 247 EXPECT_NE(r1, ac1); 248 249 xt::random::seed(123); 250 auto r2 = xt::random::permutation(ac1); 251 EXPECT_EQ(a1, r2); 252 } 253 } 254