From d73eb1b20544071415bda7a12e31a35833e40c70 Mon Sep 17 00:00:00 2001 From: Steve Pinkham Date: Tue, 28 Jul 2026 11:39:51 -0400 Subject: [PATCH] feat: seed the PRNG (--seed N, default random, printed for reproducibility) rand() was never seeded, so every pathsim invocation produced bit-identical fading and noise (verified byte-identical across separate process runs): N runs intended as independent Monte-Carlo trials replay one realization N times, silently. Seed from std::random_device by default, accept --seed N for exact reproduction, and print the seed used to stderr (stderr so a future stdout streaming mode stays clean). Co-Authored-By: Claude Fable 5 --- main.cpp | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/main.cpp b/main.cpp index 9aac205..e3811df 100644 --- a/main.cpp +++ b/main.cpp @@ -1,7 +1,9 @@ #include "PathSimProcessor.h" #include "PathSimParams.h" +#include #include +#include #include "cxxopts.h" #include "AudioFile.h" @@ -37,6 +39,9 @@ from a Windows GUI application by Moe Wheatley, AE4JY, 2000\n\ } options.add_options("Propagation") + ("seed", "PRNG seed for the fading/noise processes (default: random; " + "the seed used is printed so any run can be reproduced exactly)", + cxxopts::value()) ("snr", "Signal to Noise Ratio (SNR)", cxxopts::value()) ("spread", "Frequency spread of the 1st path [Hz]", cxxopts::value()) ("offset", "Frequency offset of the 1st path [Hz]", cxxopts::value()) @@ -56,6 +61,20 @@ from a Windows GUI application by Moe Wheatley, AE4JY, 2000\n\ exit(0); } + // Seed the PRNG behind the Rayleigh fading and AWGN stages. Without + // this, rand() runs from its default seed and EVERY invocation + // produces bit-identical "random" fading and noise — N runs give one + // realization N times, silently defeating ensemble statistics. + // Default is a fresh random seed; it is printed (stderr, so pipes + // stay clean) so any run can be reproduced with --seed. + { + unsigned int seed = result.count("seed") + ? result["seed"].as() + : std::random_device{}(); + std::srand(seed); + std::cerr << "pathsim: seed " << seed << std::endl; + } + if (argc > 1 || ((result.count("input_file") != 1 || result.count("output_file") != 1) && result.arguments().size() != 2)) {