Monte Carlo Integration Library 1.0
High-performance Monte Carlo methods for numerical integration and optimization
test_rng_reproducibility.cpp
Go to the documentation of this file.
1
20#include <iostream>
21#include <vector>
22#include <cmath>
23#include <iomanip>
24#include <omp.h>
25
30
39double rosenbrock(const std::vector<double>& x) {
40 double a = 1.0, b = 100.0;
41 return std::pow(a - x[0], 2) + b * std::pow(x[1] - x[0]*x[0], 2);
42}
43
56double run_pso_test() {
58 cfg.population_size = 20;
59 cfg.max_iterations = 30;
60 cfg.inertia_weight = 0.7;
61 cfg.cognitive_coeff = 1.5;
62 cfg.social_coeff = 1.5;
63
64 mc::optim::PSO pso(cfg);
66 pso.setBounds({-5.0, -5.0}, {5.0, 5.0});
68
69 mc::optim::Solution best = pso.optimize();
70 return best.value;
71}
72
85double run_ga_test() {
87 cfg.population_size = 20;
88 cfg.max_generations = 30;
89 cfg.tournament_k = 3;
90 cfg.crossover_rate = 0.9;
91 cfg.mutation_rate = 0.1;
92 cfg.mutation_sigma = 0.1;
93 cfg.elitism_count = 1;
94
95 mc::optim::GA ga(cfg);
97 ga.setBounds({-5.0, -5.0}, {5.0, 5.0});
99
100 mc::optim::Solution best = ga.optimize();
101 return best.value;
102}
103
104std::vector<double> generate_samples(int n_samples, std::uint64_t stream_id) {
105 std::vector<double> results(n_samples);
106
107 #pragma omp parallel for
108 for (int i = 0; i < n_samples; ++i) {
109 // Deterministic per-index stream; independent of scheduling
110 auto rng = mc::rng::make_engine(stream_id + static_cast<std::uint64_t>(i));
111 std::uniform_real_distribution<double> dist(0.0, 1.0);
112 results[i] = dist(rng);
113 }
114
115 return results;
116}
117
118int main() {
119 std::cout << "=== RNG Reproducibility Test ===\n\n";
120
121 bool all_passed = true;
122
123 // Seed can be set only once (library policy)
124 std::cout << "Init: set global seed once...\n";
125 bool seed_ok = mc::rng::set_global_seed(12345u);
126 std::uint32_t seed_now = mc::rng::get_global_seed();
127
128 std::cout << " set_global_seed returned: " << (seed_ok ? "true" : "false") << "\n";
129 std::cout << " get_global_seed: " << seed_now << "\n\n";
130
131 if (!seed_ok || seed_now != 12345u) {
132 std::cout << " FAILED: Global seed initialization failed\n\n";
133 return 1;
134 }
135
136 // =========================================================================
137 // Test 1: PSO determinism within same process (same global seed)
138 // =========================================================================
139 std::cout << "Test 1: PSO determinism...\n";
140 double pso_run1 = run_pso_test();
141 double pso_run2 = run_pso_test();
142
143 std::cout << " Run 1: " << std::fixed << std::setprecision(10) << pso_run1 << "\n";
144 std::cout << " Run 2: " << std::fixed << std::setprecision(10) << pso_run2 << "\n";
145
146 if (std::abs(pso_run1 - pso_run2) < 1e-12) {
147 std::cout << " PASSED: Results are identical\n\n";
148 } else {
149 std::cout << " FAILED: Results differ!\n\n";
150 all_passed = false;
151 }
152
153 // =========================================================================
154 // Test 2: GA determinism within same process (same global seed)
155 // =========================================================================
156 std::cout << "Test 2: GA determinism...\n";
157 double ga_run1 = run_ga_test();
158 double ga_run2 = run_ga_test();
159
160 std::cout << " Run 1: " << std::fixed << std::setprecision(10) << ga_run1 << "\n";
161 std::cout << " Run 2: " << std::fixed << std::setprecision(10) << ga_run2 << "\n";
162
163 if (std::abs(ga_run1 - ga_run2) < 1e-12) {
164 std::cout << " PASSED: Results are identical\n\n";
165 } else {
166 std::cout << " FAILED: Results differ!\n\n";
167 all_passed = false;
168 }
169
170 // =========================================================================
171 // Test 3: Parallel sample generation determinism
172 // =========================================================================
173 std::cout << "Test 3: Parallel sample generation reproducibility...\n";
174
175 int n_samples = 1000;
176 auto samples1 = generate_samples(n_samples, 9000ULL);
177 auto samples2 = generate_samples(n_samples, 9000ULL);
178
179 int mismatches = 0;
180 for (int i = 0; i < n_samples; ++i) {
181 if (std::abs(samples1[i] - samples2[i]) > 1e-15) {
182 mismatches++;
183 }
184 }
185
186 std::cout << " Generated " << n_samples << " samples in parallel\n";
187 std::cout << " Mismatches between runs: " << mismatches << "\n";
188
189 if (mismatches == 0) {
190 std::cout << " PASSED: All samples are identical\n\n";
191 } else {
192 std::cout << " FAILED: Some samples differ!\n\n";
193 all_passed = false;
194 }
195
196 // =========================================================================
197 // Summary
198 // =========================================================================
199 std::cout << "=================================\n";
200 if (all_passed) {
201 std::cout << "ALL TESTS PASSED!\n";
202 return 0;
203 } else {
204 std::cout << "SOME TESTS FAILED!\n";
205 return 1;
206 }
207}
Genetic Algorithm (GA) interface and data structures.
Particle Swarm Optimization (PSO) interface and data structures.
Genetic Algorithm optimizer.
Definition GA.hpp:46
void setMode(OptimizationMode mode) override
Set optimization mode (minimize or maximize).
Definition GA.cpp:43
void setBounds(const Coordinates &lower, const Coordinates &upper) override
Set lower/upper bounds of the search hyper-rectangle.
Definition GA.cpp:34
Solution optimize() override
Run GA for max_generations.
Definition GA.cpp:211
void setObjectiveFunction(ObjectiveFunction func) override
Set the objective function to optimize.
Definition GA.cpp:25
Particle Swarm Optimization algorithm.
Definition PSO.hpp:40
Solution optimize() override
Execute the optimization loop for max_iterations.
Definition PSO.cpp:167
void setBounds(const Coordinates &lower, const Coordinates &upper) override
Set lower/upper bounds of the search hyper-rectangle.
Definition PSO.cpp:32
void setObjectiveFunction(ObjectiveFunction func) override
Set the objective function to optimize.
Definition PSO.cpp:23
void setMode(OptimizationMode mode) override
Set optimization mode (minimize or maximize).
Definition PSO.cpp:41
bool set_global_seed(std::uint32_t s)
Set the global seed used by all library RNG components.
std::mt19937 make_engine(std::uint64_t stream_id)
Create a deterministic RNG engine for a specific stream.
std::uint32_t get_global_seed()
Get the current global seed.
Factory for creating deterministic, independent RNG engines.
Configuration parameters for GA.
Definition GA.hpp:21
size_t elitism_count
Number of top individuals copied unchanged to next generation.
Definition GA.hpp:38
size_t tournament_k
Tournament size for selection (k >= 2).
Definition GA.hpp:28
Real mutation_rate
Per-gene mutation probability.
Definition GA.hpp:33
size_t population_size
Size of the population.
Definition GA.hpp:23
Real crossover_rate
Probability of performing crossover in reproduction.
Definition GA.hpp:31
Real mutation_sigma
Mutation magnitude (scaled by coordinate span).
Definition GA.hpp:35
size_t max_generations
Number of generations to evolve.
Definition GA.hpp:25
Configuration parameters for PSO.
Definition PSO.hpp:21
size_t population_size
Number of particles in the swarm.
Definition PSO.hpp:23
Real social_coeff
Social coefficient (c2): scales attraction to global best.
Definition PSO.hpp:32
Real cognitive_coeff
Cognitive coefficient (c1): scales attraction to particle best.
Definition PSO.hpp:30
Real inertia_weight
Inertia weight (w): scales previous velocity.
Definition PSO.hpp:28
size_t max_iterations
Number of iterations to run the optimizer.
Definition PSO.hpp:25
Represents a candidate solution in the search space.
Definition types.hpp:51
Real value
Evaluated objective value for params.
Definition types.hpp:55
Stores benchmark result for a single sample count.
std::vector< double > generate_samples(int n_samples, std::uint64_t stream_id)
double rosenbrock(const std::vector< double > &x)
Rosenbrock function benchmark.
double run_ga_test()
Run GA on Rosenbrock function and return best value found.
double run_pso_test()
Run PSO on Rosenbrock function and return best value found.