MayaFlux 0.3.0
Digital-First Multimedia Processing Framework
Loading...
Searching...
No Matches
Stochastic.cpp
Go to the documentation of this file.
1#include "Stochastic.hpp"
2
4
6 : m_engine(std::random_device {}())
7 , m_algorithm(algo)
8 , m_xorshift_state(std::random_device {}() | (static_cast<uint64_t>(std::random_device {}()) << 32))
9{
10 if (m_xorshift_state == 0)
11 m_xorshift_state = 0xDEADBEEFCAFEBABE;
12}
13
14void Stochastic::seed(uint64_t seed)
15{
16 m_engine.seed(static_cast<std::mt19937::result_type>(seed));
18 if (m_xorshift_state == 0)
19 m_xorshift_state = 0xDEADBEEFCAFEBABE;
21}
22
24{
25 if (m_algorithm != algo) {
26 m_algorithm = algo;
28 m_dist_dirty = true;
29 }
30}
31
32void Stochastic::configure(const std::string& key, std::any value)
33{
34 m_config[key] = std::move(value);
35 m_dist_dirty = true;
36}
37
38std::optional<std::any> Stochastic::get_config(const std::string& key) const
39{
40 auto it = m_config.find(key);
41 if (it != m_config.end()) {
42 return it->second;
43 }
44 return std::nullopt;
45}
46
47double Stochastic::operator()(double min, double max)
48{
49 validate_range(min, max);
50
51 switch (m_algorithm) {
56 return generate_memoryless(min, max);
57
59 return generate_perlin_impl(m_state.phase, 0.0, 0.0);
60
62 return generate_gendy_impl(min, max);
63
65 return generate_brownian_impl(min, max);
66
67 case Algorithm::PINK:
68 case Algorithm::BLUE:
69 return generate_colored_noise_impl(min, max);
70
71 default:
72 return generate_memoryless(min, max);
73 }
74}
75
76double Stochastic::at(double x, double y, double z)
77{
79 throw std::runtime_error("Multi-dimensional access only supported for PERLIN algorithm");
80 }
81 return generate_perlin_impl(x, y, z);
82}
83
84std::vector<double> Stochastic::batch(double min, double max, size_t count)
85{
86 validate_range(min, max);
87
88 std::vector<double> result;
89 result.reserve(count);
90
91 for (size_t i = 0; i < count; ++i) {
92 result.push_back((*this)(min, max));
93 }
94
95 return result;
96}
97
99{
100 m_state.reset();
101}
102
103double Stochastic::generate_memoryless(double min, double max)
104{
105 if (min != m_cached_min || max != m_cached_max) {
106 m_cached_min = min;
107 m_cached_max = max;
108 m_dist_dirty = true;
109 }
110
111 double raw_value = 0.0;
112
113 switch (m_algorithm) {
114 [[likely]] case Algorithm::UNIFORM:
115 return min + fast_uniform() * (max - min);
116
117 case Algorithm::NORMAL: {
119 raw_value = m_normal_dist(m_engine);
120 return std::clamp(raw_value, min, max);
121 }
122
125 raw_value = m_exponential_dist(m_engine);
126 raw_value /= max;
127 return min + raw_value * (max - min);
128 }
129
130 case Algorithm::POISSON: {
131 std::poisson_distribution<int> dist(static_cast<int>(max - min));
132 return static_cast<double>(dist(m_engine));
133 }
134
135 default:
136 return min + fast_uniform() * (max - min);
137 }
138}
139
140double Stochastic::generate_stateful(double min, double max)
141{
143 return m_state.current_value;
144}
145
146double Stochastic::generate_perlin_impl(double x, double y, double z)
147{
148 return 0.0;
149}
150
151double Stochastic::generate_gendy_impl(double min, double max)
152{
153 return min + fast_uniform() * (max - min);
154}
155
156double Stochastic::generate_brownian_impl(double min, double max)
157{
158 double step_size = 0.01;
159 if (auto cfg = get_config("step_size"); cfg.has_value()) {
160 step_size = std::any_cast<double>(*cfg);
161 }
162
163 double step = (fast_uniform() - 0.5) * 2.0 * step_size;
164 m_state.current_value += step;
165 m_state.current_value = std::clamp(m_state.current_value, min, max);
166
168 return m_state.current_value;
169}
170
171double Stochastic::generate_colored_noise_impl(double min, double max)
172{
173 return min + fast_uniform() * (max - min);
174}
175
176void Stochastic::validate_range(double min, double max) const
177{
178 if (min > max) {
179 throw std::invalid_argument("Stochastic: min must be <= max");
180 }
181}
182
184{
185 if (!m_dist_dirty)
186 return;
187
188 const double range = max - min;
189
191 double spread = 4.0;
192 if (auto cfg = get_config("spread"); cfg.has_value()) {
193 spread = std::any_cast<double>(*cfg);
194 }
195 m_normal_dist = std::normal_distribution<double>(0.0, range / spread);
196 } else if (m_algorithm == Algorithm::EXPONENTIAL) {
197 m_exponential_dist = std::exponential_distribution<double>(1.0);
198 }
199
200 m_dist_dirty = false;
201}
202
203}
Eigen::Index count
void validate_range(double min, double max) const
double generate_stateful(double min, double max)
double generate_gendy_impl(double min, double max)
std::map< std::string, std::any > m_config
void configure(const std::string &key, std::any value)
Configures algorithm-specific parameters.
void rebuild_distributions_if_needed(double min, double max)
std::vector< double > batch(double min, double max, size_t count)
Batch generation.
void reset_state()
Resets internal state for stateful algorithms.
double generate_brownian_impl(double min, double max)
std::optional< std::any > get_config(const std::string &key) const
Gets configuration parameter.
double generate_perlin_impl(double x, double y, double z)
double operator()(double min, double max)
Generates single value in range.
std::exponential_distribution< double > m_exponential_dist
double at(double x, double y=0.0, double z=0.0)
Multi-dimensional generation (Perlin, spatial noise)
void set_algorithm(Algorithm algo)
Changes active algorithm.
std::normal_distribution< double > m_normal_dist
double generate_memoryless(double min, double max)
double generate_colored_noise_impl(double min, double max)
void seed(uint64_t seed)
Seeds entropy source.
Unified generative infrastructure for stochastic and procedural algorithms.
Algorithm
Stochastic and procedural generation algorithms.