Changeset 92cb73f in mainline
- Timestamp:
- 2018-07-05T21:41:22Z (7 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- d2a66ae7
- Parents:
- a629655
- git-author:
- Dzejrou <dzejrou@…> (2018-05-03 17:51:00)
- git-committer:
- Dzejrou <dzejrou@…> (2018-07-05 21:41:22)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/cpp/include/impl/random.hpp
ra629655 r92cb73f 1149 1149 1150 1150 template<class RealType, size_t bits, class URNG> 1151 RealType generate_canonical(URNG& g); 1151 RealType generate_canonical(URNG& g) 1152 { 1153 auto b = (bits < numeric_limits<RealType>::digits) ? bits : numeric_limits<RealType>::digits; 1154 RealType r = g.max() - g.min() + 1; 1155 size_t tmp = aux::ceil(b / aux::log2(r)); 1156 size_t k = (1U < tmp) ? tmp : 1U; 1157 1158 RealType s{}; 1159 for (size_t i = 0; i < k; ++i) 1160 s += (g() - g.min()) * aux::pow(r, i); 1161 1162 return s / aux::pow(r, k); 1163 } 1152 1164 1153 1165 /** … … 1156 1168 1157 1169 template<class IntType = int> 1158 class uniform_int_distribution; 1170 class uniform_int_distribution 1171 { 1172 public: 1173 using result_type = IntType; 1174 using param_type = pair<result_type, result_type>; 1175 1176 explicit uniform_int_distribution(result_type a = 0, 1177 result_type b = numeric_limits<result_type>::max()) 1178 : a_{a}, b_{b} 1179 { /* DUMMY BODY */ } 1180 1181 explicit uniform_int_distribution(const param_type& p) 1182 : a_{p.first}, b_{p.second} 1183 { /* DUMMY BODY */ } 1184 1185 void reset() 1186 { /* DUMMY BODY */ } 1187 1188 template<class URNG> 1189 result_type operator()(URNG& g) 1190 { 1191 auto range = b_ - a_ + 1; 1192 1193 return g() % range + a_; 1194 } 1195 1196 template<class URNG> 1197 result_type operator()(URNG& g, const param_type& p) 1198 { 1199 auto range = p.second - p.first + 1; 1200 1201 return g() % range + p.first; 1202 } 1203 1204 result_type a() const 1205 { 1206 return a_; 1207 } 1208 1209 result_type b() const 1210 { 1211 return b_; 1212 } 1213 1214 param_type param() const 1215 { 1216 return param_type{a_, b_}; 1217 } 1218 1219 void param(const param_type& p) 1220 { 1221 a_ = p.first; 1222 b_ = p.second; 1223 } 1224 1225 result_type min() const 1226 { 1227 return a_; 1228 } 1229 1230 result_type max() const 1231 { 1232 return b_; 1233 } 1234 1235 bool operator==(const uniform_int_distribution& rhs) const 1236 { 1237 return a_ == rhs.a_ && b_ == rhs.b_; 1238 } 1239 1240 bool operator!=(const uniform_int_distribution& rhs) const 1241 { 1242 return !(*this == rhs); 1243 } 1244 1245 template<class Char, class Traits> 1246 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const 1247 { 1248 auto flags = os.flags(); 1249 os.flags(ios_base::dec | ios_base::left); 1250 1251 os << a_ << os.widen(' ') << b_; 1252 1253 os.flags(flags); 1254 return os; 1255 } 1256 1257 template<class Char, class Traits> 1258 basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const 1259 { 1260 auto flags = is.flags(); 1261 is.flags(ios_base::dec); 1262 1263 if (!(is >> a_) || !(is >> b_)) 1264 is.setstate(ios::failbit); 1265 1266 is.flags(flags); 1267 return is; 1268 } 1269 1270 private: 1271 result_type a_; 1272 result_type b_; 1273 }; 1159 1274 1160 1275 /** … … 1163 1278 1164 1279 template<class RealType = double> 1165 class uniform_real_distribution; 1280 class uniform_real_distribution 1281 { 1282 public: 1283 using result_type = RealType; 1284 using param_type = pair<result_type, result_type>; 1285 1286 explicit uniform_real_distribution(result_type a = 0.0, 1287 result_type b = 1.0) 1288 : a_{a}, b_{b} 1289 { /* DUMMY BODY */ } 1290 1291 explicit uniform_real_distribution(const param_type& p) 1292 : a_{p.first}, b_{p.second} 1293 { /* DUMMY BODY */ } 1294 1295 void reset() 1296 { /* DUMMY BODY */ } 1297 1298 template<class URNG> 1299 result_type operator()(URNG& g) 1300 { 1301 auto range = b_ - a_ + 1; 1302 1303 return generate_canonical< 1304 result_type, numeric_limits<result_type>::digits 1305 >(g) * range + a_; 1306 } 1307 1308 template<class URNG> 1309 result_type operator()(URNG& g, const param_type& p) 1310 { 1311 auto range = p.second - p.first + 1; 1312 1313 return generate_canonical< 1314 result_type, numeric_limits<result_type>::digits 1315 >(g) * range + p.first; 1316 } 1317 1318 result_type a() const 1319 { 1320 return a_; 1321 } 1322 1323 result_type b() const 1324 { 1325 return b_; 1326 } 1327 1328 param_type param() const 1329 { 1330 return param_type{a_, b_}; 1331 } 1332 1333 void param(const param_type& p) 1334 { 1335 a_ = p.first; 1336 b_ = p.second; 1337 } 1338 1339 result_type min() const 1340 { 1341 return a_; 1342 } 1343 1344 result_type max() const 1345 { 1346 return b_; 1347 } 1348 1349 bool operator==(const uniform_real_distribution& rhs) const 1350 { 1351 return a_ == rhs.a_ && b_ == rhs.b_; 1352 } 1353 1354 bool operator!=(const uniform_real_distribution& rhs) const 1355 { 1356 return !(*this == rhs); 1357 } 1358 1359 // TODO: ostream/istream operators can't be members 1360 template<class Char, class Traits> 1361 basic_ostream<Char, Traits>& operator<<(basic_ostream<Char, Traits>& os) const 1362 { 1363 auto flags = os.flags(); 1364 os.flags(ios_base::dec | ios_base::left); 1365 1366 os << a_ << os.widen(' ') << b_; 1367 1368 os.flags(flags); 1369 return os; 1370 } 1371 1372 template<class Char, class Traits> 1373 basic_istream<Char, Traits>& operator>>(basic_istream<Char, Traits>& is) const 1374 { 1375 auto flags = is.flags(); 1376 is.flags(ios_base::dec); 1377 1378 if (!(is >> a_) || !(is >> b_)) 1379 is.setstate(ios::failbit); 1380 1381 is.flags(flags); 1382 return is; 1383 } 1384 1385 private: 1386 result_type a_; 1387 result_type b_; 1388 }; 1166 1389 1167 1390 /** … … 1169 1392 */ 1170 1393 1171 class bernoulli_distribution; 1394 class bernoulli_distribution 1395 { 1396 public: 1397 using result_type = bool; 1398 using param_type = float; 1399 1400 explicit bernoulli_distribution(double prob = 0.5) 1401 : prob_{static_cast<float>(prob)} 1402 { /* DUMMY BODY */ } 1403 1404 explicit bernoulli_distribution(const param_type& p) 1405 : prob_{p} 1406 { /* DUMMY BODY */ } 1407 1408 void reset() 1409 { /* DUMMY BODY */ } 1410 1411 template<class URNG> 1412 result_type operator()(URNG& g) 1413 { 1414 uniform_real_distribution<float> dist{}; 1415 1416 return dist(g) < prob_; 1417 } 1418 1419 template<class URNG> 1420 result_type operator()(const param_type& p) 1421 { 1422 uniform_real_distribution<float> dist{}; 1423 1424 return dist(p) < prob_; 1425 } 1426 1427 double p() const 1428 { 1429 return prob_; 1430 } 1431 1432 param_type param() const 1433 { 1434 return prob_; 1435 } 1436 1437 void param(const param_type& p) 1438 { 1439 prob_ = p; 1440 } 1441 1442 result_type min() const 1443 { 1444 return false; 1445 } 1446 1447 result_type max() const 1448 { 1449 return true; 1450 } 1451 1452 private: 1453 /** 1454 * Note: We use float because we do not 1455 * have the macro DBL_MANT_DIGITS 1456 * for generate_cannonical. 1457 */ 1458 float prob_; 1459 }; 1460 1461 // TODO: complete the rest of the distributions 1172 1462 1173 1463 /**
Note:
See TracChangeset
for help on using the changeset viewer.