5#ifndef LINE_API_MAM_MMAP_ASSEMBLE_H
6#define LINE_API_MAM_MMAP_ASSEMBLE_H
53 if (n == 0)
throw InputError(
"mmap_exponential_vec: order must be positive");
57 for (std::size_t c = 0; c < lambda.size(); ++c) {
59 for (std::size_t i = 0; i < n; ++i) Dc(i, n - 1 - i) = lambda[c];
60 for (std::size_t i = 0; i < n; ++i)
61 for (std::size_t j = 0; j < n; ++j) m.
D1(i, j) += Dc(i, j);
74 const std::size_t K = prob.
rows(), R = prob.
cols();
76 throw InputError(
"mmap_mark_probs: the probability matrix has more input types than the "
81 const std::size_t n = in.
order();
82 for (std::size_t r = 0; r < R; ++r) {
84 for (std::size_t k = 0; k < K; ++k)
85 for (std::size_t i = 0; i < n; ++i)
86 for (std::size_t j = 0; j < n; ++j) Dr(i, j) += in.
Dc[k](i, j) * prob(k, r);
104 const std::size_t C = in.
classes();
105 if (M.size() != C)
throw InputError(
"mmap_scale_perclass: one target mean per class is needed");
110 for (std::size_t c = 0; c < C; ++c) {
113 for (std::size_t i = 0; i < Dc.
rows(); ++i)
114 for (std::size_t j = 0; j < Dc.
cols(); ++j) {
116 s.
D1(i, j) += Dc(i, j);
123namespace mmap_super_detail {
127double arrival_norm(
const Mmap<T>& m) {
129 for (std::size_t j = 0; j < m.D1.cols(); ++j) {
131 for (std::size_t i = 0; i < m.D1.rows(); ++i)
133 if (col > best) best = col;
140Mmap<T> to_poisson(
const Mmap<T>& m) {
166 if (maxorder == 0)
throw InputError(
"mmap_super_safe: maxorder must be positive");
167 std::vector<Mmap<T>> parts;
169 if (m.order() == 0)
continue;
173 if (m.order() > 1 && mmap_super_detail::arrival_norm(m) < 1e-13)
179 if (parts.empty())
throw InputError(
"mmap_super_safe: no components to superpose");
181 std::vector<std::size_t> order(parts.size());
182 std::iota(order.begin(), order.end(), 0u);
188 std::vector<double> scv(parts.size());
189 for (std::size_t i = 0; i < parts.size(); ++i)
190 scv[i] = mmap_super_detail::arrival_norm(parts[i]) > 0.0
192 : std::numeric_limits<double>::infinity();
193 std::stable_sort(order.begin(), order.end(),
194 [&scv](std::size_t a, std::size_t b) { return scv[a] < scv[b]; });
199 std::vector<std::size_t> markbase(parts.size() + 1, 0);
200 for (std::size_t i = 0; i < parts.size(); ++i)
201 markbase[i + 1] = markbase[i] + parts[i].classes();
202 std::vector<std::size_t> outorder;
206 for (std::size_t idx : order) {
207 for (std::size_t j = 0; j < parts[idx].classes(); ++j)
208 outorder.push_back(markbase[idx] + j);
210 if (cur.
order() > maxorder) {
213 "mmap_super_safe: a component of order " + std::to_string(cur.
order()) +
214 " exceeds the order budget and the reference compresses it with "
215 "mamap2m_fit_gamma_fb_mmap, which is not ported to C++");
216 cur = mmap_super_detail::to_poisson(cur);
219 sup = (maxorder == 1) ? mmap_super_detail::to_poisson(cur) : cur;
224 if (sup.
order() * 2 <= maxorder)
226 "mmap_super_safe: the superposition exceeds the order budget and the "
227 "reference compresses the next component with mamap2m_fit_gamma_fb_mmap, "
228 "which is not ported to C++");
229 sup =
mmap_super(sup, mmap_super_detail::to_poisson(cur));
235 if (sup.
Dc.size() == outorder.size() &&
236 !std::is_sorted(outorder.begin(), outorder.end())) {
237 std::vector<Matrix<T>> reordered(outorder.size());
238 for (std::size_t j = 0; j < outorder.size(); ++j) reordered[outorder[j]] = sup.
Dc[j];
239 sup.
Dc.swap(reordered);
UnsupportedError(const std::string &what)
The exception types the port throws.
Dense linear algebra over the templated number type: products, identity, inverse, and powers.
Markovian arrival process descriptors: stationary vectors, rate, moments, autocorrelation and the ind...
Dense matrix and non-owning view.
Marked MAP (MMAP) algebra: per-class rates, class probabilities, superposition, normalization and sca...
Mmap< T > mmap_normalize(const Mmap< T > &in)
Clamp negative off-diagonal and per-class entries to zero and rebuild D1 and the diagonal of D0 from ...
Mmap< T > mmap_mark_probs(const Mmap< T > &in, const Matrix< T > &prob)
Re-mark an MMAP by a (K x R) probability matrix (mmap_mark.m): a type-k arrival is reported as class ...
Mmap< T > mmap_scale_perclass(const Mmap< T > &in, const std::vector< T > &M)
Retarget the per-class MEAN inter-arrival times (mmap_scale.m, vector form).
Mmap< T > mmap_exponential_vec(const std::vector< T > &lambda, std::size_t n=1)
Order-n MMAP with the given per-class arrival rates (mmap_exponential.m).
T map_scv(const Map< T > &m)
Squared coefficient of variation.
Mmap< T > mmap_super(const Mmap< T > &a, const Mmap< T > &b)
Superposition of two MMAPs: the phase process is the product chain, and the class list of the result ...
std::vector< T > mmap_count_lambda(const Mmap< T > &m)
Per-class arrival rates, lambda_c = theta D1^(c) e.
Mmap< T > mmap_super_safe(const std::vector< Mmap< T > > &in, std::size_t maxorder)
Order-bounded superposition of several MMAPs (mmap_super_safe.m).
Number-type abstraction for the templated API port.
An MMAP: the underlying MAP plus the per-class arrival matrices.
std::size_t classes() const
std::vector< Matrix< T > > Dc
per-class matrices, sum_c Dc = D1
std::size_t order() const