80 const std::vector<T>& cs) {
82 "qsys_mg1_psjf requires transcendental arithmetic");
83 detail::mg1_discipline_check(
"qsys_mg1_psjf", lambda, mu, cs);
84 const std::size_t K = lambda.size();
90 for (std::size_t i = 0; i < K; ++i)
91 if (!(
num_abs(T(cs[i] - one)) < cs_tol)) all_exp =
false;
97 T lambda_total = zero;
98 for (
const T& v : lambda) lambda_total += v;
100 for (std::size_t i = 0; i < K; ++i) p[i] = lambda[i] / lambda_total;
103 for (std::size_t k = 0; k < K; ++k) {
104 const T mu_k = mu[k];
106 r.
W[k] = detail::num_integral<T>(
108 return detail::mg1_psjf_response(x, mu, p, lambda_total) * mu_k *
109 detail::num_exp(T(-mu_k * x));
111 zero, x_max, reltol, abstol);
116 std::vector<std::size_t> idx(K);
117 std::iota(idx.begin(), idx.end(), std::size_t(0));
118 std::stable_sort(idx.begin(), idx.end(),
119 [&](std::size_t i, std::size_t j) { return one / mu[i] < one / mu[j]; });
121 for (std::size_t pos = 0; pos < K; ++pos) {
122 const std::size_t k = idx[pos];
123 const T x = one / mu[k];
124 rho_cum += lambda[k] / mu[k];
126 for (std::size_t q = 0; q <= pos; ++q) {
127 const std::size_t i = idx[q];
128 m2_x += lambda[i] * (one + cs[i] * cs[i]) / (mu[i] * mu[i]);
132 "qsys_mg1_psjf: truncated load reaches one, the mean is infinite");
133 r.
W[k] = m2_x / (two * (one - rho_cum) * (one - rho_cum)) + x / (one - rho_cum);
136 r.
rhohat = detail::mg1_discipline_rhohat(lambda, r.
W);
Mg1DisciplineResult< T > qsys_mg1_psjf(const std::vector< T > &lambda, const std::vector< T > &mu, const std::vector< T > &cs)
M/G/1 under PSJF (preemptive shortest job first).