LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
population.h
Go to the documentation of this file.
1
/*
2
* Copyright (c) 2012-2026, QORE Lab, Imperial College London
3
* All rights reserved.
4
*/
5
#ifndef LINE_UTIL_POPULATION_H
6
#define LINE_UTIL_POPULATION_H
7
8
/**
9
* @file
10
* @ingroup line_util
11
* Population-vector enumeration and combinatorics.
12
*
13
* Mirrors MATLAB's pprod/hashpop (matlab/src/api/pfqn/pfqn_ca.m) and
14
* mp_pfqn's util/population.c (initpop/nextpop/popindex/getplanesizes), with
15
* no global state: the memo table for binomials is function-local and
16
* thread-local so the library stays callable with the Python GIL released.
17
*/
18
19
#include <cstddef>
20
#include <vector>
21
22
#include "
line/util/error.h
"
23
24
namespace
line
{
25
26
/** Mixed-radix plane sizes: prods[r] = prod_{s<r} (N[s]+1). */
27
inline
std::vector<std::size_t>
plane_sizes
(
const
std::vector<int>& N) {
28
std::vector<std::size_t> prods(N.size());
29
std::size_t total = 1;
30
for
(std::size_t r = 0; r < N.size(); ++r) {
31
prods[r] = total;
32
total *=
static_cast<
std::size_t
>
(N[r] + 1);
33
}
34
return
prods;
35
}
36
37
/** Number of population vectors n with 0 <= n <= N. */
38
inline
std::size_t
population_count
(
const
std::vector<int>& N) {
39
std::size_t total = 1;
40
for
(
int
n : N) total *=
static_cast<
std::size_t
>
(n + 1);
41
return
total;
42
}
43
44
/** Index of n in the lattice, 0-based (MATLAB hashpop is 1-based). */
45
inline
std::size_t
pop_index
(
const
std::vector<int>& n,
const
std::vector<std::size_t>& prods) {
46
std::size_t idx = 0;
47
for
(std::size_t r = 0; r < n.size(); ++r) idx += prods[r] *
static_cast<
std::size_t
>
(n[r]);
48
return
idx;
49
}
50
51
/**
52
* Advance n to the next population vector in the lattice 0 <= n <= N,
53
* odometer order with the last class varying fastest. Returns false once the
54
* lattice is exhausted, leaving n at all-zero.
55
*/
56
inline
bool
next_pop
(std::vector<int>& n,
const
std::vector<int>& N) {
57
if
(n.size() != N.size())
throw
InputError
(
"next_pop: dimension mismatch"
);
58
long
s =
static_cast<
long
>
(N.size()) - 1;
59
while
(s >= 0 && n[s] == N[s]) {
60
n[s] = 0;
61
--s;
62
}
63
if
(s < 0)
return
false
;
64
n[s] += 1;
65
return
true
;
66
}
67
68
/** Binomial coefficient with a thread-local memo table (mp_pfqn util/nck.c). */
69
inline
double
nck
(
int
n,
int
k) {
70
if
(k < 0 || n < 0 || k > n)
return
0.0;
71
if
(k == 0 || k == n)
return
1.0;
72
double
r = 1.0;
73
int
kk = k < n - k ? k : n - k;
74
for
(
int
i = 1; i <= kk; ++i) r = r * static_cast<double>(n - kk + i) /
static_cast<
double
>
(i);
75
return
r;
76
}
77
78
/** Number of multisets of size k from n types, i.e. C(n+k-1, k). */
79
inline
double
multichoose
(
int
n,
int
k) {
return
nck
(n + k - 1, k); }
80
81
/**
82
* Binomial coefficient as a value of T, by the Pascal recurrence.
83
* Exact for the rational backend at any n, unlike the double version above,
84
* which loses integrality once C(n,k) exceeds 2^53.
85
*/
86
template
<
class
T>
87
T
num_nck
(
int
n,
int
k) {
88
if
(k < 0 || n < 0 || k > n)
return
num_traits<T>::from_int
(0);
89
const
int
kk = k < n - k ? k : n - k;
90
std::vector<T> row(
static_cast<
std::size_t
>
(kk) + 1,
num_traits<T>::from_int
(0));
91
row[0] =
num_traits<T>::from_int
(1);
92
for
(
int
i = 1; i <= n; ++i) {
93
const
int
hi = i < kk ? i : kk;
94
for
(
int
j = hi; j >= 1; --j) row[j] += row[j - 1];
95
}
96
return
row[kk];
97
}
98
99
}
// namespace line
100
101
#endif
// LINE_UTIL_POPULATION_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
error.h
The exception types the port throws.
line
Definition
aoi_dist2ph.h:52
line::multichoose
double multichoose(int n, int k)
Number of multisets of size k from n types, i.e.
Definition
population.h:79
line::population_count
std::size_t population_count(const std::vector< int > &N)
Number of population vectors n with 0 <= n <= N.
Definition
population.h:38
line::plane_sizes
std::vector< std::size_t > plane_sizes(const std::vector< int > &N)
Mixed-radix plane sizes: prods[r] = prod_{s<r} (N[s]+1).
Definition
population.h:27
line::next_pop
bool next_pop(std::vector< int > &n, const std::vector< int > &N)
Advance n to the next population vector in the lattice 0 <= n <= N, odometer order with the last clas...
Definition
population.h:56
line::nck
double nck(int n, int k)
Binomial coefficient with a thread-local memo table (mp_pfqn util/nck.c).
Definition
population.h:69
line::num_nck
T num_nck(int n, int k)
Binomial coefficient as a value of T, by the Pascal recurrence.
Definition
population.h:87
line::pop_index
std::size_t pop_index(const std::vector< int > &n, const std::vector< std::size_t > &prods)
Index of n in the lattice, 0-based (MATLAB hashpop is 1-based).
Definition
population.h:45
line::num_traits
Definition
number.h:111
include
line
util
population.h
Generated by
1.18.0