Changeset 92cb73f in mainline


Ignore:
Timestamp:
2018-07-05T21:41:22Z (6 years ago)
Author:
Dzejrou <dzejrou@…>
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)
Message:

cpp: added generate_cannonical, uniform_int_distribution, uniform_real_distribution and bernoulli_distribution

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/cpp/include/impl/random.hpp

    ra629655 r92cb73f  
    11491149
    11501150    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    }
    11521164
    11531165    /**
     
    11561168
    11571169    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    };
    11591274
    11601275    /**
     
    11631278
    11641279    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    };
    11661389
    11671390    /**
     
    11691392     */
    11701393
    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
    11721462
    11731463    /**
Note: See TracChangeset for help on using the changeset viewer.