3#ifndef LINE_SOLVERS_TR_TRANSFORM_SOLVE_H
4#define LINE_SOLVERS_TR_TRANSFORM_SOLVE_H
81template <
class T,
class InnerSolve>
83 InnerSolve inner_solve,
84 const std::string& method) {
96 sn, d, chain.
QN, chain.
UN, chain.
RN, chain.
TN, chain.
XN);
143template <
class T,
class InnerSolve>
145 InnerSolve inner_solve,
146 const std::string& method,
147 std::size_t iter_max = 1000) {
148 const double kTol = 1e-10;
149 const double kFineTol = 1e-12;
156 const std::size_t R = dem.
Lchain.cols();
158 throw InputError(
"transform_solve_lc: the chain-aggregated model has a class count that "
159 "differs from its chain count; load concealment needs one class per chain");
163 std::vector<bool> is_delay(M,
false);
165 std::vector<double> Z(R, 0.0), N(R, 0.0);
166 for (std::size_t i = 0; i < M; ++i)
167 is_delay[i] = snChain.
stations[i].sched == qn::SchedStrategy::INF;
168 for (std::size_t r = 0; r < R; ++r) {
170 for (std::size_t i = 0; i < M; ++i) {
174 L(i, r) = dem.
Lchain(i, r);
179 std::vector<qn::NetworkStruct<T>> subs;
180 std::vector<std::vector<lang::Distrib<T>>> base(R);
182 for (std::size_t l = 0; l < R; ++l) {
186 for (std::size_t k = R; k >= 1; --k)
190 for (std::size_t i = 0; i < M; ++i)
191 if (!is_delay[i]) base[l][i] = m.
service[i][0];
198 std::vector<double> X(R, 0.0);
206 std::vector<T> Nv(R), Zv(R);
207 for (std::size_t r = 0; r < R; ++r) {
213 if (bk.
X.size() == R)
214 for (std::size_t r = 0; r < R; ++r) X[r] = num_traits<T>::to_double(bk.
X[r]);
215 }
catch (
const std::exception&) {
220 for (std::size_t r = 0; r < R; ++r) {
221 if (!std::isfinite(X[r]) || X[r] < 0) X[r] = 0.0;
222 double sum = Z[r], cap = 0.0;
223 for (std::size_t i = 0; i < M; ++i) {
226 cap = std::max(cap, l);
228 if (X[r] == 0.0 && N[r] > 0 &&
sum > 0) X[r] = N[r] /
sum;
229 if (cap > 0) X[r] = std::min(X[r], 1.0 / cap);
232 auto conceal_all = [&]() {
233 for (std::size_t l = 0; l < R; ++l)
234 for (std::size_t i = 0; i < M; ++i) {
235 if (is_delay[i])
continue;
237 for (std::size_t k = 0; k < R; ++k)
239 const double a = std::max(1.0 - busy, kFineTol);
248 std::vector<mva::AvgResult<T>> res(R);
249 std::vector<double> Xold(R, -1.0);
250 std::size_t iters = 0;
251 for (std::size_t it = 1; it <= std::max<std::size_t>(1, iter_max); ++it) {
253 for (std::size_t l = 0; l < R; ++l) {
254 res[l] = inner_solve(subs[l]);
258 if (!(X[l] >= 0)) X[l] = 0.0;
261 double diff = 0.0, scale = 1.0;
262 for (std::size_t r = 0; r < R; ++r) {
263 diff = std::max(diff, std::abs(X[r] - Xold[r]));
264 scale = std::max(scale, std::abs(X[r]));
267 if (diff <= kTol * scale)
break;
274 for (std::size_t l = 0; l < R; ++l) {
275 for (std::size_t i = 0; i < M && i < res[l].QN.rows(); ++i) {
276 Q(i, l) = res[l].QN(i, 0);
277 U(i, l) = res[l].UN(i, 0);
278 Rr(i, l) = res[l].RN(i, 0);
279 Tp(i, l) = res[l].TN(i, 0);
285 if (
sn.nchains >=
sn.nclasses) {
288 out.
QN = Q; out.
UN = U; out.
RN = Rr; out.
TN = Tp; out.
XN = Xc;
290 for (std::size_t l = 0; l < R; ++l) {
292 for (std::size_t i = 0; i < M; ++i) acc = acc + Rr(i, l);
299 out.
QN = cls.
Q; out.
UN = cls.
U; out.
RN = cls.
R;
300 out.
TN = cls.
Tp; out.
CN = cls.
C; out.
XN = cls.
X;
306 out.
iter =
static_cast<int>(iters);
A network plus its refreshed NetworkStruct.
std::vector< std::vector< Distrib< T > > > service
service[i][r], 0-based station and class; a disabled entry marks a pair never visited.
std::vector< Station< T > > stations
stations[k-1] is the k-th station
Rate-scaled copy of a distribution, preserving its shape.
ChainAggregationResult< T > sn_aggregate_chains(const qn::NetworkStruct< T > &sn, const std::string &suffix=std::string())
Collapse every chain onto one class, port of ModelAdapter.aggregateChains.
qn::NetworkStruct< T > sn_remove_class(const qn::NetworkStruct< T > &sn, std::size_t cls)
The model without class cls (1-based), leaving sn untouched.
Distrib< T > dist_scale_rate(const Distrib< T > &d, const T &factor)
The law of X / factor, in the same family as d.
Matrix< T > sn_get_residt_from_respt(const qn::NetworkStruct< T > &L, const Matrix< T > &RN)
Port of sn_get_residt_from_respt: the per-JOB residence time.
ClassResults< T > sn_deaggregate_chain_results(const qn::NetworkStruct< T > &L, const ChainDemands< T > &d, const Matrix< T > &Qchain, const Matrix< T > &Uchain, const Matrix< T > &Rchain, const Matrix< T > &Tchain, const std::vector< T > &Xchain)
Port of sn_deaggregate_chain_results.
Matrix< T > sn_get_arvr_from_tput(const qn::NetworkStruct< T > &L, const Matrix< T > &TN)
ChainDemands< T > sn_get_demands_chain(const qn::NetworkStruct< T > &L)
Port of sn_get_demands_chain.
BkResult< T > pfqn_bk(const Matrix< T > &L, const std::vector< T > &N, const std::vector< T > &Z)
Birman-Kogan saddle point normalizing constant with bottleneck detection.
mva::AvgResult< T > transform_solve_lc(const qn::NetworkStruct< T > &sn, InnerSolve inner_solve, const std::string &method, std::size_t iter_max=1000)
LOAD CONCEALMENT (Birman-Kogan Algorithm 2) as a transformation, and the first ITERATED one.
mva::AvgResult< T > transform_solve_chains(const qn::NetworkStruct< T > &sn, InnerSolve inner_solve, const std::string &method)
Chain aggregation: collapse every chain onto a single class, solve, and map the chain metrics back on...
A queueing network and its refreshed NetworkStruct.
Birman-Kogan asymptotic evaluation of closed networks with many stations.
Collapse every chain onto one class, port of ModelAdapter.aggregateChains.
Chain aggregation and de-aggregation.
Drop one job class from a model, port of ModelAdapter.removeClass.
The SolverMVA class surface: @@SolverMVA/runAnalyzer.m and the gates around it.
What sn_aggregate_chains returns.
qn::Network< T > model
the aggregate, one class per chain
The metrics getAvg returns, after filtering.
Matrix< T > RN
response time, per visit
Matrix< T > UN
utilization
Matrix< T > WN
residence time, per job
std::string method
the method asked for
std::string actualmethod
the algorithm that ran
Matrix< T > QN
queue length
std::vector< T > CN
system response time per class
std::vector< T > XN
system throughput per class
Matrix< T > AN
arrival rate
The chain-level view of a layer, as sn_get_demands_chain returns it.
std::vector< double > Nchain
(C) population, infinite for an open chain
Matrix< T > Lchain
(M x C) demand
Class-level results, as sn_deaggregate_chain_results returns them.
Return value of pfqn_bk, mirroring [G, lG, X, U, A, B].
std::vector< T > X
the saddle point coordinates