69 const std::vector<T>& b2,
70 const std::vector<std::size_t>& table,
71 const std::vector<T>& s_mean,
72 const std::vector<T>& s_var,
bool gated) {
73 static const char* who =
"polling_qsys_table";
74 const std::size_t n = lambda.size();
75 const std::size_t M = table.size();
78 if (n == 0 || b.size() != n || b2.size() != n)
79 throw InputError(
ErrorKind{
"Argument"}, std::string(who) +
": lambda, b and b2 must have one entry per queue");
80 if (s_mean.size() != M || s_var.size() != M)
81 throw InputError(
ErrorKind{
"Argument"}, std::string(who) +
": polling_qsys_table needs one switchover per table position (" +
82 std::to_string(M) +
").");
84 std::vector<bool> seen(n,
false);
85 for (std::size_t p : table) {
87 throw InputError(
ErrorKind{
"Argument"}, std::string(who) +
": The polling table must list every queue 1.." +
88 std::to_string(n) +
" at least once.");
91 for (std::size_t i = 0; i < n; ++i)
93 throw InputError(
ErrorKind{
"Argument"}, std::string(who) +
": The polling table must list every queue 1.." +
94 std::to_string(n) +
" at least once.");
96 std::vector<T> rho1(n), s2(M);
98 for (std::size_t i = 0; i < n; ++i) {
99 if (lambda[i] <= zero)
100 throw InputError(
ErrorKind{
"Argument"}, std::string(who) +
": polling_qsys_table needs a positive arrival rate at every queue.");
101 rho1[i] = lambda[i] * b[i];
105 throw NumericError(
ErrorKind{
"Instability"}, std::string(who) +
": The polling system is unstable: rho >= 1.");
107 for (std::size_t m = 0; m < M; ++m) {
108 s2[m] = s_var[m] + s_mean[m] * s_mean[m];
109 if (s_mean[m] != zero) anysw =
true;
112 throw InputError(
ErrorKind{
"Argument"}, std::string(who) +
": polling_qsys_table needs a positive total switchover time per cycle.");
115 std::vector<T> y1(n), y2(n);
116 for (std::size_t q = 0; q < n; ++q) {
121 const T omr = one - rho1[q];
123 y2[q] = b2[q] / (omr * omr * omr);
127 const std::size_t N = n + n * n;
129 const auto Sidx = [n](std::size_t i, std::size_t j) {
return n + j * n + i; };
131 const auto step = [&](
const std::vector<T>& zi, std::size_t q, std::size_t m) {
132 std::vector<T>
lp(lambda);
133 if (!gated)
lp[q] = zero;
135 const T Sqq = zi[Sidx(q, q)];
136 const T EV = y1[q] * muq;
137 const T EV2 = muq * (y2[q] - y1[q] * y1[q]) + Sqq * y1[q] * y1[q];
138 std::vector<T> mu1(n);
139 for (std::size_t i = 0; i < n; ++i) mu1[i] = (i == q ? zero : zi[i]) +
lp[i] * y1[q] * muq;
140 std::vector<T> zo(N, zero);
141 for (std::size_t j = 0; j < n; ++j) {
142 for (std::size_t i = 0; i < n; ++i) {
143 const T DSD = (i != q && j != q) ? zi[Sidx(i, j)] : zero;
144 const T DSq = (i != q) ? zi[Sidx(i, q)] : zero;
145 const T SqD = (j != q) ? zi[Sidx(q, j)] : zero;
146 T s1v = DSD + DSq * y1[q] *
lp[j] +
lp[i] * y1[q] * SqD +
lp[i] *
lp[j] * EV2;
147 if (i == j) s1v +=
lp[i] * EV;
148 T s2v = s1v + mu1[i] * lambda[j] * s_mean[m] + lambda[i] * mu1[j] * s_mean[m] +
149 lambda[i] * lambda[j] * s2[m];
150 if (i == j) s2v += lambda[i] * s_mean[m];
151 zo[Sidx(i, j)] = s2v;
154 for (std::size_t i = 0; i < n; ++i) zo[i] = mu1[i] + lambda[i] * s_mean[m];
158 std::vector<Matrix<T> > A(M,
Matrix<T>(N, N, zero));
159 std::vector<std::vector<T> > c(M);
160 for (std::size_t m = 0; m < M; ++m) {
161 const std::size_t q = table[m] - 1;
162 c[m] = step(std::vector<T>(N, zero), q, m);
163 for (std::size_t k = 0; k < N; ++k) {
164 std::vector<T> e(N, zero);
166 const std::vector<T> col = step(e, q, m);
167 for (std::size_t r = 0; r < N; ++r) A[m](r, k) = col[r] - c[m][r];
170 const auto matvec = [N, zero](
const Matrix<T>& X,
const std::vector<T>& v) {
171 std::vector<T> out(N, zero);
172 for (std::size_t r = 0; r < N; ++r)
173 for (std::size_t k = 0; k < N; ++k) out[r] += X(r, k) * v[k];
178 for (std::size_t r = 0; r < N; ++r) Acyc(r, r) = one;
179 std::vector<T> ccyc(N, zero);
180 for (std::size_t m = 0; m < M; ++m) {
181 std::vector<T>
nc = matvec(A[m], ccyc);
182 for (std::size_t r = 0; r < N; ++r)
nc[r] += c[m][r];
185 for (std::size_t r = 0; r < N; ++r)
186 for (std::size_t k = 0; k < N; ++k) {
188 for (std::size_t l = 0; l < N; ++l) s += A[m](r, l) * Acyc(l, k);
194 for (std::size_t r = 0; r < N; ++r)
195 for (std::size_t k = 0; k < N; ++k) IA(r, k) = (r == k ? one : zero) - Acyc(r, k);
196 std::vector<std::vector<T> > z(M);
197 z[0] =
solve(IA, ccyc);
198 for (std::size_t m = 0; m + 1 < M; ++m) {
199 z[m + 1] = matvec(A[m], z[m]);
200 for (std::size_t r = 0; r < N; ++r) z[m + 1][r] += c[m][r];
204 out.
EX.assign(M, std::vector<T>(n, zero));
206 for (std::size_t m = 0; m < M; ++m)
207 for (std::size_t i = 0; i < n; ++i) {
208 out.
EX[m][i] = z[m][i];
209 for (std::size_t j = 0; j < n; ++j)
210 out.
EX2[m](i, j) = (z[m][Sidx(i, j)] + z[m][Sidx(j, i)]) / two;
212 out.
W.assign(n, zero);
213 for (std::size_t i = 0; i < n; ++i) {
214 T num = zero, den = zero;
215 for (std::size_t m = 0; m < M; ++m) {
216 if (table[m] != i + 1)
continue;
217 num += out.
EX2[m](i, i) - out.
EX[m][i];
220 const T resid = num / (two * lambda[i] * den);
222 out.
W[i] = (one + rho1[i]) * resid;
224 out.
W[i] = lambda[i] * b2[i] / (two * (one - rho1[i])) + resid;