LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
ctmc_isfeasible.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_MC_CTMC_ISFEASIBLE_H
6
#define LINE_API_MC_CTMC_ISFEASIBLE_H
7
8
/**
9
* @file
10
* @ingroup api_mc
11
* Feasibility predicates for generators and stochastic matrices.
12
*
13
* Templated port of matlab/src/api/mc/ctmc_isfeasible.m and
14
* matlab/lib/kpctoolbox/mc/dtmc_isfeasible.m.
15
*
16
* The two return different things and that difference is deliberate. The CTMC
17
* predicate is a BOOLEAN at a caller-supplied tolerance. The DTMC one returns a
18
* PRECISION LEVEL: the largest tol in 1..15 at which the row sums are within
19
* 10^-tol of one and the entries are above -10^-tol, and 0 when no level holds.
20
* A caller that reads the DTMC result as a boolean is right by accident, since
21
* any nonzero level is truthy, but a caller that compares it to 1 is wrong.
22
*/
23
24
#include <cstddef>
25
26
#include "
line/num/number.h
"
27
#include "
line/util/error.h
"
28
#include "
line/util/matrix.h
"
29
30
namespace
line
{
31
namespace
mc
{
32
33
/** True when Q is square, has nonnegative off-diagonals, nonpositive diagonal and zero row sums. */
34
template
<
class
T>
35
bool
ctmc_isfeasible
(
const
Matrix<T>
& Q,
const
T& tol) {
36
const
std::size_t n = Q.
rows
();
37
if
(n == 0 || Q.
cols
() != n)
return
false
;
38
for
(std::size_t i = 0; i < n; ++i) {
39
T rowsum =
num_traits<T>::from_int
(0);
40
for
(std::size_t j = 0; j < n; ++j) {
41
if
(i != j && Q(i, j) < -tol)
return
false
;
42
rowsum += Q(i, j);
43
}
44
if
(Q(i, i) > tol)
return
false
;
45
if
(
num_abs
(rowsum) > tol)
return
false
;
46
}
47
return
true
;
48
}
49
50
/** Default tolerance 1e-10, matching the MATLAB signature. */
51
template
<
class
T>
52
bool
ctmc_isfeasible
(
const
Matrix<T>
& Q) {
53
return
ctmc_isfeasible
(Q,
num_traits<T>::from_double
(1e-10));
54
}
55
56
/** Largest precision level 1..15 at which P is stochastic, or 0 when none holds. */
57
template
<
class
T>
58
int
dtmc_isfeasible
(
const
Matrix<T>
& P) {
59
const
std::size_t n = P.
rows
();
60
if
(n == 0)
return
0;
61
T minsum =
num_traits<T>::from_int
(0), maxsum =
num_traits<T>::from_int
(0);
62
T minel = P(0, 0);
63
for
(std::size_t i = 0; i < n; ++i) {
64
T s =
num_traits<T>::from_int
(0);
65
for
(std::size_t j = 0; j < P.
cols
(); ++j) {
66
s += P(i, j);
67
if
(P(i, j) < minel) minel = P(i, j);
68
}
69
if
(i == 0 || s < minsum) minsum = s;
70
if
(i == 0 || s > maxsum) maxsum = s;
71
}
72
int
res = 0;
73
const
T one =
num_traits<T>::from_int
(1);
74
T eps =
num_traits<T>::from_int
(1);
75
const
T ten =
num_traits<T>::from_int
(10);
76
for
(
int
tol = 1; tol <= 15; ++tol) {
77
eps = eps / ten;
78
if
(minsum > one - eps && maxsum < one + eps && minel > -eps) res = tol;
79
}
80
return
res;
81
}
82
83
}
// namespace mc
84
}
// namespace line
85
86
#endif
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::mc
Definition
ctmc_bicgstab.h:59
line::mc::dtmc_isfeasible
int dtmc_isfeasible(const Matrix< T > &P)
Largest precision level 1..15 at which P is stochastic, or 0 when none holds.
Definition
ctmc_isfeasible.h:58
line::mc::ctmc_isfeasible
bool ctmc_isfeasible(const Matrix< T > &Q, const T &tol)
True when Q is square, has nonnegative off-diagonals, nonpositive diagonal and zero row sums.
Definition
ctmc_isfeasible.h:35
line
Definition
aoi_dist2ph.h:52
line::num_abs
T num_abs(const T &v)
Definition
number.h:172
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
include
line
api
mc
ctmc_isfeasible.h
Generated by
1.18.0