5#ifndef LINE_API_MAPQN_MAPQN_PARAMS_H
6#define LINE_API_MAPQN_MAPQN_PARAMS_H
49 std::vector<Matrix<T>>
mu;
50 std::vector<Matrix<T>>
v;
57 if (
M <= 0)
throw InputError(
"mapqn: M must be positive");
58 if (
N < 0)
throw InputError(
"mapqn: N must be nonnegative");
59 if (
static_cast<int>(
K.size()) !=
M)
throw InputError(
"mapqn: K has the wrong length");
60 if (
static_cast<int>(
mu.size()) !=
M ||
static_cast<int>(
v.size()) !=
M)
61 throw InputError(
"mapqn: mu and v must have one entry per queue");
62 for (
int i = 0; i <
M; ++i) {
63 if (
K[i] <= 0)
throw InputError(
"mapqn: every queue needs at least one phase");
64 const std::size_t k =
static_cast<std::size_t
>(
K[i]);
65 if (
mu[i].rows() != k ||
mu[i].cols() != k)
66 throw InputError(
"mapqn: mu{i} must be K(i) x K(i)");
67 if (
v[i].rows() != k ||
v[i].cols() != k)
68 throw InputError(
"mapqn: v{i} must be K(i) x K(i)");
70 if (
r.
rows() !=
static_cast<std::size_t
>(
M) ||
r.
cols() !=
static_cast<std::size_t
>(
M))
73 throw InputError(
"mapqn: alpha must have M rows");
90 if (n == 0)
return T();
92 if (!p.
alpha.empty() &&
static_cast<std::size_t
>(n) <= p.
alpha.cols())
93 alpha_val = p.
alpha(
static_cast<std::size_t
>(i),
static_cast<std::size_t
>(n - 1));
94 const std::size_t ki =
static_cast<std::size_t
>(k), hi =
static_cast<std::size_t
>(h);
96 const T base = p.
r(
static_cast<std::size_t
>(i),
static_cast<std::size_t
>(j)) * p.
mu[i](ki, hi);
97 return T(base * alpha_val);
99 const T base = p.
v[i](ki, hi) +
100 p.
r(
static_cast<std::size_t
>(i),
static_cast<std::size_t
>(i)) * p.
mu[i](ki, hi);
101 return T(base * alpha_val);
120 P2Index(
int m,
int n,
const std::vector<int>& k) :
M(m),
N(n),
K(k) {
121 cumK.assign(
static_cast<std::size_t
>(
M) + 1, 0);
122 for (
int i = 0; i <
M; ++i)
cumK[i + 1] =
cumK[i] +
K[i];
123 block =
static_cast<std::size_t
>(
N + 1) *
static_cast<std::size_t
>(
cumK[
M]);
127 std::size_t
half(
int i,
int ni,
int h)
const {
128 return static_cast<std::size_t
>(
N + 1) *
static_cast<std::size_t
>(
cumK[i]) +
129 static_cast<std::size_t
>(ni) *
static_cast<std::size_t
>(
K[i]) +
130 static_cast<std::size_t
>(h);
133 std::size_t
operator()(
int j,
int nj,
int k,
int i,
int ni,
int h)
const {
The exception types the port throws.
Dense matrix and non-owning view.
MapqnSense
Which direction the bound is taken in.
T mapqn_q(const MapqnParams< T > &p, int i, int j, int k, int h, int n)
q(i,j,k,h,n): rate at which queue i, holding n jobs and in phase k, moves to phase h while routing a ...
Number-type abstraction for the templated API port.
Parameters of a MAP queueing network for the QR bounds.
Matrix< T > r
M x M routing probabilities.
std::vector< Matrix< T > > mu
mu[i] is K(i) x K(i), completion rates
std::vector< int > K
K[i] = number of phases at queue i.
T Z
think time (delay model only)
Matrix< T > alpha
M x N load-dependent scalings, 1 beyond the table.
T D1
service demand at queue 1 (delay model only)
std::vector< Matrix< T > > v
v[i] is K(i) x K(i), background rates
Result of a QR bound solve.
std::string status
textual LP status
std::vector< T > x
full solution vector, indexed by P2Index
std::vector< Matrix< T > > p2marginals
p2marginals[j](nj, k) = p2(j,nj,k,j,nj,k)
bool ok
the LP reached an optimal vertex
P2Index(int m, int n, const std::vector< int > &k)
std::size_t num_vars() const
std::size_t block
(N+1) * sum_i K(i)
std::size_t operator()(int j, int nj, int k, int i, int ni, int h) const
std::size_t half(int i, int ni, int h) const
Half-index of (queue, population, phase); identical for both halves.
std::vector< int > cumK
cumK[i] = sum_{i' < i} K(i')