LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
pfqn_perm.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_API_PFQN_PERM_H
6
#define LINE_API_PFQN_PERM_H
7
8
/**
9
* @file
10
* @ingroup api_pfqn
11
* Permanent of a matrix with repeated columns, by Ryser's formula.
12
*
13
* Templated port of matlab/src/util/perm.m, which the pfqn family uses in two
14
* places: the joint queue-length probability pfqn_joint (through its local
15
* Fper) and the LCFS normalizing constant pfqn_lcfsqn_nc.
16
*
17
* For an (n x R) matrix A whose column k is repeated m_k times, n = sum_k m_k,
18
* the permanent of the expanded (n x n) matrix is
19
*
20
* perm = (-1)^n sum_{0 <= f <= m} (-1)^{|f|} prod_k C(m_k, f_k)
21
* prod_{i=1}^{n} sum_k f_k A(i,k),
22
*
23
* which costs prod_k (m_k + 1) evaluations rather than the n! of the
24
* definition. Collapsing the repeated columns is what makes the formula usable
25
* here at all: the queueing applications have n jobs but only R distinct
26
* classes, and R is small.
27
*
28
* Arithmetic: EXACT-CAPABLE. Additions, multiplications and integer binomials
29
* only; the binomials are formed by the exact Pascal recurrence of num_nck,
30
* not by the floating-point nck, so a large multiplicity does not lose
31
* integrality.
32
*/
33
34
#include <cstddef>
35
#include <vector>
36
37
#include "
line/num/number.h
"
38
#include "
line/util/error.h
"
39
#include "
line/util/matrix.h
"
40
#include "
line/util/population.h
"
41
42
namespace
line
{
43
namespace
pfqn
{
44
45
/**
46
* @brief Permanent of a matrix with repeated columns, by Ryser's formula.
47
*
48
* @param A (n x R) matrix, column k standing for m_k identical columns
49
* @param m (R) column multiplicities, summing to n
50
*/
51
template
<
class
T>
52
T
pfqn_perm
(
const
Matrix<T>
& A,
const
std::vector<int>& m) {
53
const
std::size_t R = m.size();
54
if
(A.
cols
() != R)
throw
InputError
(
"pfqn_perm: A and the multiplicities disagree in width"
);
55
int
n = 0;
56
for
(
int
v : m) {
57
if
(v < 0)
throw
InputError
(
"pfqn_perm: negative multiplicity"
);
58
n += v;
59
}
60
if
(
static_cast<
int
>
(A.
rows
()) != n)
61
throw
InputError
(
"pfqn_perm: A must have sum(m) rows"
);
62
const
T zero =
num_traits<T>::from_int
(0);
63
const
T one =
num_traits<T>::from_int
(1);
64
if
(n == 0)
return
one;
65
66
T val = zero;
67
std::vector<int> f(R, 0);
68
bool
more =
true
;
69
while
(more) {
70
int
fs = 0;
71
for
(
int
v : f) fs += v;
72
T term = (fs % 2 == 0) ? one : -one;
73
for
(std::size_t k = 0; k < R; ++k) term *= num_nck<T>(m[k], f[k]);
74
for
(std::size_t i = 0; i < static_cast<std::size_t>(n); ++i) {
75
T s = zero;
76
for
(std::size_t k = 0; k < R; ++k)
77
if
(f[k] != 0) s +=
num_traits<T>::from_int
(f[k]) * A(i, k);
78
term *= s;
79
}
80
val += term;
81
more =
next_pop
(f, m);
82
}
83
return
(n % 2 == 0) ? val : T(-val);
84
}
85
86
}
// namespace pfqn
87
}
// namespace line
88
89
#endif
// LINE_API_PFQN_PERM_H
line::InputError::InputError
InputError(const std::string &what)
Definition
error.h:39
line::Matrix
Definition
matrix.h:56
line::Matrix::cols
std::size_t cols() const
Definition
matrix.h:90
line::Matrix::rows
std::size_t rows() const
Definition
matrix.h:89
error.h
The exception types the port throws.
matrix.h
Dense matrix and non-owning view.
line::pfqn
Definition
cd_peak_scaling.h:43
line::pfqn::pfqn_perm
T pfqn_perm(const Matrix< T > &A, const std::vector< int > &m)
Permanent of a matrix with repeated columns, by Ryser's formula.
Definition
pfqn_perm.h:52
line
Definition
aoi_dist2ph.h:52
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
number.h
Number-type abstraction for the templated API port.
population.h
Population-vector enumeration and combinatorics.
line::num_traits
Definition
number.h:111
include
line
api
pfqn
pfqn_perm.h
Generated by
1.18.0