1#ifndef LINE_API_LOSSN_LOSSN_REC_H
2#define LINE_API_LOSSN_LOSSN_REC_H
90 const std::vector<int>& bound) {
91 const std::size_t K = bound.size();
92 const std::size_t J = C.size();
93 std::vector<int> domain(K);
94 for (std::size_t r = 0; r < K; ++r) domain[r] = bound[r] + 1;
96 const mdd::MddNextState nextfun = [&A, &C, &bound, K, J](
const std::vector<int>& s) {
97 std::vector<std::vector<int>> out;
98 for (std::size_t r = 0; r < K; ++r) {
99 if (s[r] >= bound[r])
continue;
100 std::vector<int> t = s;
103 for (std::size_t j = 0; j < J && ok; ++j) {
105 for (std::size_t q = 0; q < K; ++q)
109 if (ok) out.push_back(t);
122T lossn_rec_G(
const Matrix<T>& A,
const std::vector<T>& C,
const std::vector<int>& bound,
123 const std::vector<std::vector<T>>& g) {
125 for (std::size_t j = 0; j < C.size(); ++j)
126 if (C[j] < zero)
return zero;
142 const std::vector<T>& C) {
144 const std::size_t K = nu.size();
145 const std::size_t J = C.size();
148 " columns but there are " + std::to_string(K) +
" classes");
150 throw InputError(
"lossn_rec: A has " + std::to_string(A.
rows()) +
" rows but C has " +
151 std::to_string(J) +
" entries");
152 for (std::size_t j = 0; j < J; ++j)
153 for (std::size_t r = 0; r < K; ++r)
155 throw InputError(
"lossn_rec: the resource matrix A must be non-negative");
158 std::vector<int> bound(K, 0);
159 for (std::size_t r = 0; r < K; ++r) {
160 double b = std::numeric_limits<double>::infinity();
161 for (std::size_t j = 0; j < J; ++j)
165 if (!std::isfinite(b))
166 throw InputError(
"lossn_rec: class " + std::to_string(r + 1) +
167 " consumes no resource, so the admissible set is unbounded in that "
168 "coordinate and its normalising constant diverges");
169 bound[r] =
static_cast<int>(std::max(0.0, b));
172 std::vector<std::vector<T>> g(K);
173 for (std::size_t r = 0; r < K; ++r) {
174 g[r].assign(bound[r] + 1, one);
175 T fact = one, pw = one;
176 for (
int k = 0; k <= bound[r]; ++k) {
181 g[r][k] = T(pw / fact);
185 const T G = detail::lossn_rec_G<T>(A, C, bound, g);
187 throw InputError(
"lossn_rec: the admissible set is empty: no call of any class fits "
191 const mdd::MddStruct mdds = detail::lossn_rec_diagram<T>(A, C, bound);
194 out.
QLen.assign(K, zero);
195 out.
Loss.assign(K, zero);
196 for (std::size_t r = 0; r < K; ++r) {
199 for (std::size_t k = 0; k < pk.size(); ++k)
205 for (std::size_t r = 0; r < K; ++r) {
206 std::vector<T> Cr(J, zero);
208 for (std::size_t j = 0; j < J; ++j) {
209 Cr[j] = T(C[j] - A(j, r));
210 if (Cr[j] < zero) fits =
false;
216 const T Gr = detail::lossn_rec_G<T>(A, Cr, bound, g);
217 out.
Loss[r] = T(one - Gr / G);
218 if (out.
Loss[r] < zero) out.
Loss[r] = zero;
219 if (out.
Loss[r] > one) out.
Loss[r] = one;
The diagram: insert / member / index / enumerate / cardinality.
MddStruct to_struct() const
Export the diagram as plain arrays for downstream algorithms.
The exception types the port throws.
Dense matrix and non-owning view.
Reachability set generation into a decision diagram.
MDD-rec: the normalising constant of a product-form model whose reachable set is held in a decision d...
LossnRecResult< T > lossn_rec(const std::vector< T > &nu, const Matrix< T > &A, const std::vector< T > &C)
Exact loss-network analysis by MDD-rec.
std::function< std::vector< std::vector< int > >(const std::vector< int > &)> MddNextState
Successor function over local indices, for mdd_reachset.
T mdd_rec(const MddStruct &mdds, const std::vector< std::vector< T > > &g)
The normalising constant G = sum_{s in S} prod_l g_l(s_l).
MDD mdd_reachset(const std::vector< int > &domain, const std::vector< int > &init, const MddNextState &nextfun)
Generate and store the reachability set into a quasi-reduced ordered MDD.
std::vector< T > mdd_rec_marginal(const MddStruct &mdds, const std::vector< std::vector< T > > &g, std::size_t l)
Unnormalised masses of {s in S : s_l = k}, one per local value k of level l.
Number-type abstraction for the templated API port.
Carried load, blocking, log normalising constant and walk count.
double lG
log G(C), a double diagnostic.
T G
Normalising constant G(C).
std::vector< T > Loss
Blocking probability per class.
std::vector< T > QLen
Mean number of class-r calls in progress, the carried load.
int iterations
Number of diagram walks performed, K + 1.
Plain-array export of an MDD, the input contract of mdd_mcd.