INSTINCT Code Coverage Report


Directory: src/
File: util/Random/RandomNumberGenerator.hpp
Date: 2025-06-02 15:19:59
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 1764 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 168 void resetSeed(size_t id = 0)
47 {
48
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
168 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 168 times.
✗ Branch 2 not taken.
✗ Branch 3 not taken.
✓ Branch 5 taken 168 times.
✗ Branch 6 not taken.
✗ Branch 8 not taken.
✗ Branch 9 not taken.
✗ Branch 11 not taken.
✗ Branch 12 not taken.
✓ Branch 14 taken 168 times.
✗ Branch 15 not taken.
✓ Branch 17 taken 168 times.
✗ Branch 18 not taken.
✓ Branch 20 taken 168 times.
✗ Branch 21 not taken.
✗ Branch 25 not taken.
✓ Branch 26 taken 168 times.
✓ Branch 28 taken 168 times.
✗ Branch 29 not taken.
✗ Branch 33 not taken.
✗ Branch 34 not taken.
✗ Branch 36 not taken.
✗ Branch 37 not taken.
504 auto hash = hashSeed(std::to_string(seed) + (useSeed || id == 0 ? "" : " " + std::to_string(id)));
50
1/2
✓ Branch 3 taken 168 times.
✗ Branch 4 not taken.
168 std::seed_seq seed_seq(hash.begin(), hash.end());
51
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 _generator.seed(seed_seq);
52 168 }
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 1039159 double getRand_normalDist(RealType mean = 0.0, RealType stddev = 1.0)
92 {
93
2/4
✓ Branch 1 taken 1039218 times.
✗ Branch 2 not taken.
✓ Branch 4 taken 1039267 times.
✗ Branch 5 not taken.
1039159 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 168 static std::string hashSeed(const std::string& seed)
104 {
105
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 SHA256 sha;
106
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 sha.update(seed);
107
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 uint8_t* digest = sha.digest();
108
109
1/2
✓ Branch 1 taken 168 times.
✗ Branch 2 not taken.
168 std::string hashed(digest, digest + 32); // NOLINT //SHA256::ToString method is shady... (manipulates data?). Keep Pointer Arithmetic
110
1/2
✓ Branch 0 taken 168 times.
✗ Branch 1 not taken.
168 delete[] digest; // NOLINT
111
112 336 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