105 const std::size_t M = alpha.
rows(), N = alpha.
cols();
106 if (c.size() != M)
throw InputError(
"pfqn_fnc: the offset vector must have one entry per station");
109 const T inf = detail::num_inf_marker<T>();
112 for (std::size_t i = 0; i < M; ++i) {
113 const T d0 = T(one + c[i]);
114 if (d0 == zero)
throw NumericError(
"pfqn_fnc: offset -1 makes the first rate undefined");
115 mu(i, 0) = T(alpha(i, 0) / d0);
117 Matrix<T> anum(N + 1, N + 1, zero), aden(N + 1, N + 1, zero);
118 for (std::size_t n = 2; n <= N; ++n) {
119 anum(n, 1) = alpha(i, n - 1);
120 aden(n, 1) = alpha(i, n - 2);
121 for (std::size_t k = 2; k + 1 <= n; ++k) {
122 anum(n, k) = T(anum(n, k - 1) * alpha(i, n - k));
123 aden(n, k) = T(aden(n, k - 1) * alpha(i, n - k - 1));
126 for (std::size_t n = 2; n <= N; ++n) {
127 T rho = zero, muden = one;
129 for (std::size_t k = 1; k + 1 <= n; ++k) {
130 muden *= mu(i, k - 1);
135 rho += T(T(anum(n, k) - aden(n, k)) / muden);
137 if (bad || T(one - rho) == zero) {
141 T v = T(anum(n, n - 1) * alpha(i, 0) / muden);
142 v = T(v / T(one - rho));
148 const double big = 1e15;
149 for (std::size_t i = 0; i < M; ++i) {
150 for (std::size_t n = 0; n < N; ++n) {
152 if (std::isnan(v) || std::fabs(v) > big) mu(i, n) = inf;
154 for (std::size_t n = 0; n < N; ++n) {
155 if (detail::is_inf_marker(mu(i, n))) {
156 for (std::size_t k = n; k < N; ++k) mu(i, k) = inf;