23template <
int _rows,
int _cols,
typename T =
float>
24 requires(std::is_arithmetic_v<T> && _rows > 0 && _cols > 0)
27 template <
int r,
int c,
typename U>
28 requires(std::is_arithmetic_v<U> && r > 0 && c > 0)
38 constexpr explicit Matrix(T val)
40 for (
int i = 0; i < _rows; i++)
41 std::fill(data[i].begin(), data[i].end(), val);
50 for (
int i = 0; i < _rows; i++)
51 for (
int j = 0; j < _cols; j++)
52 this->data[i][j] = data[i * _cols + j];
61 this->data = mat.data;
66 this->data = std::move(mat.data);
69 template <
typename Ty>
70 requires(std::is_arithmetic_v<Ty>)
71 constexpr Matrix(
const Matrix<_rows, _cols, Ty> &mat) : Matrix()
73 for (
int i = 0; i < _rows; i++)
74 for (
int j = 0; j < _cols; j++)
75 data[i][j] =
static_cast<T
>(mat.data[i][j]);
87 [[nodiscard]]
constexpr uint32_t
rows()
const
96 [[nodiscard]]
constexpr uint32_t
cols()
const
110 constexpr const std::array<T, _cols> &operator[](
int row)
const
128 data = std::move(mat.data);
140 for (
int i = 0; i < _rows; i++)
141 for (
int j = 0; j < _cols; j++)
142 data[i][j] += mat.data[i][j];
155 for (
int i = 0; i < _rows; i++)
156 for (
int j = 0; j < _cols; j++)
157 data[i][j] -= mat.data[i][j];
168 template <
typename Ty>
169 requires(std::is_arithmetic_v<Ty>)
172 for (
int i = 0; i < _rows; i++)
173 for (
int j = 0; j < _cols; j++)
186 template <
typename Ty>
187 requires(std::is_arithmetic_v<Ty>)
190 for (
int i = 0; i < _rows; i++)
191 for (
int j = 0; j < _cols; j++)
206 for (
int i = 0; i < _rows; i++)
207 for (
int j = 0; j < _cols; j++)
208 res.data[i][j] = data[i][j] + mat.data[i][j];
222 for (
int i = 0; i < _rows; i++)
223 for (
int j = 0; j < _cols; j++)
224 res.data[i][j] = data[i][j] - mat.data[i][j];
235 template <
typename Ty>
236 requires(std::is_arithmetic_v<Ty>)
240 for (
int i = 0; i < _rows; i++)
241 for (
int j = 0; j < _cols; j++)
242 res.data[i][j] = data[i][j] * val;
254 template <
typename Ty>
255 requires(std::is_arithmetic_v<Ty>)
268 template <
typename Ty>
269 requires(std::is_arithmetic_v<Ty>)
273 for (
int i = 0; i < _rows; i++)
274 for (
int j = 0; j < _cols; j++)
275 res.data[i][j] = data[i][j] / val;
292 for (
int i = 0; i < _rows; i++)
293 for (
int k = 0; k < _cols; k++)
294 for (
int j = 0; j < cols2; j++)
295 res[i][j] += mat1[i][k] * mat2[k][j];
306 return data == mat.data;
310 template <
int rows,
int cols>
constexpr Matrix<rows, cols, T> block(
int start_row,
int start_col)
const
313 for (
int i = 0; i < rows; i++)
314 std::copy(data[i + start_row].begin() + start_col, data[i + start_row].begin() + start_col + cols,
315 res.data[i].begin());
326 return block<1, _cols>(row, 0);
336 return block<_rows, 1>(0, col);
347 for (
int i = 0; i < _rows; i++)
348 for (
int j = 0; j < _cols; j++)
349 res[j][i] = data[i][j];
373 for (
int i = 0; i < std::min(_rows, _cols); i++)
385 static_assert(_cols == _rows,
"Matrix must be square");
388 Matrix temp = this->clone();
391 for (
int k = 0; k < _cols; k++)
394 auto magnitude = [](T value)
constexpr {
395 const auto converted =
static_cast<long double>(value);
396 return converted < 0.0L ? -converted : converted;
398 auto pivot_magnitude = magnitude(temp[k][k]);
399 for (
int i = k + 1; i < _rows; i++)
401 const auto candidate_magnitude = magnitude(temp[i][k]);
402 if (candidate_magnitude > pivot_magnitude)
405 pivot_magnitude = candidate_magnitude;
411 if (pivot_magnitude == 0.0L)
418 std::swap(temp[pivot_row], temp[k]);
419 std::swap(res[pivot_row], res[k]);
422 T pivot = temp[k][k];
423 for (
int j = 0; j < _cols; j++)
429 for (
int i = 0; i < _rows; i++)
433 T factor = temp[i][k];
434 for (
int j = 0; j < _cols; j++)
436 temp[i][j] -= factor * temp[k][j];
437 res[i][j] -= factor * res[k][j];
456 return Matrix(
static_cast<T
>(0));
467 return Matrix(
static_cast<T
>(1));
480 for (
int i = 0; i < std::min(_rows, _cols); i++)
496 for (
int i = 0; i < std::min(_rows, _cols); i++)
498 res[i][i] = vec[i][0];
504 std::array<std::array<T, _cols>, _rows> data;
508template <
int r,
int c>
using Matrixf = Matrix<r, c, float>;
constexpr Matrix(const T *data)
Constructor with input data
constexpr uint32_t cols() const
return the column size of the matrix
constexpr Matrix operator+(const Matrix &mat) const
Additonal operator
constexpr Matrix< _cols, _rows, T > trans() const
Get the transpose of the matrix
constexpr std::array< T, _cols > & operator[](int row)
Return the element of the matrix
constexpr uint32_t rows() const
returns the row size of the matrix
constexpr Matrix inv() const
Get the inverse of the matrix
static constexpr Matrix eye()
Returns a _rows * columns matrix
static constexpr Matrix diag(const Matrix< _rows, 1, T > &vec)
Returns a _rows x _cols diagonal matrix
~Matrix()=default
Destructor
static constexpr Matrix zeros()
Returns a _rows x _cols zero matrix
constexpr Matrix< _rows, 1, T > col(int col) const
Return the specific row of the matrix
constexpr Matrix & operator=(const Matrix &mat)
Copy assignment of the matrix(row * size) instance
constexpr Matrix()
Constructor without input data
constexpr Matrix clone() const
constexpr Matrix(const Matrix &mat)
Copy Constructor
constexpr Matrix & operator-=(const Matrix &mat)
Substraction operator of two matrices(row * size)
constexpr T trace() const
Get the trace of the matrix
constexpr bool operator==(const Matrix &mat) const
Compare whether two matrices are identical
static constexpr Matrix ones()
Returns a _rows x _cols one matrix
constexpr Matrix< 1, _cols, T > row(int row) const
Return the specific row of the matrix
constexpr Matrix & operator+=(const Matrix &mat)
Additional operator of two matrices(row * size)
constexpr friend Matrix< _rows, cols2, T > operator*(const Matrix< _rows, _cols, T > &mat1, const Matrix< _cols, cols2, T > &mat2)
The matrix multiplication
constexpr Matrix operator-(const Matrix &mat) const
Substraction matrix