FERS 1.0.0
The Flexible Extensible Radar Simulator
Loading...
Searching...
No Matches
noise_generators.cpp
Go to the documentation of this file.
1// SPDX-License-Identifier: GPL-2.0-only
2//
3// Copyright (c) 2006-2008 Marc Brooker and Michael Inggs
4// Copyright (c) 2008-present FERS Contributors (see AUTHORS.md).
5//
6// See the GNU GPLv2 LICENSE file in the FERS project root for more information.
7
8/**
9 * @file noise_generators.cpp
10 * @brief Implementation file for noise generator classes.
11 */
12
13#include "noise_generators.h"
14
15#include <cmath>
16#include <ranges>
17#include <utility>
18
19#include "core/parameters.h"
20#include "noise/falpha_branch.h"
21
22namespace noise
23{
24 MultirateGenerator::MultirateGenerator(std::mt19937& rngEngine, const RealType alpha, const unsigned branches) :
25 _rng_engine(rngEngine)
26 {
27 const RealType beta = -(alpha - 2) / 2.0;
28 const int fint = static_cast<int>(std::floor(beta));
29 const RealType ffrac = std::fmod(beta, 1.0);
30
31 createTree(ffrac, fint, branches);
32 // TODO: verify scale factor calculation (* 2.0 appears to be a bug)
33 _scale = 1.0 / std::pow(10.0, (-alpha + 2.0) * 2.0);
34 }
35
36 // NOLINTNEXTLINE(readability-make-member-function-const)
37 void MultirateGenerator::skipSamples(const long long samples) noexcept
38 {
39 if (const int skip_branches = static_cast<int>(std::log10(samples)) - 1; skip_branches > 0)
40 {
41 std::vector<FAlphaBranch*> flushbranches;
42 FAlphaBranch* branch = _topbranch.get();
43
44 for (int i = 0; i < skip_branches && branch; ++i)
45 {
46 flushbranches.push_back(branch);
47 branch = branch->getPre();
48 }
49
50 if (branch)
51 {
52 const auto reduced_samples = samples / static_cast<long long>(std::pow(10.0, skip_branches));
53 for (long long i = 0; i < reduced_samples; ++i)
54 {
55 branch->getSample();
56 }
57 }
58
59 for (const auto& fb : std::ranges::reverse_view(flushbranches))
60 {
61 fb->flush(1.0);
62 }
63 }
64 else
65 {
66 for (long long i = 0; i < samples; ++i)
67 {
68 _topbranch->getSample();
69 }
70 }
71 }
72
73 void MultirateGenerator::createTree(const RealType fAlpha, const int fInt, const unsigned branches)
74 {
75 std::unique_ptr<FAlphaBranch> previous_branch = nullptr;
76 for (unsigned i = 0; i < branches; ++i)
77 {
78 previous_branch = std::make_unique<FAlphaBranch>(_rng_engine.get(), fAlpha, fInt,
79 std::move(previous_branch), i == branches - 1);
80 }
81 _topbranch = std::move(previous_branch);
82 }
83
84 // NOLINTNEXTLINE(readability-make-member-function-const)
86 {
87 std::vector<FAlphaBranch*> branches;
88 FAlphaBranch* branch = _topbranch.get();
89
90 while (branch)
91 {
92 branches.push_back(branch);
93 branch = branch->getPre();
94 }
95
96 for (const auto& b : std::ranges::reverse_view(branches))
97 {
98 b->flush(1.0);
99 }
100 }
101
102 ClockModelGenerator::ClockModelGenerator(std::mt19937& rngEngine, const std::vector<RealType>& alpha,
103 const std::vector<RealType>& inWeights, const RealType frequency,
104 const RealType phaseOffset, const RealType freqOffset,
105 int branches) noexcept :
106 _rng_engine(rngEngine), _weights(inWeights), _phase_offset(phaseOffset), _freq_offset(freqOffset),
107 _frequency(frequency)
108 {
109 for (size_t i = 0; i < alpha.size(); ++i)
110 {
111 auto mgen = std::make_unique<MultirateGenerator>(_rng_engine.get(), alpha[i], branches);
112 _generators.push_back(std::move(mgen));
113
114 switch (static_cast<int>(alpha[i]))
115 {
116 case 2:
117 _weights[i] *= std::pow(10.0, 1.225);
118 break;
119 case 1:
120 _weights[i] *= std::pow(10.0, 0.25);
121 break;
122 case 0:
123 _weights[i] *= std::pow(10.0, -0.25);
124 break;
125 case -1:
126 _weights[i] *= std::pow(10.0, -0.5);
127 break;
128 case -2:
129 _weights[i] *= std::pow(10.0, -1.0);
130 break;
131 default:
132 break;
133 }
134 }
135 }
136
138 {
139 RealType sample = 0;
140 for (size_t i = 0; i < _generators.size(); ++i)
141 {
142 sample += _generators[i]->getSample() * _weights[i];
143 }
144
145 sample += _phase_offset;
146 sample += 2 * PI * _freq_offset * static_cast<double>(_count) / params::rate();
147 ++_count;
148
149 return sample;
150 }
151
152 void ClockModelGenerator::skipSamples(const long long samples)
153 {
154 for (const auto& generator : _generators)
155 {
156 generator->skipSamples(samples);
157 }
158 _count += samples;
159 }
160
162 {
163 // reset() call chain is only called if sync on pulse is enabled,
164 // otherwise the all generators and counts remain as-is
165 for (const auto& generator : _generators)
166 {
167 generator->reset();
168 }
169 _count = 0;
170 }
171
173 {
174 return !_generators.empty() || _freq_offset != 0 || _phase_offset != 0;
175 }
176}
void skipSamples(long long samples)
Skips a number of samples in the noise sequence.
void reset()
Resets the noise generator state.
bool enabled() const
Checks if the noise generator is enabled.
ClockModelGenerator(std::mt19937 &rngEngine, const std::vector< RealType > &alpha, const std::vector< RealType > &inWeights, RealType frequency, RealType phaseOffset, RealType freqOffset, int branches) noexcept
Constructor to initialize the clock model generator.
RealType getSample() override
Generates a clock model noise sample.
Class responsible for generating fractional and integer noise components.
FAlphaBranch * getPre() const noexcept
Retrieves the previous branch in the chain.
void flush(RealType scale)
Flushes the branch with a new scaling factor.
RealType getSample() noexcept
Retrieves the current noise sample.
MultirateGenerator(std::mt19937 &rngEngine, RealType alpha, unsigned branches)
Constructor to initialize the multirate generator.
void reset() noexcept
Resets the noise generator state.
void skipSamples(long long samples) noexcept
Skips a number of samples in the noise sequence.
double RealType
Type for real numbers.
Definition config.h:27
constexpr RealType PI
Mathematical constant π (pi).
Definition config.h:43
Implementation of the FAlphaBranch class for noise generation.
RealType rate() noexcept
Get the rendering sample rate.
Definition parameters.h:109
Header file for noise generator classes.
Defines the Parameters struct and provides methods for managing simulation parameters.