98 const std::size_t K =
sn.nclasses;
101 "fluid mfq: the priority fluid queue needs a model of open classes flowing "
102 "Source -> Queue -> Sink and nothing else");
104 out.
QN.assign(K, 0.0);
105 out.
RN.assign(K, 0.0);
106 out.
TN.assign(K, 0.0);
107 out.
UN.assign(K, 0.0);
111 std::stable_sort(ord.begin(), ord.end(), [&
sn](std::size_t a, std::size_t b) {
112 return sn.classes[a].prio > sn.classes[b].prio;
114 const std::size_t Kc = ord.size();
117 out.
reason =
"invalid service rates";
122 std::vector<double> mu(Kc, 0.0);
123 for (std::size_t i = 0; i < Kc; ++i)
125 for (std::size_t i = 0; i < Kc; ++i)
126 if (!std::isfinite(mu[i]) || mu[i] <= 0.0) {
128 out.
reason =
"invalid service rates";
131 const double fine_tol = 1e-8;
132 for (std::size_t i = 0; i < Kc; ++i)
133 if (std::fabs(mu[i] - mu[0]) > fine_tol * std::max(1.0, mu[0])) {
135 out.
reason =
"class-dependent service";
138 const double d = mu[0];
141 std::vector<Matrix<double>> Qk(Kc), Rk(Kc);
142 std::vector<std::size_t> Nk(Kc, 0);
143 std::vector<double> lambda(Kc, 0.0);
144 for (std::size_t i = 0; i < Kc; ++i) {
146 const std::size_t n = arr.
D0.rows();
147 if (n == 0 || arr.
D1.rows() != n) {
149 out.
reason =
"non-MAP arrival";
154 for (std::size_t a = 0; a < n; ++a)
155 for (std::size_t b = 0; b < n; ++b) {
164 std::size_t Njoint = 1;
165 for (std::size_t i = 0; i < Kc; ++i) Njoint *= Nk[i];
168 out.
reason =
"non-modulated (exponential) arrivals";
174 for (std::size_t i = 0; i < Kc; ++i) {
176 for (std::size_t a = 0; a < Njoint; ++a)
177 for (std::size_t b = 0; b < Njoint; ++b) Qjoint(a, b) += term(a, b);
180 std::vector<Matrix<double>> ones_col(Kc);
181 for (std::size_t j = 0; j < Kc; ++j) ones_col[j] = Matrix<double>(Nk[j], 1, 1.0);
182 for (std::size_t i = 0; i < Kc; ++i) {
184 for (std::size_t j = 0; j < Kc; ++j) v =
mam::kron(v, (j == i) ? Rk[i] : ones_col[j]);
185 for (std::size_t a = 0; a < Njoint; ++a) Rjoint(i, a) = v(a, 0);
189 po.
prec = (tol > 0.0) ? tol : 1e-14;
191 for (std::size_t i = 1; i <= Kc; ++i) po.
classes.push_back(i);
200 }
catch (
const std::exception& e) {
206 for (std::size_t i = 0; i < Kc; ++i) {
207 const std::size_t k = ord[i];
210 out.
TN[k] = lambda[i];
211 out.
UN[k] = std::min(1.0, lambda[i] / d);