INSTINCT Code Coverage Report


Directory: src/
File: util/Random/RandomNumberGenerator.hpp
Date: 2025-02-07 16:54:41
Exec Total Coverage
Lines: 16 20 80.0%
Functions: 4 6 66.7%
Branches: 17 52 32.7%

Line Branch Exec Source
1 // This file is part of INSTINCT, the INS Toolkit for Integrated
2 // Navigation Concepts and Training by the Institute of Navigation of
3 // the University of Stuttgart, Germany.
4 //
5 // This Source Code Form is subject to the terms of the Mozilla Public
6 // License, v. 2.0. If a copy of the MPL was not distributed with this
7 // file, You can obtain one at https://mozilla.org/MPL/2.0/.
8
9 /// @file RandomNumberGenerator.hpp
10 /// @brief Random Number Generator
11 /// @author T. Topp (topp@ins.uni-stuttgart.de)
12 /// @date 2023-08-24
13
14 #pragma once
15
16 #include <random>
17 #include <string>
18
19 #include <nlohmann/json.hpp>
20 using json = nlohmann::json; ///< json namespace
21
22 #include "SHA256.hpp"
23
24 namespace NAV
25 {
26
27 /// @brief Manages a thread which calls a specified function at a specified interval
28 class RandomNumberGenerator
29 {
30 public:
31 /// @brief Default constructor
32 1680 explicit RandomNumberGenerator(bool useSeed = true) : useSeed(useSeed) {} // NOLINT(cert-msc32-c,cert-msc51-cpp)
33 /// @brief Copy constructor
34 RandomNumberGenerator(const RandomNumberGenerator&) = delete;
35 /// @brief Move constructor
36 RandomNumberGenerator(RandomNumberGenerator&&) = delete;
37 /// @brief Copy assignment operator
38 RandomNumberGenerator& operator=(const RandomNumberGenerator&) = delete;
39 /// @brief Move assignment operator
40 RandomNumberGenerator& operator=(RandomNumberGenerator&&) = delete;
41 /// @brief Destructor
42 ~RandomNumberGenerator() = default;
43
44 /// @brief Reset the seed to the internal seed or the system time
45 /// @param id Some id used to make a unique hash when using the system time to set the seed
46 84 void resetSeed(size_t id = 0)
47 {
48
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 uint64_t seed = useSeed ? this->seed : static_cast<uint64_t>(std::chrono::system_clock::now().time_since_epoch().count());
49
7/24
✗ Branch 0 not taken.
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 5 taken 84 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 14 taken 84 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 84 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 84 times.
✗ Branch 21 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 84 times.
✓ Branch 28 taken 84 times.
✗ Branch 29 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
252 auto hash = hashSeed(std::to_string(seed) + (useSeed || id == 0 ? "" : " " + std::to_string(id)));
50
1/2
✓ Branch 3 taken 84 times.
✗ Branch 4 not taken.
84 std::seed_seq seed_seq(hash.begin(), hash.end());
51
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 _generator.seed(seed_seq);
52 84 }
53
54 /// @brief Reset the seed to the specified seed, but do not update the internal seed
55 /// @param[in] userSeed Seed to use once
56 void resetSeedOnce(uint64_t userSeed)
57 {
58 auto hash = hashSeed(std::to_string(userSeed));
59 std::seed_seq seed_seq(hash.begin(), hash.end());
60 _generator.seed(seed_seq);
61 }
62
63 /// @brief Gets a random integer number from an uniform distribution
64 /// @tparam IntType The result type generated by the generator. The effect is undefined if this is not one of short, int, long, long long, unsigned short, unsigned int, unsigned long, or unsigned long long.
65 /// @param min Minimum value
66 /// @param max Maximum value
67 /// @return Random number
68 template<typename IntType = int>
69 double getRand_uniformIntDist(IntType min = 0, IntType max = std::numeric_limits<IntType>::max())
70 {
71 return std::uniform_int_distribution<IntType>(min, max)(_generator);
72 }
73
74 /// @brief Gets a random real number from an uniform distribution
75 /// @tparam RealType The result type generated by the generator. The effect is undefined if this is not one of float, double, or long double
76 /// @param min Minimum value
77 /// @param max Maximum value
78 /// @return Random number
79 template<typename RealType = double>
80 double getRand_uniformRealDist(RealType min = 0.0, RealType max = 1.0)
81 {
82 return std::uniform_real_distribution<RealType>(min, max)(_generator);
83 }
84
85 /// @brief Gets a random number from a normal distribution
86 /// @tparam RealType The result type generated by the generator. The effect is undefined if this is not one of float, double, or long double
87 /// @param mean The μ distribution parameter (mean)
88 /// @param stddev The σ distribution parameter (standard deviation)
89 /// @return Random number
90 template<typename RealType = double>
91 1065018 double getRand_normalDist(RealType mean = 0.0, RealType stddev = 1.0)
92 {
93
2/4
✓ Branch 1 taken 1065082 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1065177 times.
✗ Branch 5 not taken.
1065018 return std::normal_distribution<RealType>(mean, stddev)(_generator);
94 }
95
96 bool useSeed = true; ///< Flag whether to use the seed instead of the system time
97 uint64_t seed = 0; ///< Seed for the random number generator
98
99 private:
100 /// @brief Hash the given seed
101 /// @param seed Seed
102 /// @return Hashed seed
103 84 static std::string hashSeed(const std::string& seed)
104 {
105
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 SHA256 sha;
106
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 sha.update(seed);
107
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 uint8_t* digest = sha.digest();
108
109
1/2
✓ Branch 1 taken 84 times.
✗ Branch 2 not taken.
84 std::string hashed(digest, digest + 32); // NOLINT //SHA256::ToString method is shady... (manipulates data?). Keep Pointer Arithmetic
110
1/2
✓ Branch 0 taken 84 times.
✗ Branch 1 not taken.
84 delete[] digest; // NOLINT
111
112 168 return hashed;
113 }
114
115 std::mt19937_64 _generator; ///< Random number generator
116 };
117
118 /// @brief Write info to a json object
119 /// @param[out] j Json output
120 /// @param[in] rng Object to read info from
121 void to_json(json& j, const RandomNumberGenerator& rng);
122 /// @brief Read info from a json object
123 /// @param[in] j Json variable to read info from
124 /// @param[out] rng Output object
125 void from_json(const json& j, RandomNumberGenerator& rng);
126
127 } // namespace NAV
128