88 const std::vector<T>& Z,
const T& tol,
int maxiter) {
89 const std::size_t M = L.
rows(), R = L.
cols();
90 if (M == 0 || R == 0)
throw InputError(
"pfqn_momlin: empty demand matrix");
91 if (N.size() != R)
throw InputError(
"pfqn_momlin: L and N disagree on the class count");
92 if (Z.size() != R)
throw InputError(
"pfqn_momlin: L and Z disagree on the class count");
93 if (maxiter < 1)
throw InputError(
"pfqn_momlin: maxiter must be at least one");
94 for (std::size_t r = 0; r < R; ++r)
95 if (N[r] < 0)
throw InputError(
"pfqn_momlin: pfqn_momlin supports closed classes only");
101 for (std::size_t r = 0; r < R; ++r)
102 for (std::size_t s = 0; s < R; ++s) {
112 std::vector<T> X(R, zero);
113 for (std::size_t r = 0; r < R; ++r)
115 for (std::size_t i = 0; i < M; ++i)
117 for (
int it = 0; it < maxiter; ++it) {
119 for (std::size_t r = 0; r < R; ++r) {
122 for (std::size_t i = 0; i < M; ++i)
Rm(i, r) = zero;
126 for (std::size_t i = 0; i < M; ++i) {
128 for (std::size_t s = 0; s < R; ++s) acc += c(r, s) * Q(i, s);
129 Rm(i, r) = L(i, r) * (one + acc);
132 const T den = Z[r] + Rtot;
133 if (den <= zero)
throw NumericError(
"pfqn_momlin: degenerate residence time");
135 for (std::size_t i = 0; i < M; ++i) Q(i, r) = X[r] *
Rm(i, r);
138 for (std::size_t i = 0; i < M; ++i)
139 for (std::size_t r = 0; r < R; ++r) {
140 const T d =
num_abs(T(Q(i, r) - Qold(i, r)));
153 for (std::size_t r = 0; r < R; ++r)
154 for (std::size_t i = 0; i < M; ++i) res.
U(i, r) = X[r] * L(i, r);
157 res.
dQ.assign(M * R * M * R, zero);
158 for (std::size_t j = 0; j < M; ++j) {
159 for (std::size_t s0 = 0; s0 < R; ++s0) {
160 if (N[s0] == 0)
continue;
162 for (
int it = 0; it < maxiter; ++it) {
164 for (std::size_t r = 0; r < R; ++r) {
165 if (N[r] == 0)
continue;
166 std::vector<T> dR(M, zero);
168 for (std::size_t i = 0; i < M; ++i) {
169 T acc = zero, dacc = zero;
170 for (std::size_t s = 0; s < R; ++s) {
171 acc += c(r, s) * Q(i, s);
172 dacc += c(r, s) * dq(i, s);
174 dR[i] = L(i, r) * dacc;
175 if (i == j && r == s0) dR[i] += one + acc;
179 for (std::size_t i = 0; i < M; ++i) dq(i, r) = dXr *
Rm(i, r) + X[r] * dR[i];
182 for (std::size_t i = 0; i < M; ++i)
183 for (std::size_t r = 0; r < R; ++r) {
184 const T d =
num_abs(T(dq(i, r) - dqold(i, r)));
189 for (std::size_t i = 0; i < M; ++i)
190 for (std::size_t r = 0; r < R; ++r)
191 res.
dQ[((i * R + r) * M + j) * R + s0] = dq(i, r);
196 res.
QCov.assign(M * R * M * R, zero);
197 for (std::size_t i = 0; i < M; ++i)
198 for (std::size_t r = 0; r < R; ++r)
199 for (std::size_t j = 0; j < M; ++j)
200 for (std::size_t s = 0; s < R; ++s) {
201 const std::size_t k = ((i * R + r) * M + j) * R + s;
202 res.
QCov[k] = L(j, s) * res.
dQ[k];
205 for (std::size_t i = 0; i < M; ++i)
206 for (std::size_t r = 0; r < R; ++r) res.
QVar(i, r) = res.
cov(i, r, i, r);
MomlinResult< T > pfqn_momlin(const Matrix< T > &L, const std::vector< int > &N, const std::vector< T > &Z, const T &tol, int maxiter)
Moment linearizer: approximate first and second queue-length moments of a large closed product-form n...