24 v = std::stod(s, &idx);
25 }
catch (
const std::exception &) {
35void strip(std::string &s)
37 while (!s.empty() && std::isspace(
static_cast<unsigned char>(s.front())))
39 while (!s.empty() && std::isspace(
static_cast<unsigned char>(s.back())))
43bool parse_double(
const std::string &raw,
double &out)
47 if (s.empty())
return false;
50 out = std::stod(s, &idx);
51 return idx == s.size();
52 }
catch (
const std::exception &) {
61 const auto colon = s.find(
':');
62 if (colon == std::string::npos)
return std::nullopt;
64 std::string kind_str = s.substr(0, colon);
65 std::string params = s.substr(colon + 1);
70 if (kind_str ==
"normal" || kind_str ==
"uniform") {
71 const auto comma = params.find(
',');
72 if (comma == std::string::npos)
return std::nullopt;
73 if (!parse_double(params.substr(0, comma), out.
p1))
return std::nullopt;
74 if (!parse_double(params.substr(comma + 1), out.
p2))
return std::nullopt;
78 if (kind_str ==
"exponential") {
79 if (!parse_double(params, out.
p1))
return std::nullopt;
84 if (kind_str ==
"erlang") {
85 const auto comma = params.find(
',');
86 if (comma == std::string::npos)
return std::nullopt;
87 if (!parse_double(params.substr(0, comma), out.
p1))
return std::nullopt;
88 if (!parse_double(params.substr(comma + 1), out.
p2))
return std::nullopt;
99 return "normal:" + std::to_string(d.
p1) +
"," + std::to_string(d.
p2);
101 return "uniform:" + std::to_string(d.
p1) +
"," + std::to_string(d.
p2);
103 return "exponential:" + std::to_string(d.
p1);
107 return "erlang:" + std::to_string(
static_cast<long long>(d.
p1))
108 +
"," + std::to_string(d.
p2);
128 const double sigma = d.
p2;
129 return sigma * sigma;
132 const double w = d.
p2 - d.
p1;
133 return (w * w) / 12.0;
136 const double lambda = d.
p1;
137 return 1.0 / (lambda * lambda);
140 const double k = d.
p1, lambda = d.
p2;
141 return k / (lambda * lambda);
149double factorial(
unsigned k)
152 for (
unsigned i = 2; i <= k; ++i) r *= static_cast<double>(i);
156double binomial_coeff(
unsigned n,
unsigned k)
158 if (k > n)
return 0.0;
159 if (k > n - k) k = n - k;
161 for (
unsigned i = 1; i <= k; ++i) {
162 r *=
static_cast<double>(n - i + 1);
163 r /=
static_cast<double>(i);
173double double_factorial_minus_one(
unsigned j)
175 if (j == 0)
return 1.0;
177 for (
unsigned i = 1; i < j; i += 2) r *= static_cast<double>(i);
185 if (k == 0)
return 1.0;
189 const double mu = d.
p1;
190 const double sigma = d.
p2;
193 for (
unsigned j = 0; j <= k; j += 2) {
194 total += binomial_coeff(k, j)
195 * std::pow(mu,
static_cast<double>(k - j))
196 * std::pow(sigma,
static_cast<double>(j))
197 * double_factorial_minus_one(j);
202 const double a = d.
p1;
203 const double b = d.
p2;
204 const double kp1 =
static_cast<double>(k + 1);
205 return (std::pow(b, kp1) - std::pow(a, kp1)) / (kp1 * (b - a));
208 const double lambda = d.
p1;
209 return factorial(k) / std::pow(lambda,
static_cast<double>(k));
217 const double s = d.
p1, lambda = d.
p2;
219 for (
unsigned i = 0; i < k; ++i) rising *= (s + static_cast<double>(i));
220 return rising / std::pow(lambda,
static_cast<double>(k));
Generic directed-acyclic-graph circuit template and gate identifier.
Continuous random-variable helpers (distribution parsing, moments).
Exception type thrown by circuit operations on invalid input.
@ Normal
Normal (Gaussian): p1=μ, p2=σ
@ Exponential
Exponential: p1=λ, p2 unused.
@ Uniform
Uniform on [a,b]: p1=a, p2=b.
@ Erlang
Erlang: p1=k (positive integer), p2=λ.
double analytical_variance(const DistributionSpec &d)
Closed-form variance Var(X) for a basic distribution.
double parseDoubleStrict(const std::string &s)
Strictly parse s as a double.
std::optional< DistributionSpec > parse_distribution_spec(const std::string &s)
Parse the on-disk text encoding of a gate_rv distribution.
double analytical_mean(const DistributionSpec &d)
Closed-form expectation E[X] for a basic distribution.
std::string format_distribution_spec(const DistributionSpec &d)
Format a spec back into its on-disk text encoding.
double analytical_raw_moment(const DistributionSpec &d, unsigned k)
Closed-form raw moment for a basic distribution.
Parsed distribution spec (kind + up to two parameters).
double p2
Second parameter (σ or b; unused for Exponential).
double p1
First parameter (μ, a, or λ).