Matrix library for C++20
A tiny C++20 general-purpose library for dense, fixed-size and dynamically-sized matrices with no dependencies.
Overview
Features:
- intuitive syntax
- low-overhead
- header-only and single-header
- fully constexpr (except where math functions like `sqrt` are used).
- STL-oriented
- Statically-sized have static memory (e.g. suited for audio development).
- Dynamically-sized matrices are now available as well.
- simple software design in comparison to some other matrix libs, e.g. no CRTP, virtual functions, ...
- fully tested. Tests can be run with Catch2.
Limitations:
- only C++20 (and up) because of heavy use of concepts and constexpr
- this is not a linear algebra library - at the moment the library provides no linear algebra algorithms such as decomposition and solvers
Sample Code (some possible operations)
Matrix<float, 3, 3> mat{ 1,2,3,4,5,6,7,8,9 };
auto mat2 = mat * 2.f - mat;
// Take sqrt of all entries
mat.apply([](float& f) {f = std::sqrtf(f); });
// Iterate over all entries (row first)
for (const auto& el : mat) {}
// Iterate over one row
for (const auto& el : mat.row(1)) {}
// Copy one row into another
mat.row(1) = mat.row(0);
// Copy matrix block into other matrix
mat2.block(1, 1, 2, 2) = mat.block(0, 0, 2, 2);
Vector3f vec = mat.col(0);
vec.x() += 5;
float norm = vec.norm();
RowVector3f row_vec(7);
// Auto cast 1x1 matrix to scalar
float scalar = row_vec * vec;
// Pretty print matrices
cout << mat << mat2 << vec;
// Dynamic matrices
Matrix<float, dynamic, dynamic> dyn_mat{ 3, 4 };
Documentation
Documentation overview
- Classes
- Type Definitions
- Predefined Matrices
- Exceptions (optional)
- Matrix Class
- Matrix_view Class
- Global Functions
Classes
class Matrix<T,m,n> m×nmatrices of type T.class Matrix_view<T> class Matrix_iterator<T> class Matrix_stride_iterator<T> class Matrix_block_iterator<T> struct Shape<bool> Type Definitions
using Index = size_tusing Vector<T,n> = Matrix<T,1,n>Matrix.using RowVector<T,m> = Matrix<T,m,1>Matrix.Predefined Matrices
using Matrix2f = Matrix<float, 2, 2>using Matrix3f = Matrix<float, 3, 3>using Matrix4f = Matrix<float, 4, 4>using Vector2f = Vector<float, 2>using Vector3f = Vector<float, 3>using Vector4f = Vector<float, 4>using RowVector2f = RowVector<float, 2>using RowVector3f = RowVector<float, 3>using RowVector4f = RowVector<float, 4>float matrix and vector types.using Matrix2d = Matrix<double, 2, 2>using Matrix3d = Matrix<double, 3, 3>using Matrix4d = Matrix<double, 4, 4>using Vector2d = Vector<double, 2>using Vector3d = Vector<double, 3>using Vector4d = Vector<double, 4>using RowVector2d = RowVector<double, 2>using RowVector3d = RowVector<double, 3>using RowVector4d = RowVector<double, 4>double matrix and vector types.Exceptions
By default, exceptions are not activated. Calls to Matrix::block(Index, Index, Index, Index), Matrix::row(Index), Matrix::col(Index),
Matrix_view::operator=(const Matrix_view&), Matrix_view::operator=(const Matrix&) and
Matrix(const Matrix_view&)
will do an assertation when running in debug mode. Defining the macro MATRIX_EXCEPTIONS before
including this library will instead turn on exceptions for these cases.
struct Matrix_view_mismatch Matrix_view into another is attempted with different block dimensions.struct Matrix_block_domain_error struct Matrix_shape_error Matrix Class
Template Parameters
class TT needs to be default-constructible, copy-insertable, destructable, equality-comparable and capable of basic arithmetic. Index mIndex n
Matrix satisfies the requirements for a C++ Container, ReversableContainer and ContiguousContainer with the same exceptions as std::array that the complexity of swapping is
linear and the default-constructed matrix is not empty for non-zero m and n.
Types
using value_type = Tusing size_type = size_tusing difference_type = ptrdiff_tusing iterator = Matrix_iterator<T>,using const_iterator = Matrix_iterator<const T>using reverse_iterator = std::reverse_iterator<iterator>,using const_reverse_iterator = std::reverse_iterator<const_iterator>Constructors (fixed-size)
Matrix()Matrix(const T& value)value. Matrix(const std::initializer_list<T> elems)Matrix(const std::array<T, m*n>& elems)std::array with fitting length.Matrix(std::array<T, m*n>&& elems)std::array with fitting length.Matrix(const Matrix_view<T>& mat_view)mat_view.Constructors (dynamically-sized)
Matrix(Index m, Index n)Matrix(Index m, Index n, const T& value)value. Matrix(Index m, Index n, const std::initializer_list<T> elems)Matrix(Index m, Index n, const std::vector<T>& elems)std::vector with fitting length.Matrix(Index m, Index n, std::vector<T>&& elems)std::vector with fitting length.Matrix(const Matrix_view<T>& mat_view)mat_view.Matrix Access
size_type rows() constsize_type cols() constsize_type size() constT* data(),const T* data() constT& operator()(size_type i, size_type j),const T& operator()(size_type i, size_type j) const i and column j.T& at(size_type i, size_type j),const T& at(size_type i, size_type j) const i and column j (bounds checked).void fill(const T& c)c.void swap(Matrix& a)Arithmetic
template<class F>Matrix& apply(F f)f takes one argument: the entry). template<class F>Matrix& apply(F f, const T& c)f takes two arguments: the entry and the constant c). template<class F>Matrix& apply(F f, const Matrix& a))f takes two arguments: one entry of each matrix). Matrix& operator+=(const T& c)Matrix operator+(const T& c) constMatrix& operator-=(const T& c)Matrix operator-(const T& c) constMatrix& operator*=(const T& c)Matrix operator*(const T& c) constMatrix& operator/=(const T& c)Matrix operator/(const T& c) constMatrix& operator%=(const T& c)Matrix operator%(const T& c) constMatrix& operator+=(const Matrix& a)Matrix operator+(const Matrix& a) constMatrix& operator-=(const Matrix& a)Matrix operator-(const Matrix& a) constResize and reshape (only for dynamically-sized matrices)
void resize(Index m, Index n)resize() on the vector storing the matrix' elements. void reshape(Index m, Index n)void reshape(Shape new_shape)Shape shape() constOther Matrix Operations
Matrix<T, n, m> transpose() constMatrix<T, m, p> operator*(const Matrix<T, n, p>& a) consttemplate<class U>Matrix<U, m, n> cast() constU. This function returns a new matrix. The type U needs to fulfill std::convertible_to<T, U>. Iterators
iterator begin(),const_iterator begin() constiterator end(),const_iterator end() constreverse_iterator rbegin(),const_reverse_iterator rbegin() constreverse_iterator rend(),const_reverse_iterator rend() constRow/Column/Block Access
The programmer is responsible to ensure that a Matrix_view<T> does not outlive the pointed-to matrix.
Matrix_view<T> block(size_type row, size_type col, size_type rows, size_type cols),Matrix_view<const T> block(size_type row, size_type col, size_type rows, size_type cols) constMatrix_view<T> referencing a rectangular block of the matrix. Matrix_view<T> row(size_type row),Matrix_view<const T> row(size_type row) constMatrix_view<T> referencing the specified row of the matrix. Matrix_view<T> col(size_type col),Matrix_view<const T> col(size_type col) constMatrix_view<T> referencing the specified column of the matrix. Vector-specific Operations
Matrices that have at least one dimension equal 1 are considered vectors. These feature some additional operations.
T& operator[](size_type i),const T& operator[](size_type i) consti'th element of the vector. T& x(size_type i),const T& x(size_type i) constT& y(size_type i),const T& y(size_type i) constT& z(size_type i),const T& z(size_type i) constT norm() constMatrix& normalize()T operator*(const Matrix& vec)operator T() constFactory Functions
static Matrix zero()static Matrix zero(Index m, Index n)static Matrix identity()static Matrix identity(Index n)Matrix_view Class
Types
using value_type = Tusing pointer = T*using reference = T&using size_type = size_tusing iterator = Matrix_block_iterator<T>,using const_iterator = Matrix_block_iterator<const T>using reverse_iterator = std::reverse_iterator<iterator>,using const_reverse_iterator = std::reverse_iterator<const_iterator>Constructors
Matrix_view()Matrix_view(T* ptr, size_type m, size_type n, size_type rows, size_type cols)Iterators
iterator begin(),const_iterator begin() constiterator end(),const_iterator end() constreverse_iterator rbegin(),const_reverse_iterator rbegin() constreverse_iterator rend(),const_reverse_iterator rend() constMember functions
size_type rows() constsize_type cols() constMatrix_view& operator=(const Matrix_view& mat_view)mat_view points to the matrix block that this view points to. The block dimensions need to match. template<size_type m, size_type n>Matrix_view& operator=(const Matrix<T, m, n>& mat)mat into the matrix block that this view points to. Block dimensions and dimensions of mat need to match. Global Functions
template<class T, Index m, Index n>bool operator==(const Matrix<T, m, n>& a, const Matrix<T, m, n>& b)template<class T, Index m, Index n>bool operator!=(const Matrix<T, m, n>& a, const Matrix<T, m, n>& b)template<class T, Index m, Index n>Matrix<T, m, n>& operator-(const Matrix<T, m, n>& mat)mat*-1). template<class T, Index m, Index n>Matrix<T, m, n>& operator*(const T& c, const Matrix<T, m, n>& mat)mat*c). template<class T, Index m>T distance(const Vector& a, const Vector& b) template<class T, Index m>T distance(const RowVector& a, const RowVector& b) (a - b).norm()). template<class T, Index n>Matrix<T, n, n> diag(const T(&values)[n])values. All other values are default-initialized. Template parameters can be deduced automaticallytemplate<class T, Index n>Matrix<T, n, n> antidiag(const T(&values)[n])values. All other values are default-initialized. Template parameters can be deduced automatically