LINE Solver (C++)
Templated C++ port of the LINE queueing solver
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
24namespace line {
25
26/** Identity of order n. */
27template <class T>
28Matrix<T> eye(std::size_t n) {
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. */
35template <class T>
36Matrix<T> matmul(const Matrix<T>& A, const Matrix<T>& B) {
37 if (A.cols() != B.rows()) throw InputError("matmul: inner dimensions disagree");
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. */
49template <class T>
50std::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. */
61template <class T>
62std::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. */
71template <class T>
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);
78 for (std::size_t c = 0; c < n; ++c) {
79 std::vector<T> e(n, num_traits<T>::from_int(0));
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. */
88template <class T>
89Matrix<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. */
103template <class T>
104std::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
InputError(const std::string &what)
Definition error.h:39
std::size_t cols() const
Definition matrix.h:90
std::size_t rows() const
Definition matrix.h:89
The exception types the port throws.
LU factorization with partial pivoting, templated on the number type.
Dense matrix and non-owning view.
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
std::vector< T > vecmul(const std::vector< T > &v, const Matrix< T > &A)
Row vector times matrix, v A.
Definition linalg.h:50
std::vector< std::size_t > lu_factor(Matrix< T > &A)
In-place LU of A (n x n).
Definition lu.h:48
Matrix< T > inverse(const Matrix< T > &A)
Inverse by LU with one factorization and n back substitutions.
Definition linalg.h:72
Matrix< T > matmul(const Matrix< T > &A, const Matrix< T > &B)
Matrix product A B.
Definition linalg.h:36
std::vector< T > mulvec(const Matrix< T > &A, const std::vector< T > &v)
Matrix times column vector, A v.
Definition linalg.h:62
Matrix< T > matpow(const Matrix< T > &A, unsigned k)
Integer matrix power, by repeated squaring.
Definition linalg.h:89
std::vector< T > ones(std::size_t n)
Column vector of ones, the ubiquitous e in MAP algebra.
Definition linalg.h:104
Matrix< T > eye(std::size_t n)
Identity of order n.
Definition linalg.h:28
Number-type abstraction for the templated API port.