LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Loading...
Searching...
No Matches
sn_print_routing_matrix.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_PRINT_ROUTING_MATRIX_H
6#define LINE_API_SN_SN_PRINT_ROUTING_MATRIX_H
7
8/**
9 * @file
10 * @ingroup api_sn
11 * The human-readable form of `sn.rtnodes`: one line per positive (node, class)
12 * to (node, class) edge.
13 *
14 * Port of matlab/src/api/sn/sn_print_routing_matrix.m. A Cache's outgoing
15 * probability is reported as
16 * "state-dependent" rather than as a number, because the number the refresh
17 * left there is a placeholder the cache fixed point later replaces; a Sink has
18 * no outgoing edge to report; and a class whose routing at that node is
19 * DISABLED is skipped even though the expanded matrix may carry a value for it.
20 *
21 * Returned as a string rather than printed, so a caller can route it to a log,
22 * a CLI or a test. `sn_print_routing_matrix` in the reference ends with a
23 * newline and so does this.
24 *
25 * ARITHMETIC: field, but the rendering is in double.
26 */
27
28#include <cstddef>
29#include <cstdio>
30#include <string>
31
33#include "line/num/number.h"
34
35namespace line {
36namespace api {
37
38/**
39 * @brief The human-readable form of `sn.rtnodes`: one line per positive
40 * (node, class) to (node, class) edge.
41 *
42 * @param onlyclass 1-based class index to restrict to, 0 for every class.
43 * The reference matches on the class NAME and keeps an edge when
44 * EITHER end names it, which is what the index test below reproduces.
45 */
46template <class T>
47std::string sn_print_routing_matrix(const qn::NetworkStruct<T>& sn, std::size_t onlyclass = 0) {
48 const std::size_t I = sn.nodes.size(), K = sn.nclasses;
49 std::string out;
50 if (sn.rtnodes.rows() != I * K) return out + "\n";
51 for (std::size_t i = 0; i < I; ++i)
52 for (std::size_t r = 0; r < K; ++r)
53 for (std::size_t j = 0; j < I; ++j)
54 for (std::size_t s = 0; s < K; ++s) {
55 if (!(num_traits<T>::to_double(sn.rtnodes(i * K + r, j * K + s)) > 0.0))
56 continue;
57 std::string pr;
58 if (sn.nodes[i].nodetype == qn::NodeType::Cache) {
59 pr = "state-dependent";
60 } else if (sn.nodes[i].nodetype == qn::NodeType::Sink) {
61 continue;
62 } else {
63 if (r < sn.nodes[i].routing.size() &&
64 sn.nodes[i].routing[r] == qn::RoutingStrategy::DISABLED)
65 continue;
66 char buf[64];
67 std::snprintf(buf, sizeof(buf), "%f",
68 num_traits<T>::to_double(sn.rtnodes(i * K + r, j * K + s)));
69 pr = buf;
70 }
71 if (onlyclass != 0 && r + 1 != onlyclass && s + 1 != onlyclass) continue;
72 out += "\n" + sn.nodes[i].name + " [" + sn.classes[r].name + "] => " +
73 sn.nodes[j].name + " [" + sn.classes[s].name + "] : Pr=" + pr;
74 }
75 out += "\n";
76 return out;
77}
78
79} // namespace api
80} // namespace line
81
82#endif // LINE_API_SN_SN_PRINT_ROUTING_MATRIX_H
A network plus its refreshed NetworkStruct.
std::string sn_print_routing_matrix(const qn::NetworkStruct< T > &sn, std::size_t onlyclass=0)
The human-readable form of sn.rtnodes: one line per positive (node, class) to (node,...
A queueing network and its refreshed NetworkStruct.
Number-type abstraction for the templated API port.