LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
sn_rtnodes_to_rtorig.h
Go to the documentation of this file.
1/*
2 * Copyright (c) 2012-2026, QORE Lab, Imperial College London
3 * All rights reserved.
4 */
5#ifndef LINE_API_SN_SN_RTNODES_TO_RTORIG_H
6#define LINE_API_SN_SN_RTNODES_TO_RTORIG_H
7
8/**
9 * @file
10 * @ingroup api_sn
11 * Port of matlab/src/api/sn/sn_rtnodes_to_rtorig.m.
12 *
13 * `sn.rtnodes` is over every node the refresh built, INCLUDING the artificial
14 * `CS_*` class-switch nodes that the routing expansion inserts. This recovers
15 * the routing over the ORIGINAL nodes by taking the stochastic complement over
16 * their rows, i.e. by eliminating the artificial ones rather than dropping
17 * them -- dropping would lose the class switch the node performs.
18 *
19 * The original nodes are those BEFORE the first `CS_` node, because the
20 * expansion appends. A model with no class switching therefore keeps every
21 * node and the complement is the identity operation on `rtnodes`.
22 *
23 * ARITHMETIC: field. dtmc_stochcomp is a linear solve.
24 */
25
26#include <cstddef>
27#include <string>
28#include <vector>
29
32#include "line/num/number.h"
33
34namespace line {
35namespace api {
36
37/** What sn_rtnodes_to_rtorig returns: the flat matrix and its per-class-pair blocks. */
38template <class T>
39struct SnRtOrig {
40 Matrix<T> rtorig; ///< (norig*nclasses) square
41 std::vector<std::vector<Matrix<T>>> cells; ///< cells[r][s] is (norig x norig)
42 std::size_t norig = 0; ///< nodes kept, the `csshift` of the reference
43};
44
45template <class T>
47 const T zero = num_traits<T>::from_int(0);
48 const std::size_t K = sn.nclasses, I = sn.nodes.size();
49 SnRtOrig<T> out;
50 std::size_t csshift = I;
51 for (std::size_t a = 0; a < I; ++a)
52 if (sn.nodes[a].name.compare(0, 3, "CS_") == 0) {
53 csshift = a;
54 break;
55 }
56 out.norig = csshift;
57 std::vector<std::size_t> keep;
58 keep.reserve(csshift * K);
59 for (std::size_t a = 0; a < csshift; ++a)
60 for (std::size_t r = 0; r < K; ++r) keep.push_back(a * K + r);
61 if (sn.rtnodes.rows() == I * K && !keep.empty()) {
62 out.rtorig = mc::dtmc_stochcomp(sn.rtnodes, keep);
63 } else {
64 out.rtorig = Matrix<T>(csshift * K, csshift * K, zero);
65 }
66 out.cells.assign(K, std::vector<Matrix<T>>(K, Matrix<T>(csshift, csshift, zero)));
67 for (std::size_t a = 0; a < csshift; ++a) {
68 if (sn.nodes[a].nodetype == qn::NodeType::Sink) continue;
69 for (std::size_t b = 0; b < csshift; ++b)
70 for (std::size_t r = 0; r < K; ++r)
71 for (std::size_t s = 0; s < K; ++s) {
72 const double v = num_traits<T>::to_double(out.rtorig(a * K + r, b * K + s));
73 if (v != v) continue; // the reference zeroes NaN before the copy
74 out.cells[r][s](a, b) = out.rtorig(a * K + r, b * K + s);
75 }
76 }
77 return out;
78}
79
80} // namespace api
81} // namespace line
82
83#endif // LINE_API_SN_SN_RTNODES_TO_RTORIG_H
A network plus its refreshed NetworkStruct.
Stochastic complement of a DTMC partition, a port of matlab/lib/kpctoolbox/mc/dtmc_stochcomp....
SnRtOrig< T > sn_rtnodes_to_rtorig(const qn::NetworkStruct< T > &sn)
Matrix< T > dtmc_stochcomp(const Matrix< T > &P, const std::vector< std::size_t > &keep)
Stochastic complement of a DTMC partition, a port of matlab/lib/kpctoolbox/mc/dtmc_stochcomp....
A queueing network and its refreshed NetworkStruct.
Number-type abstraction for the templated API port.
What sn_rtnodes_to_rtorig returns: the flat matrix and its per-class-pair blocks.
std::vector< std::vector< Matrix< T > > > cells
cells[r][s] is (norig x norig)
Matrix< T > rtorig
(norig*nclasses) square
std::size_t norig
nodes kept, the csshift of the reference