LINE Solver (C++)
Templated C++ port of the LINE queueing solver
Toggle main menu visibility
Loading...
Searching...
No Matches
linalg.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_LINALG_H
6
#define LINE_UTIL_LINALG_H
7
8
/**
9
* @file
10
* @ingroup line_util
11
* Dense linear algebra over the templated number type: products, identity,
12
* inverse, and powers. Built on the LU in lu.h, so the exact instantiation
13
* inverts a rational matrix exactly, with no residual at all.
14
*/
15
16
#include <cstddef>
17
#include <vector>
18
19
#include "
line/num/number.h
"
20
#include "
line/util/error.h
"
21
#include "
line/util/lu.h
"
22
#include "
line/util/matrix.h
"
23
24
namespace
line
{
25
26
/** Identity of order n. */
27
template
<
class
T>
28
Matrix<T>
eye
(std::size_t n) {
29
Matrix<T>
I(n, n,
num_traits<T>::from_int
(0));
30
for
(std::size_t i = 0; i < n; ++i) I(i, i) =
num_traits<T>::from_int
(1);
31
return
I;
32
}
33
34
/** Matrix product A B. */
35
template
<
class
T>
36
Matrix<T>
matmul
(
const
Matrix<T>
& A,
const
Matrix<T>
& B) {
37
if
(A.
cols
() != B.
rows
())
throw
InputError
(
"matmul: inner dimensions disagree"
);
38
Matrix<T>
C(A.
rows
(), B.
cols
(),
num_traits<T>::from_int
(0));
39
for
(std::size_t i = 0; i < A.
rows
(); ++i)
40
for
(std::size_t k = 0; k < A.
cols
(); ++k) {
41
const
T a = A(i, k);
42
if
(a ==
num_traits<T>::from_int
(0))
continue
;
43
for
(std::size_t j = 0; j < B.
cols
(); ++j) C(i, j) += a * B(k, j);
44
}
45
return
C;
46
}
47
48
/** Row vector times matrix, v A. */
49
template
<
class
T>
50
std::vector<T>
vecmul
(
const
std::vector<T>& v,
const
Matrix<T>
& A) {
51
if
(v.size() != A.
rows
())
throw
InputError
(
"vecmul: dimensions disagree"
);
52
std::vector<T> r(A.
cols
(),
num_traits<T>::from_int
(0));
53
for
(std::size_t i = 0; i < v.size(); ++i) {
54
if
(v[i] ==
num_traits<T>::from_int
(0))
continue
;
55
for
(std::size_t j = 0; j < A.
cols
(); ++j) r[j] += v[i] * A(i, j);
56
}
57
return
r;
58
}
59
60
/** Matrix times column vector, A v. */
61
template
<
class
T>
62
std::vector<T>
mulvec
(
const
Matrix<T>
& A,
const
std::vector<T>& v) {
63
if
(v.size() != A.
cols
())
throw
InputError
(
"mulvec: dimensions disagree"
);
64
std::vector<T> r(A.
rows
(),
num_traits<T>::from_int
(0));
65
for
(std::size_t i = 0; i < A.
rows
(); ++i)
66
for
(std::size_t j = 0; j < A.
cols
(); ++j) r[i] += A(i, j) * v[j];
67
return
r;
68
}
69
70
/** Inverse by LU with one factorization and n back substitutions. */
71
template
<
class
T>
72
Matrix<T>
inverse
(
const
Matrix<T>
& A) {
73
const
std::size_t n = A.
rows
();
74
if
(A.
cols
() != n)
throw
InputError
(
"inverse: matrix is not square"
);
75
Matrix<T>
LU = A;
76
const
std::vector<std::size_t> piv =
lu_factor
(LU);
77
Matrix<T>
X(n, n,
num_traits<T>::from_int
(0));
78
for
(std::size_t c = 0; c < n; ++c) {
79
std::vector<T> e(n,
num_traits<T>::from_int
(0));
80
e[c] =
num_traits<T>::from_int
(1);
81
lu_solve
(LU, piv, e);
82
for
(std::size_t i = 0; i < n; ++i) X(i, c) = e[i];
83
}
84
return
X;
85
}
86
87
/** Integer matrix power, by repeated squaring. */
88
template
<
class
T>
89
Matrix<T>
matpow
(
const
Matrix<T>
& A,
unsigned
k) {
90
if
(A.
rows
() != A.
cols
())
throw
InputError
(
"matpow: matrix is not square"
);
91
Matrix<T>
R =
eye<T>
(A.
rows
());
92
Matrix<T>
B = A;
93
unsigned
e = k;
94
while
(e > 0) {
95
if
(e & 1u) R =
matmul
(R, B);
96
B =
matmul
(B, B);
97
e >>= 1;
98
}
99
return
R;
100
}
101
102
/** Column vector of ones, the ubiquitous e in MAP algebra. */
103
template
<
class
T>
104
std::vector<T>
ones
(std::size_t n) {
105
return
std::vector<T>(n,
num_traits<T>::from_int
(1));
106
}
107
108
}
// namespace line
109
110
#endif
// LINE_UTIL_LINALG_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.
lu.h
LU factorization with partial pivoting, templated on the number type.
matrix.h
Dense matrix and non-owning view.
line
Definition
aoi_dist2ph.h:52
line::lu_solve
void lu_solve(const Matrix< T > &LU, const std::vector< std::size_t > &piv, std::vector< T > &b)
Solve LUx = Pb in place on b, using the factors from lu_factor.
Definition
lu.h:94
line::vecmul
std::vector< T > vecmul(const std::vector< T > &v, const Matrix< T > &A)
Row vector times matrix, v A.
Definition
linalg.h:50
line::lu_factor
std::vector< std::size_t > lu_factor(Matrix< T > &A)
In-place LU of A (n x n).
Definition
lu.h:48
line::inverse
Matrix< T > inverse(const Matrix< T > &A)
Inverse by LU with one factorization and n back substitutions.
Definition
linalg.h:72
line::matmul
Matrix< T > matmul(const Matrix< T > &A, const Matrix< T > &B)
Matrix product A B.
Definition
linalg.h:36
line::mulvec
std::vector< T > mulvec(const Matrix< T > &A, const std::vector< T > &v)
Matrix times column vector, A v.
Definition
linalg.h:62
line::matpow
Matrix< T > matpow(const Matrix< T > &A, unsigned k)
Integer matrix power, by repeated squaring.
Definition
linalg.h:89
line::ones
std::vector< T > ones(std::size_t n)
Column vector of ones, the ubiquitous e in MAP algebra.
Definition
linalg.h:104
line::eye
Matrix< T > eye(std::size_t n)
Identity of order n.
Definition
linalg.h:28
number.h
Number-type abstraction for the templated API port.
line::num_traits
Definition
number.h:111
include
line
util
linalg.h
Generated by
1.18.0