5#ifndef LINE_API_SN_SN_STATE_H
6#define LINE_API_SN_SN_STATE_H
58 std::vector<std::pair<T, std::vector<T>>> out;
59 out.reserve(state.size());
60 for (std::size_t isf = 0; isf < state.size(); ++isf) {
61 const std::size_t ind =
sn.stateful_nodes[isf];
86 const std::size_t M =
sn.nstations, R =
sn.nclasses;
88 std::vector<bool> declared(M,
false);
89 for (std::size_t i = 0; i < M; ++i) {
90 const std::size_t ind =
sn.station_to_node[i];
91 const typename std::map<std::size_t, Matrix<T>>::const_iterator ss =
92 sn.statespace.find(ind);
93 if (ss ==
sn.statespace.end() || ss->second.rows() != 1 || ss->second.cols() == 0)
continue;
94 std::vector<T> row(ss->second.cols());
95 for (std::size_t c = 0; c < ss->second.cols(); ++c) row[c] = ss->second(0, c);
98 std::pair<T, std::vector<T>> m;
101 }
catch (
const Error&) {
104 if (m.second.size() != R)
continue;
105 for (std::size_t r = 0; r < R; ++r) nir(i, r) = m.second[r];
108 for (std::size_t r = 0; r < R; ++r) {
109 const double pop =
sn.classes[r].population;
110 if (!std::isfinite(pop))
continue;
111 const std::size_t rs =
sn.classes[r].refstat;
112 if (rs >= 1 && rs <= M && !declared[rs - 1])
127 const std::size_t M =
sn.nstations, R =
sn.nclasses;
128 if (n.
rows() == 0 && s.
rows() != 0)
return false;
129 for (std::size_t i = 0; i < M; ++i) {
130 const std::size_t nd =
sn.station_to_node[i];
131 const bool is_place = nd != 0 &&
sn.nodes[nd - 1].nodetype == qn::NodeType::Place;
132 for (std::size_t r = 0; r < R; ++r) {
133 if (!is_place && !
sn.disabled.empty() &&
sn.disabled[i][r] &&
136 if (i <
sn.classcap.size() && r <
sn.classcap[i].size() &&
142 for (std::size_t i = 0; i < M; ++i) {
143 const std::size_t nd =
sn.station_to_node[i];
144 if (nd != 0 &&
sn.nodes[nd - 1].nodetype == qn::NodeType::Place)
continue;
145 if (!(
sn.stations[i].nservers > 0.0))
continue;
147 for (std::size_t r = 0; r < R; ++r) sums += num_traits<T>::to_double(s(i, r));
148 if (sums >
sn.stations[i].nservers) {
149 switch (sn.stations[i].sched) {
150 case qn::SchedStrategy::FCFS:
151 case qn::SchedStrategy::SIRO:
152 case qn::SchedStrategy::LCFS:
153 case qn::SchedStrategy::HOL:
154 case qn::SchedStrategy::POLLING: return false;
161 for (std::size_t a = 0; a < M; ++a)
162 for (std::size_t r = 0; r < R; ++r)
167 for (std::size_t c = 0; c <
sn.nchains; ++c) {
168 double njobs_chain = 0.0;
170 for (std::size_t r = 0; r < R; ++r) {
171 if (!
sn.chains[c][r])
continue;
172 if (std::isinf(
sn.classes[r].population)) open =
true;
173 njobs_chain +=
sn.classes[r].population;
175 if (open || std::isinf(njobs_chain))
continue;
176 double statejobs = 0.0;
177 for (std::size_t i = 0; i < M; ++i)
178 for (std::size_t r = 0; r < R; ++r)
179 if (sn.chains[c][r]) statejobs += num_traits<T>::to_double(n(i, r));
180 if (!(statejobs > 0.0))
return false;
198 const std::size_t M =
sn.nstations, R =
sn.nclasses;
200 for (std::size_t ist = 1; ist <= M; ++ist) {
201 const std::size_t isf =
sn.stateful_of_station(ist);
202 if (isf == 0 || isf > state.size())
return false;
203 const std::size_t ind =
sn.stateful_nodes[isf - 1];
205 std::vector<std::size_t> ph(R, 1), shift(R, 0);
206 for (std::size_t r = 0; r < R; ++r) {
211 for (std::size_t r = 0; r < R; ++r) {
212 n(ist - 1, r) = m.
nir[r];
213 s(ist - 1, r) = m.
sir[r];
Base error for the multiprecision C++ port.
A network plus its refreshed NetworkStruct.
The exception types the port throws.
bool sn_is_state_valid(const qn::NetworkStruct< T > &sn, const std::vector< std::vector< T > > &state)
Port of sn_is_state_valid: form the station marginals of state and test them.
Matrix< T > sn_declared_marginal(const qn::NetworkStruct< T > &sn)
The (nstations x nclasses) per-class job counts of the model's OWN state.
bool sn_state_counts_valid(const qn::NetworkStruct< T > &sn, const Matrix< T > &n, const Matrix< T > &s)
Port of State.isValid, which is the whole body of sn_is_state_valid once the marginals are formed.
std::vector< std::pair< T, std::vector< T > > > sn_get_state_aggr(const qn::NetworkStruct< T > &sn, const std::vector< std::vector< T > > &state)
Port of sn_get_state_aggr: the per-class job counts of each stateful node's state row,...
Marginal< T > to_marginal(const NetworkStruct< T > &sn, std::size_t ist, const std::vector< T > &state_i, const std::vector< std::size_t > &phasesz, const std::vector< std::size_t > &phaseshift, std::size_t nvar=0)
Port of State.toMarginal for a STATION, one state row at a time.
std::pair< T, std::vector< T > > to_marginal_aggr(const NetworkStruct< T > &sn, std::size_t ind, const std::vector< T > &state_i)
Port of State.toMarginalAggr: the job counts of one node's state row, without the per-phase detail to...
RowLayout< T > row_layout(const NetworkStruct< T > &sn, std::size_t ind, std::size_t width)
A queueing network and its refreshed NetworkStruct.
Number-type abstraction for the templated API port.
Port of the MATLAB +State package: the encoding that turns a station's state row into marginal job co...
Port of the event half of MATLAB's +State package: the successor states an event produces at one node...
static constexpr double CoarseTol
What State.toMarginal returns for one station and one state row.
std::vector< T > nir
jobs per class
std::vector< T > sir
jobs in service per class
How a station's state row splits into [buffer | server | local vars].
std::vector< std::size_t > Ks
offset of class r's phase block
std::size_t nvar
local-variable width
std::vector< std::size_t > K
phases per class