Matrix — Dense Matrix

Overview

Matrix<T> is the dynamic-size dense matrix template class in calx.

  • Dynamic size, row-major storage
  • Full operator overloading — including matrix product and matrix-vector product
  • Determinant, inverse, transpose, norm, trace
  • Views — zero-copy references to sub-matrices, rows, and columns
  • Factory functions — zeros, identity, rotation matrices
  • Static-size variant: StaticMatrix<T, Rows, Cols>

Constructors

Matrix();
Matrix(size_type rows, size_type cols);
Matrix(size_type rows, size_type cols, const T& value);
Matrix(std::initializer_list<std::initializer_list<T>> init);
SignatureDescription
Matrix()Empty matrix ($0 \times 0$)
Matrix(rows, cols)Size-specified (zero-initialized)
Matrix(rows, cols, value)Size-specified, all elements initialized to value
Matrix({{...}, {...}})2D initializer list
ParameterTypeDescription
rowssize_typeNumber of rows
colssize_typeNumber of columns
valueconst T&Initial value
Matrix<double> A(3, 3, 0.0);         // 3x3 zero matrix
Matrix<double> B = {{1, 2}, {3, 4}}; // 2x2

Element Access

reference operator()(size_type row, size_type col);
const_reference operator()(size_type row, size_type col) const;
reference at(size_type row, size_type col);
const_reference at(size_type row, size_type col) const;
pointer data() noexcept;
const_pointer data() const noexcept;
MethodReturn TypeDescription
A(i, j)T& / const T&Assert-checked in debug builds
A.at(i, j)T& / const T&Bounds-checked (throws on out-of-range)
A.data()T* / const T*Raw pointer (row-major contiguous layout)

Size & Capacity

size_type rows() const noexcept;
size_type cols() const noexcept;
size_type size() const noexcept;
bool empty() const noexcept;
bool is_square() const noexcept;
void resize(size_type rows, size_type cols);
void resize(size_type rows, size_type cols, const value_type& value);
void reshape(size_type rows, size_type cols);
void clear() noexcept;
MethodReturn TypeDescription
rows()size_typeNumber of rows
cols()size_typeNumber of columns
size()size_typeTotal number of elements ($= \text{rows} \times \text{cols}$)
empty()boolWhether the matrix is empty
is_square()boolWhether the matrix is square
resize(r, c)voidResize the matrix
reshape(r, c)voidReshape (total element count must match)
clear()voidClear to empty

Arithmetic Operators

// Matrix + Matrix
Matrix<T> operator+(const Matrix<T>& lhs, const Matrix<T>& rhs);
Matrix<T> operator-(const Matrix<T>& lhs, const Matrix<T>& rhs);
Matrix<T> operator*(const Matrix<T>& lhs, const Matrix<T>& rhs);

// Matrix + Scalar
Matrix<T> operator*(const Matrix<T>& mat, const Scalar& scalar);
Matrix<T> operator*(const Scalar& scalar, const Matrix<T>& mat);
Matrix<T> operator/(const Matrix<T>& mat, const Scalar& scalar);
Matrix<T> operator-(const Matrix<T>& mat);  // unary minus

// Matrix + Vector
Vector<T> operator*(const Matrix<T>& mat, const Vector<T>& vec);

// compound assignment
Matrix& operator+=(const Matrix& rhs);
Matrix& operator-=(const Matrix& rhs);
Matrix& operator*=(const T& scalar);
Matrix& operator/=(const T& scalar);

// operator^ (transpose / Hermitian transpose / inverse / power)
Matrix operator^(int n) const;
OperationReturn TypeDescription
A + BMatrix<T>Matrix addition (same size). Expression templates eliminate temporaries
A - BMatrix<T>Matrix subtraction
A * BMatrix<T>Matrix product ($A \in \mathbb{R}^{m \times n}$, $B \in \mathbb{R}^{n \times p}$ $\to$ $C \in \mathbb{R}^{m \times p}$)
A * s, s * AMatrix<T>Scalar multiplication
A * vVector<T>Matrix-vector product $y = Ax$
-AMatrix<T>Negate all elements
A ^ 'T'Matrix<T>Transpose $A^\top$
A ^ 'H'Matrix<T>Hermitian transpose $A^*$ (conjugate transpose)
A ^ (-1)Matrix<T>Inverse $A^{-1}$
A ^ nMatrix<T>Power $A^n$ (binary exponentiation). $n < 0$ computes $(A^{-1})^{|n|}$

Note: The ^ operator has low precedence in C++. Use parentheses in expressions: (A ^ 'T') * B

Matrix<double> A = {{1, 2}, {3, 4}};
Matrix<double> B = {{5, 6}, {7, 8}};
auto C = A * B;  // {{19, 22}, {43, 50}}

Vector<double> v = {1, 2};
auto w = A * v;  // {5, 11}

auto At   = A ^ 'T';   // transpose
auto Ainv = A ^ (-1);   // inverse
auto A3   = A ^ 3;      // A*A*A

Matrix Operations

Matrix transpose() const;
T determinant() const;
[[nodiscard]] Matrix inverse() const;
T trace() const;
T norm() const;
void zero();
void fill(const T& value);
void identity();
static Matrix identity(size_type size);
MethodReturn TypeDescription
transpose()MatrixTranspose $A^\top$
determinant()TDeterminant $\det(A)$ (LU decomposition, $O(n^3)$)
inverse()MatrixInverse $A^{-1}$ (Gauss-Jordan, $O(n^3)$)
trace()TTrace $\operatorname{tr}(A) = \sum_i a_{ii}$
norm()TFrobenius norm $\|A\|_F = \sqrt{\sum_{ij} a_{ij}^2}$
zero()voidSet all elements to zero
fill(value)voidSet all elements to value
identity()voidSet to identity matrix (square matrices only)
identity(n)Matrix$n \times n$ identity matrix (static)
Matrix<double> A = {{1, 2}, {3, 4}};
std::cout << A.determinant() << std::endl;  // -2
auto Ainv = A.inverse();
auto I = A * Ainv;  // approximately identity matrix

Low-Level Free Functions

Output-parameter form. Customizable via the ComputePolicy template parameter.

template<...> void add(const MatrixA& a, const MatrixB& b, MatrixC& c);
template<...> void subtract(const MatrixA& a, const MatrixB& b, MatrixC& c);
template<...> void scale(const MatrixA& a, const Scalar& alpha, MatrixB& b);
template<...> void multiply(const MatrixA& a, const MatrixB& b, MatrixC& c);
template<...> void multiply_vector(const MatrixA& a, const VectorX& x, VectorY& y);
template<...> void transpose(const MatrixA& a, MatrixB& b);
template<typename MatrixA> auto trace(const MatrixA& a) -> typename MatrixA::value_type;
template<typename MatrixA> auto frobenius_norm(const MatrixA& a) -> typename MatrixA::value_type;
template<typename MatrixA> auto determinant(const MatrixA& a) -> typename MatrixA::value_type;
template<typename T> Matrix<T> inverse(const Matrix<T>& a);

Row/Column Operations & Views

template<typename VectorType> void get_row(size_type row_idx, VectorType& dest) const;
template<typename VectorType> void get_column(size_type col_idx, VectorType& dest) const;
template<typename VectorType> void set_row(size_type row_idx, const VectorType& src);
template<typename VectorType> void set_column(size_type col_idx, const VectorType& src);
MatrixView<MatrixBase> submatrix(size_type r, size_type c, size_type nr, size_type nc);
ConstMatrixView<MatrixBase> submatrix(size_type r, size_type c, size_type nr, size_type nc) const;
MatrixView<MatrixBase> row(size_type row_idx);
MatrixView<MatrixBase> column(size_type col_idx);
MethodReturn TypeDescription
get_row(i, dest)voidCopy row $i$ into a vector
get_column(j, dest)voidCopy column $j$ into a vector
set_row(i, src)voidSet row $i$
set_column(j, src)voidSet column $j$
submatrix(r, c, nr, nc)MatrixViewSub-matrix view (zero-copy)
row(i)MatrixViewView of row $i$
column(j)MatrixViewView of column $j$

Factory Functions

template<typename T> Matrix<T> zeros(std::size_t rows, std::size_t cols);
template<typename T> Matrix<T> ones(std::size_t rows, std::size_t cols);
template<typename T> Matrix<T> eye(std::size_t size);
template<typename T> Matrix<T> rotation2D(T angle);
template<typename T> Matrix<T> rotationX(T angle);
template<typename T> Matrix<T> rotationY(T angle);
template<typename T> Matrix<T> rotationZ(T angle);
template<typename T> Matrix<T> hconcat(const Matrix<T>& a, const Matrix<T>& b);
template<typename T> Matrix<T> vconcat(const Matrix<T>& a, const Matrix<T>& b);
template<typename T> [[nodiscard]] Matrix<T> power(const Matrix<T>& base, unsigned int exponent);
FunctionReturn TypeDescription
zeros<T>(r, c)Matrix<T>Zero matrix
ones<T>(r, c)Matrix<T>All elements set to $1$
eye<T>(n)Matrix<T>$n \times n$ identity matrix
rotation2D(θ)Matrix<T>2D rotation matrix ($2 \times 2$)
rotationX(θ)Matrix<T>3D rotation about X-axis ($3 \times 3$)
rotationY(θ)Matrix<T>3D rotation about Y-axis
rotationZ(θ)Matrix<T>3D rotation about Z-axis
hconcat(A, B)Matrix<T>Horizontal concatenation $[A \mid B]$
vconcat(A, B)Matrix<T>Vertical concatenation $\begin{bmatrix}A \\ B\end{bmatrix}$
power(A, n)Matrix<T>Matrix power $A^n$ (binary exponentiation, $O(n^3 \log k)$)
auto I = eye<double>(3);
auto R = rotationZ<double>(M_PI / 4);  // Z-axis 45° rotation

Output

template<typename T> std::ostream& operator<<(std::ostream& os, const Matrix<T>& mat);
template<typename T> std::string to_string(const Matrix<T>& mat, std::size_t precision = 4);
template<typename T> void print_matrix(const Matrix<T>& mat,
    std::ostream& os = std::cout, std::size_t width = 12, std::size_t precision = 6);
FunctionReturn TypeDescription
operator<<std::ostream&Stream output
to_string(A, prec)std::stringString conversion
print_matrix(A, os, w, p)voidFormatted output (width and precision)

LaTeX Output

Free functions in the calx namespace that convert a matrix or vector into a LaTeX-formatted string. These are not member functions.

Matrix LaTeX Output

// style: "pmatrix" (parentheses), "bmatrix" (square brackets), "vmatrix" (vertical bars), "matrix" (no delimiters)
template<typename T>
std::string toLatex(const Matrix<T>& mat,
    const std::string& style = "pmatrix", std::size_t precision = 6);

Vector LaTeX Output (Column Vector)

template<typename T>
std::string toLatex(const Vector<T>& v,
    const std::string& style = "pmatrix", std::size_t precision = 6);

Parameters

ParameterDescription
styleLaTeX environment name. "pmatrix" = parentheses, "bmatrix" = square brackets, "vmatrix" = vertical bars, "matrix" = no delimiters. Default: "pmatrix"
precisionNumber of decimal places. Default: 6

Examples

Matrix<double> A({{1, 2}, {3, 4}});
std::cout << toLatex(A) << std::endl;
// \begin{pmatrix}
// 1 & 2 \\
// 3 & 4
// \end{pmatrix}

Vector<double> v({1, 2, 3});
std::cout << toLatex(v, "bmatrix") << std::endl;
// \begin{bmatrix}
// 1 \\
// 2 \\
// 3
// \end{bmatrix}

StaticMatrix<T, Rows, Cols>

Compile-time fixed-size variant. Allocated on the stack with a fixed size. Provides the same API as the dynamic Matrix<T>.

StaticMatrix<double, 3, 3> A;
constexpr auto r = A.static_rows();  // 3
constexpr auto c = A.static_cols();  // 3

Specific Methods

static constexpr size_type static_rows();
static constexpr size_type static_cols();
StaticMatrix<T, Cols, Rows> transpose() const;
T determinant() const requires (Rows == Cols);
T trace() const requires (Rows == Cols);
static StaticMatrix identity() requires (Rows == Cols);

Multiplication between StaticMatrix instances is size-checked at compile time: StaticMatrix<T, M, P> = StaticMatrix<T, M, N> * StaticMatrix<T, N, P>.

Examples

Basic Matrix Creation and Operations

#include <math/core/matrix.hpp>
#include <iostream>
using namespace calx;

int main() {
    // initializer_list construction
    Matrix<double> A = {{1, 2, 3},
                         {4, 5, 6},
                         {7, 8, 10}};

    // transpose, trace, determinant
    auto At = A.transpose();
    std::cout << "trace(A) = " << A.trace() << std::endl;        // 16
    std::cout << "det(A)   = " << A.determinant() << std::endl;  // -3

    // matrix multiplication
    Matrix<double> B = {{1, 0}, {0, 1}, {1, 1}};
    auto C = A * B;  // 3x2 result
    print_matrix(C);

    // scalar operations
    auto D = 2.0 * A - A;  // == A

    // factory functions
    auto I = eye<double>(3);
    auto R = rotationZ<double>(M_PI / 6);  // Z-axis 30 deg rotation
}

Solving Linear Systems with solve()

#include <math/core/matrix.hpp>
#include <math/linalg/solve.hpp>
#include <iostream>
using namespace calx;

int main() {
    // Solve Ax = b
    Matrix<double> A = {{2, 1, -1},
                         {-3, -1, 2},
                         {-2, 1, 2}};
    Vector<double> b = {8, -11, -3};

    auto x = solve(A, b);
    std::cout << "x = " << x << std::endl;  // {2, 3, -1}

    // verify: A * x == b
    auto residual = A * x - b;
    std::cout << "residual norm = " << norm(residual) << std::endl;  // ~0
}

Exact Inverse of a Hilbert Matrix with Matrix<Rational>

#include <math/core/matrix.hpp>
#include <math/core/mp/Rational.hpp>
#include <iostream>
using namespace calx;

int main() {
    const int n = 4;
    Matrix<Rational> H(n, n);
    for (int i = 0; i < n; ++i)
        for (int j = 0; j < n; ++j)
            H(i, j) = Rational(1, i + j + 1);

    // exact inverse -- no floating-point error
    auto Hinv = H.inverse();
    auto I = H * Hinv;

    // verify: every diagonal element is exactly 1
    for (int i = 0; i < n; ++i)
        std::cout << "I(" << i << "," << i << ") = " << I(i, i) << std::endl;
    // Output: 1/1 for all

    print_matrix(Hinv);
}

Related Mathematical Background

The following articles explain the mathematical concepts underlying matrix operations.