115 throw InputError(
"dpfqn_nc: the cycle must contain at least one node");
119 for (std::size_t j = 0; j < p.size(); ++j) {
120 if (!(p[j] > zero) || !(p[j] < one)) {
121 throw InputError(
"dpfqn_nc: service probabilities must be in the open interval (0,1)");
124 const std::size_t J = p.size();
126 for (std::size_t j = 0; j < J; ++j) {
127 x[j] = (one - p[j]) / p[j];
134 std::vector<std::vector<T> > Gt(N + 1, std::vector<T>(J + 1, zero));
135 for (std::size_t j = 0; j <= J; ++j) {
138 std::vector<T> G1(N + 1, zero);
141 for (std::size_t k = 1; k <= N; ++k) {
142 for (std::size_t j = 1; j <= J; ++j) {
143 Gt[k][j] = Gt[k][j - 1] + x[j - 1] * Gt[k - 1][j] + Gt[k - 1][j - 1];
149 for (std::size_t j = 1; j < J; ++j) {
152 G1[2] = s * Gt[0][0];
154 G1[k] = Gt[k - 1][J - 1] + x[J - 1] * G1[k - 1];
157 for (std::size_t j = 0; j <= J; ++j) {
163 for (std::size_t a = 0; a <= N; ++a) {
164 for (std::size_t b = 0; b <= J; ++b) {
165 Gt[a][b] = Gt[a][b] / mx;
207 throw InputError(
"dpfqn_ncld: P must be a non-empty matrix of service probabilities");
209 const std::size_t J = P.size();
215 out.
G.assign(1, one);
216 out.
W.assign(J, std::vector<T>(1, one));
221 for (std::size_t j = 0; j < J; ++j) {
222 if (P[j].size() < N) {
223 throw InputError(
"dpfqn_ncld: P must supply p_j(n) for every n = 1..N");
225 for (std::size_t n = 0; n < N; ++n) {
226 if (!(P[j][n] > zero) || P[j][n] > one) {
227 throw InputError(
"dpfqn_ncld: service probabilities must be in the interval (0,1]");
231 if (n + 1 < N && !(P[j][n] < one)) {
232 throw InputError(
"dpfqn_ncld: service probabilities below the population bound must be "
233 "strictly less than 1");
243 std::vector<double> shift(J, 0.0);
244 out.
W.assign(J, std::vector<T>(N + 1, zero));
245 out.
Wa.assign(J, std::vector<T>(N + 1, zero));
246 for (std::size_t j = 0; j < J; ++j) {
248 for (std::size_t n = 1; n <= N; ++n) {
249 const T q = (n >= 2) ? (one - P[j][n - 2]) : one;
250 out.
W[j][n] = out.
W[j][n - 1] * q / P[j][n - 1];
253 for (std::size_t n = 1; n <= N; ++n) {
254 if (out.
W[j][n] > mx) {
259 for (std::size_t n = 0; n <= N; ++n) {
260 out.
W[j][n] = out.
W[j][n] / mx;
262 out.
Wa[j][0] = out.
W[j][0];
263 for (std::size_t n = 1; n <= N; ++n) {
264 out.
Wa[j][n] = out.
W[j][n] * (one - P[j][n - 1]);
270 std::vector<std::vector<T> > pre(J + 1, std::vector<T>(N + 1, zero));
272 for (std::size_t j = 0; j < J; ++j) {
273 pre[j + 1] = detail::dt_conv(pre[j], out.
W[j], N);
275 std::vector<std::vector<T> > suf(J + 1, std::vector<T>(N + 1, zero));
277 for (std::size_t j = J; j-- > 0;) {
278 suf[j] = detail::dt_conv(suf[j + 1], out.
W[j], N);
281 out.
Gc.assign(J, std::vector<T>(N + 1, zero));
282 for (std::size_t j = 0; j < J; ++j) {
283 out.
Gc[j] = detail::dt_conv(pre[j], suf[j + 1], N);
287 for (std::size_t j = 0; j < J; ++j) {