83 const std::vector<T>& cs) {
85 "qsys_mg1_fb requires transcendental arithmetic");
86 detail::mg1_discipline_check(
"qsys_mg1_fb", lambda, mu, cs);
87 const std::size_t K = lambda.size();
93 for (std::size_t i = 0; i < K; ++i)
94 if (!(
num_abs(T(cs[i] - one)) < cs_tol)) all_exp =
false;
100 T lambda_total = zero;
101 for (
const T& v : lambda) lambda_total += v;
103 for (std::size_t i = 0; i < K; ++i) p[i] = lambda[i] / lambda_total;
106 for (std::size_t k = 0; k < K; ++k) {
107 const T mu_k = mu[k];
109 r.
W[k] = detail::num_integral<T>(
111 return detail::mg1_fb_response(x, mu, p, lambda_total) * mu_k *
112 detail::num_exp(T(-mu_k * x));
114 zero, x_max, reltol, abstol);
117 for (std::size_t k = 0; k < K; ++k) {
118 const T x = one / mu[k];
119 T rho_x = zero, numer = zero;
120 for (std::size_t i = 0; i < K; ++i) {
121 T int_Fbar, int_tFbar;
122 if (
num_abs(T(cs[i] - one)) < cs_tol) {
123 const T e = detail::num_exp(T(-mu[i] * x));
124 int_Fbar = (one - e) / mu[i];
125 int_tFbar = (one - e * (one + mu[i] * x)) / (mu[i] * mu[i]);
127 int_Fbar = detail::num_min(x, T(one / mu[i]));
128 int_tFbar = detail::num_min(T(x * x / two), T(one / (mu[i] * mu[i])));
130 rho_x += lambda[i] * int_Fbar;
131 numer += lambda[i] * int_tFbar;
134 throw NumericError(
"qsys_mg1_fb: truncated load reaches one, the mean is infinite");
135 r.
W[k] = numer / ((one - rho_x) * (one - rho_x)) + x / (one - rho_x);
138 r.
rhohat = detail::mg1_discipline_rhohat(lambda, r.
W);
Mg1DisciplineResult< T > qsys_mg1_fb(const std::vector< T > &lambda, const std::vector< T > &mu, const std::vector< T > &cs)
M/G/1 under FB (feedback), also called LAS (least attained service).