5#ifndef LINE_API_NPFQN_TRAFFIC_SPLIT_CS_H
6#define LINE_API_NPFQN_TRAFFIC_SPLIT_CS_H
53using Mmap = std::vector<Matrix<T>>;
63void mmap_normalize(
Mmap<T>& M) {
64 if (M.empty())
return;
66 const std::size_t K = M[0].rows();
67 const std::size_t C = M.size() - 2;
69 for (std::size_t i = 0; i < K; ++i)
70 for (std::size_t j = 0; j < K; ++j)
71 if (i != j && M[0](i, j) < zero) M[0](i, j) = zero;
73 M[1] =
Matrix<T>(M[0].rows(), M[0].cols(), zero);
74 for (std::size_t c = 0; c < C; ++c) {
76 bool allNaN = Dc.
rows() > 0 && Dc.
cols() > 0;
77 for (std::size_t i = 0; i < Dc.
rows(); ++i)
78 for (std::size_t j = 0; j < Dc.
cols(); ++j) {
79 if (!num_isnan(Dc(i, j))) allNaN =
false;
80 if (Dc(i, j) < zero) Dc(i, j) = zero;
83 for (std::size_t i = 0; i < Dc.
rows(); ++i)
84 for (std::size_t j = 0; j < Dc.
cols(); ++j) M[1](i, j) += Dc(i, j);
87 for (std::size_t k = 0; k < K; ++k) {
90 for (std::size_t j = 0; j < M[0].cols(); ++j) s += M[0](k, j);
91 for (std::size_t j = 0; j < M[1].cols(); ++j) s += M[1](k, j);
107 if (MMAP.size() < 3)
throw InputError(
"npfqn_traffic_split_cs: MMAP has no marking matrices");
108 const std::size_t R = P.
rows();
109 const std::size_t J = P.
cols();
110 if (R == 0 || J % R != 0)
111 throw InputError(
"npfqn_traffic_split_cs: the class-switching matrix is not R x (M R)");
112 if (MMAP.size() - 2 != R)
113 throw InputError(
"npfqn_traffic_split_cs: MMAP and P disagree on the class count");
114 const std::size_t M = J / R;
117 const std::size_t n = MMAP[0].rows();
119 std::vector<Mmap<T>> SMMAP(M);
120 for (std::size_t jst = 0; jst < M; ++jst) {
122 S.assign(2 + R,
Matrix<T>(n, MMAP[0].cols(), zero));
124 for (std::size_t a = 0; a < n; ++a)
125 for (std::size_t b = 0; b < MMAP[0].cols(); ++b)
126 S[0](a, b) = MMAP[0](a, b) + MMAP[1](a, b);
127 for (std::size_t s = 0; s < R; ++s) {
128 for (std::size_t r = 0; r < R; ++r) {
129 const T& p = P(r, jst * R + s);
130 for (std::size_t a = 0; a < n; ++a)
131 for (std::size_t b = 0; b < MMAP[2 + r].cols(); ++b) {
132 const T v = MMAP[2 + r](a, b) * p;
139 detail::mmap_normalize(S);
The exception types the port throws.
Dense matrix and non-owning view.
std::vector< Mmap< T > > npfqn_traffic_split_cs(const Mmap< T > &MMAP, const Matrix< T > &P)
Splitting of a marked MAP departure flow with class switching.
std::vector< Matrix< T > > Mmap
An MMAP as the MATLAB cell {D0, D1, D1^(1), ..., D1^(R)}.
Shared arithmetic helpers for the templated npfqn port.
Number-type abstraction for the templated API port.