77 const std::function<T(
const std::vector<int>&)>& f) {
78 const std::size_t R = N.size();
79 if (R == 0)
throw InputError(
"pfqn_oi_fnc: empty population vector");
80 std::vector<std::size_t> shp(R), stride(R, 1);
81 std::size_t total = 1;
82 for (std::size_t d = 0; d < R; ++d) {
83 if (N[d] < 0)
throw InputError(
"pfqn_oi_fnc: negative population");
84 shp[d] =
static_cast<std::size_t
>(N[d]) + 1;
86 for (std::size_t d = 1; d < R; ++d) stride[d] = stride[d - 1] * shp[d - 1];
87 for (std::size_t d = 0; d < R; ++d) total *= shp[d];
88 if (Phi.size() != total)
throw InputError(
"pfqn_oi_fnc: numel(Phi) must equal prod(N+1)");
91 std::vector<std::vector<int>> subs(total, std::vector<int>(R, 0));
92 for (std::size_t i = 0; i < total; ++i) {
94 for (std::size_t d = 0; d < R; ++d) {
95 subs[i][d] =
static_cast<int>(li % shp[d]);
101 std::vector<T> Psi(total, zero);
102 for (std::size_t i = 0; i < total; ++i) {
103 const std::vector<int>& n = subs[i];
104 const T fv = f ? f(n) : [&]() {
109 T acc = T(T(one + fv) * Phi[i]);
110 for (std::size_t j = 0; j < i; ++j) {
111 const std::vector<int>& k = subs[j];
113 for (std::size_t d = 0; d < R && le; ++d)
114 if (k[d] > n[d]) le =
false;
117 for (std::size_t d = 0; d < R; ++d)
118 idx +=
static_cast<std::size_t
>(n[d] - k[d]) * stride[d];
119 acc -= Psi[j] * Phi[idx];
125 const T inf = detail::num_inf_marker<T>();
126 std::vector<T> mu(total, inf);
127 for (std::size_t i = 0; i < total; ++i) {
128 const std::vector<int>& n = subs[i];
130 for (
int v : n) tot += v;
135 if (Psi[i] == zero)
continue;
137 for (std::size_t r = 0; r < R; ++r)
138 if (n[r] > 0) num += Psi[i - stride[r]];
139 mu[i] = T(num / Psi[i]);
OiFncResult< T > pfqn_oi_fnc(const std::vector< T > &Phi, const std::vector< int > &N, const std::function< T(const std::vector< int > &)> &f)
Order-independent (OI) functional server: the balance function Psi and the rate mu_f of an auxiliary ...