5#ifndef LINE_API_MDD_MDD_TYPES_H
6#define LINE_API_MDD_MDD_TYPES_H
50 std::vector<std::vector<std::size_t>>
cols;
52 std::vector<std::vector<T>>
vals;
63 m.
cols.assign(d, std::vector<std::size_t>());
64 m.
vals.assign(d, std::vector<T>());
66 for (std::size_t i = 0; i < d; ++i) {
67 m.
cols[i].push_back(i);
68 m.
vals[i].push_back(one);
77 explicit Builder(std::size_t d) : dim_(d), rows_(d) {}
80 Builder&
add(std::size_t i, std::size_t j,
const T& value) {
82 if (value == zero)
return *
this;
83 if (i >= dim_ || j >= dim_)
84 throw InputError(
"MddLocalMatrix::Builder: index outside the level domain");
85 typename std::map<std::size_t, T>::iterator it = rows_[i].find(j);
86 if (it == rows_[i].end())
89 it->second = T(it->second + value);
97 m.
cols.assign(dim_, std::vector<std::size_t>());
98 m.
vals.assign(dim_, std::vector<T>());
100 for (std::size_t i = 0; i < dim_; ++i) {
104 for (
typename std::map<std::size_t, T>::const_iterator it = rows_[i].begin();
105 it != rows_[i].end(); ++it) {
106 m.
cols[i].push_back(it->first);
107 m.
vals[i].push_back(it->second);
111 m.
nnz += rows_[i].size();
118 std::vector<std::map<std::size_t, T>> rows_;
130 std::vector<std::size_t>
lev;
132 std::vector<MddLocalMatrix<T>>
W;
155typedef std::function<std::vector<std::vector<int>>(
const std::vector<int>&)>
MddNextState;
237 std::vector<std::vector<T>>
pik;
239 std::vector<std::vector<std::pair<int, int>>>
Mrows;
269 std::size_t i,
const std::string& caller) {
271 if (!given.empty()) {
272 std::vector<T> v = given;
274 for (std::size_t a = 0; a < v.size(); ++a) s += v[a];
275 for (std::size_t a = 0; a < v.size(); ++a) v[a] = T(v[a] / s);
278 std::vector<T> t0(h, zero);
280 std::size_t nlive = 0;
281 for (std::size_t a = 0; a < h; ++a) {
283 for (std::size_t b = 0; b < h; ++b) s += D1(a, b);
287 if (live < 0) live =
static_cast<long>(a);
291 std::vector<T> pie(h, zero);
295 const std::size_t l =
static_cast<std::size_t
>(live);
296 std::vector<T> first(h, zero);
297 for (std::size_t b = 0; b < h; ++b) first[b] = T(D1(l, b) / t0[l]);
302 for (std::size_t a = l + 1; a < h; ++a) {
303 if (!(t0[a] > zero))
continue;
304 for (std::size_t b = 0; b < h; ++b) {
307 if (d > 1e-9 || d < -1e-9)
308 throw InputError(caller +
": station " + std::to_string(i + 1) +
309 " carries a service law whose restart distribution depends "
310 "on the completing phase (a non-renewal MAP); the local "
311 "state names one entry law, so this encoding cannot "
Builder & add(std::size_t i, std::size_t j, const T &value)
Accumulate value into entry (i,j).
MddLocalMatrix< T > build() const
The exception types the port throws.
Dense matrix and non-owning view.
std::vector< T > mdd_entry_law(const std::vector< T > &given, const Matrix< T > &D1, std::size_t h, std::size_t i, const std::string &caller)
Entry law of a phase-type station, taken as given or derived from D1.
std::function< std::vector< std::vector< int > >(const std::vector< int > &)> MddNextState
Successor function over local indices, for mdd_reachset.
Number-type abstraction for the templated API port.
Kronecker rate descriptor of a structured model, the input of mdd_mcd.
MddNextState nextfun
Successor function over local indices.
std::vector< int > domain
Local domain per level.
std::vector< std::vector< double > > valuemap
valuemap[i][idx] is the physical occupancy of level i in local state idx.
std::vector< double > servers
Servers per station; infinite for a delay station.
std::vector< std::size_t > nphases
Phases per station, 1 when exponential.
int N
Closed population; the conservation law the level marginals must satisfy.
std::vector< T > mu
Station service rates, 1/E[S]; empty for a descriptor with no queueing parameters.
std::vector< double > invariant_weights
Optional conservation law as weights' * QLen = value, overriding the closed-population test.
std::vector< int > init
Initial local index per level.
double invariant_value
Value of the invariant when invariant_weights is set.
std::vector< MddEvent< T > > events
The events of the descriptor.
std::size_t K
Number of levels, i.e.
Matrix< T > P
Station-to-station routing matrix.
One event of the Kronecker rate descriptor.
std::size_t b
Station (or mode) the event arrives at, 0-based; equals a for an internal event.
std::size_t a
Station (or transition node) the event departs from, 0-based.
std::vector< MddLocalMatrix< T > > W
Local matrices at the levels named by lev.
std::vector< std::size_t > lev
Levels the event touches, as 0-based level indices, aligned with W.
A local rate matrix W_k^e of the Kronecker descriptor, held row-compressed.
static MddLocalMatrix< T > identity(std::size_t d)
The identity of the given order, used for a level an event does not touch.
std::vector< std::vector< T > > vals
vals[i] holds the values of the nonzeros of row i, aligned with cols[i].
std::size_t dim
Order of the (square) local matrix, i.e.
std::vector< std::vector< std::size_t > > cols
cols[i] holds the column indices of the nonzeros of row i.
std::size_t nnz
Total number of stored nonzeros.
std::vector< T > row_sum
row_sum[i] is the local enabling rate lambda[i].
Knobs of the level iteration in mdd_mcd.
std::vector< std::vector< double > > initpik
The reference's 'verbose' knob is NOT carried: it is a console trace of the level sizes and the itera...
double tol
Convergence tolerance on the level marginals.
int maxiter
Maximum coupled sweeps before the iteration is declared non-convergent.
Result of the Miner-Ciardo-Donatelli level aggregation.
std::vector< std::size_t > level_sizes
|M_k| per paper level.
bool no_aggregation
True certifies the result is EXACT with no reference solve needed; false means "not certified by this...
std::vector< std::vector< T > > pik
pik[k] is the level-k stationary vector over M_k, in paper orientation.
std::vector< std::vector< std::pair< int, int > > > Mrows
Mrows[k][r] = {node id, local value} of row r of M_k.
int iters
Fixed-point iterations performed.
std::vector< T > QLen
Mean occupancy per station (or place), in station order.
std::vector< double > paths_per_level
max |A(p)| per paper level: the largest number of distinct root-to-node paths at that level.
std::vector< T > X
Per-station throughput; empty when the descriptor carries no queueing parameters.
std::vector< T > U
Per-station utilization; empty when the descriptor carries no queueing parameters.
Phase-type service law of one station, as a Markovian (D0,D1) pair.
std::size_t phases() const
std::vector< T > pie
Optional entry law; empty to derive it from D1.
bool present
false marks "this station is exponential"