5#ifndef LINE_SOLVERS_CTMC_SOLVER_CTMC_PROB_H
6#define LINE_SOLVERS_CTMC_SOLVER_CTMC_PROB_H
69 " is unavailable: the model has a matrix-exponential (ME) service or arrival "
70 "process, so the stationary vector of the generator is a signed measure and "
71 "per-state probabilities and uniformization-based transients do not exist. "
72 "Mean measures (getAvg, getAvgTable) remain exact");
75namespace prob_detail {
79std::vector<T> align(
const std::vector<T>& row, std::size_t width) {
80 if (row.size() >= width)
return row;
82 out.insert(out.end(), row.begin(), row.end());
88std::vector<T> marginal_of(
const NetworkStruct<T>& sn, std::size_t ind,
89 const std::vector<T>& row) {
90 const std::size_t R = sn.nclasses;
91 const std::size_t ist = sn.nodes[ind - 1].station;
95 return std::vector<T>(row.begin(), row.begin() + std::min(R, row.size()));
97 std::vector<std::size_t> ph(R, 1), shift(R, 0);
99 for (std::size_t r = 0; r < R; ++r) {
100 ph[r] = sn.phasessz_of(ist, r + 1);
122 for (std::size_t f = 0; f < q.
local.size() && f < d.
chain.space[0].local.size(); ++f)
123 q.
local[f] = prob_detail::align(q.
local[f], d.
chain.space[0].local[f].size());
124 const std::vector<double> key = ctmc_detail::state_key(q);
125 for (std::size_t s = 0; s < d.
chain.space.size(); ++s)
126 if (ctmc_detail::state_key(d.
chain.space[s]) == key)
return d.
pi[s];
138 const std::vector<std::size_t>& sfn =
sn.stateful_nodes;
139 std::vector<std::vector<T>> want(sfn.size());
140 for (std::size_t f = 0; f < sfn.size(); ++f)
141 want[f] = prob_detail::marginal_of(
sn, sfn[f], state.
local[f]);
144 for (std::size_t s = 0; s < d.
chain.space.size(); ++s) {
146 for (std::size_t f = 0; f < sfn.size() && same; ++f) {
147 const std::vector<T> got =
148 prob_detail::marginal_of(
sn, sfn[f], d.
chain.space[s].local[f]);
149 if (got.size() != want[f].size()) { same =
false;
break; }
150 for (std::size_t r = 0; r < got.size(); ++r)
154 if (same) acc += d.
pi[s];
170 std::vector<T> out(
sn.nstations, zero);
171 for (std::size_t ist = 1; ist <=
sn.nstations; ++ist) {
172 const std::size_t isf =
sn.stateful_of_station(ist);
173 if (isf == 0)
continue;
174 const std::vector<T> want =
175 prob_detail::align(state.
local[isf - 1], d.
chain.space[0].local[isf - 1].size());
176 for (std::size_t s = 0; s < d.
chain.space.size(); ++s)
177 if (d.
chain.space[s].local[isf - 1] == want) out[ist - 1] += d.
pi[s];
195 std::vector<T> out(
sn.nstations, zero);
196 for (std::size_t ist = 1; ist <=
sn.nstations; ++ist) {
197 const std::size_t isf =
sn.stateful_of_station(ist);
198 const std::size_t ind =
sn.node_of_station(ist);
199 if (isf == 0)
continue;
200 const std::vector<T> want = prob_detail::marginal_of(
sn, ind, state.
local[isf - 1]);
201 for (std::size_t s = 0; s < d.
chain.space.size(); ++s) {
202 const std::vector<T> got =
203 prob_detail::marginal_of(
sn, ind, d.
chain.space[s].local[isf - 1]);
204 bool same = got.size() == want.size();
205 for (std::size_t r = 0; r < got.size() && same; ++r)
208 if (same) out[ist - 1] += d.
pi[s];
240 const std::vector<std::size_t>& nonimm,
241 const std::vector<std::size_t>& imm,
244 std::vector<T> r(nonimm.size(), zero);
245 for (std::size_t a = 0; a < nonimm.size(); ++a)
246 for (std::size_t j = 0; j < D.
cols(); ++j) r[a] += D(nonimm[a], j);
247 if (imm.empty())
return r;
249 std::vector<T> b(imm.size(), zero);
250 for (std::size_t a = 0; a < imm.size(); ++a)
251 for (std::size_t j = 0; j < D.
cols(); ++j) b[a] += D(imm[a], j);
253 for (std::size_t a = 0; a < Q22.
rows(); ++a)
254 for (std::size_t c = 0; c < Q22.
cols(); ++c) negQ22(a, c) = T(-Q22(a, c));
255 const std::vector<T> x =
solve(negQ22, b);
256 for (std::size_t a = 0; a < nonimm.size() && a < Q12.
rows(); ++a)
257 for (std::size_t c = 0; c < Q12.
cols() && c < x.size(); ++c) r[a] += T(Q12(a, c) * x[c]);
UnsupportedError(const std::string &what)
A network plus its refreshed NetworkStruct.
The exception types the port throws.
LU factorization with partial pivoting, templated on the number type.
Dense matrix and non-owning view.
void assert_phase_type_states(const NetworkStruct< T > &sn, const std::string &what)
Port of @@SolverCTMC/assertPhaseTypeStates: refuse a query whose answer would be a per-state probabil...
T solver_ctmc_jointaggr(const NetworkStruct< T > &sn, const CtmcSolution< T > &d, const NetState< T > &state)
Port of solver_ctmc_jointaggr: P(the network holds exactly these per-class counts),...
std::vector< T > solver_ctmc_margaggr(const NetworkStruct< T > &sn, const CtmcSolution< T > &d, const NetState< T > &state)
Port of solver_ctmc_margaggr: per STATION, P(that station holds exactly these per-class counts).
std::vector< T > solver_ctmc_marg(const NetworkStruct< T > &sn, const CtmcSolution< T > &d, const NetState< T > &state)
Port of solver_ctmc_marg: per STATION, P(that station is in exactly its local slice of state),...
T solver_ctmc_joint(const NetworkStruct< T > &sn, const CtmcSolution< T > &d, const NetState< T > &state)
Port of solver_ctmc_joint: P(the network is in exactly state).
std::vector< T > solver_ctmc_ratecomplement(const Matrix< T > &D, const std::vector< std::size_t > &nonimm, const std::vector< std::size_t > &imm, const Matrix< T > &Q12, const Matrix< T > &Q22)
Port of solver_ctmc_ratecomplement: the long-run rate of an action as seen from each TANGIBLE state,...
bool ctmc_all_phasetype(const NetworkStruct< T > &sn)
MATLAB's all(sn.isph(:)), read off the matrices instead of off a flag.
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::vector< T > solve(const Matrix< T > &A, const std::vector< T > &b)
Convenience: solve Ax = b, leaving A and b untouched.
A queueing network and its refreshed NetworkStruct.
Port of solver_ctmc_analyzer.m and the parts of @@SolverCTMC/runAnalyzer.m that surround one solve: t...
Port of the MATLAB +State package: the encoding that turns a station's state row into marginal job co...
Everything one CTMC solve produces.
std::vector< T > pi
stationary distribution over chain.space
One network state: the per-stateful-node local rows it is composed of.
std::vector< std::vector< T > > local
local[isf] is that node's state row