53 std::vector<std::size_t>
randperm(std::size_t n) {
54 std::vector<double> u(n);
55 for (std::size_t i = 0; i < n; ++i) u[i] =
rand();
56 std::vector<std::size_t> idx(n);
57 std::iota(idx.begin(), idx.end(), std::size_t(0));
58 std::stable_sort(idx.begin(), idx.end(),
59 [&u](std::size_t a, std::size_t b) { return u[a] < u[b]; });
67 std::vector<double>
randfixedsum(std::size_t n,
double s,
double a,
double b) {
68 const double nn = double(n);
69 s = (s - nn * a) / (b - a);
70 const int k = std::max(std::min(
int(std::floor(s)),
int(n) - 1), 0);
71 s = std::max(std::min(s,
double(k + 1)),
double(k));
72 std::vector<double> s1(n), s2(n);
73 for (std::size_t i = 0; i < n; ++i) {
74 s1[i] = s - double(k -
int(i));
75 s2[i] = double(k +
int(n) -
int(i)) - s;
77 const double tiny = std::numeric_limits<double>::denorm_min();
78 std::vector<std::vector<double>> w(n, std::vector<double>(n + 1, 0.0));
79 w[0][1] = std::numeric_limits<double>::max();
80 std::vector<std::vector<double>> t(n > 1 ? n - 1 : 0, std::vector<double>(n, 0.0));
81 for (std::size_t i = 2; i <= n; ++i) {
82 const double di = double(i);
83 for (std::size_t c = 0; c < i; ++c) {
84 const double tmp1 = w[i - 2][c + 1] * s1[c] / di;
85 const double tmp2 = w[i - 2][c] * s2[n - i + c] / di;
86 w[i - 1][c + 1] = tmp1 + tmp2;
87 const double tmp3 = w[i - 1][c + 1] + tiny;
88 const bool tmp4 = s2[n - i + c] > s1[c];
89 t[i - 2][c] = tmp4 ? tmp2 / tmp3 : 1.0 - tmp1 / tmp3;
92 std::vector<double> x(n, 0.0);
93 std::vector<double> rt(n > 1 ? n - 1 : 0), rs(n > 1 ? n - 1 : 0);
94 for (
double& v : rt) v =
rand();
95 for (
double& v : rs) v =
rand();
97 double sm = 0.0, pr = 1.0;
98 for (std::size_t i = n - 1; i >= 1; --i) {
99 const double e = rt[n - i - 1] <= t[i - 1][std::size_t(j - 1)] ? 1.0 : 0.0;
100 const double sx = std::pow(rs[n - i - 1], 1.0 /
double(i));
101 sm += (1.0 - sx) * pr * s /
double(i + 1);
103 x[n - i - 1] = sm + pr * e;
107 x[n - 1] = sm + pr * s;
108 const std::vector<std::size_t> p =
randperm(n);
109 std::vector<double> out(n);
110 for (std::size_t i = 0; i < n; ++i) out[i] = (b - a) * x[p[i]] + a;