28 #ifndef CYPRESS_UTIL_MATRIX_HPP 29 #define CYPRESS_UTIL_MATRIX_HPP 62 size_t m_rows, m_cols;
67 bool m_destroy =
true;
74 void check_range(
size_t i)
const 78 ss <<
"[" << i <<
"] out of range for matrix of size " << size()
80 throw std::out_of_range(ss.str());
88 void check_range(
size_t row,
size_t col)
const 90 if (row >= m_rows || col >= m_cols) {
92 ss <<
"[" << row <<
", " << col
93 <<
"] out of range for matrix of size " << m_rows <<
" x " 94 << m_cols << std::endl;
95 throw std::out_of_range(ss.str());
103 void check_range(
size_t)
const {}
108 void check_range(
size_t,
size_t)
const {}
115 Matrix() : m_buf(nullptr), m_rows(0), m_cols(0) {}
123 for (
const auto &elem : init) {
131 template <
size_t Rows,
size_t Cols>
132 Matrix(
const std::array<std::array<T, Cols>, Rows> &init)
135 for (
size_t i = 0; i < Rows; i++) {
136 for (
size_t j = 0; j < Cols; j++) {
137 (*this)(i, j) = init[i][j];
142 Matrix(
const std::vector<std::vector<T>> &init)
143 :
Matrix(init.size(), init[0].size())
145 for (
size_t i = 1; i < init.size(); i++) {
146 assert(init[0].size() == init[i].size());
148 for (
size_t i = 0; i < init.size(); i++) {
149 for (
size_t j = 0; j < init[0].size(); j++) {
150 (*this)(i, j) = init[i][j];
157 for (
size_t i = 0; i < init.size(); i++) {
158 (*this)(i, 0) = init[i];
172 : m_buf(new T[rows * cols]), m_rows(rows), m_cols(cols)
188 Matrix(
size_t rows,
size_t cols,
const T *data)
189 : m_buf(new T[rows * cols]), m_rows(rows), m_cols(cols)
191 std::copy(data, data + (rows * cols), begin());
204 Matrix(
size_t rows,
size_t cols, T *data,
bool destroy)
205 : m_buf(data), m_rows(rows), m_cols(cols), m_destroy(destroy){};
208 : m_buf(new T[o.rows() * o.cols()]), m_rows(o.rows()), m_cols(o.cols())
210 std::copy(o.
begin(), o.
end(), begin());
214 : m_buf(o.m_buf), m_rows(o.rows()), m_cols(o.cols())
227 std::copy(o.
begin(), o.
end(), begin());
253 operator std::vector<T>()
const {
return std::vector<T>(begin(), end()); }
262 return rows() == o.
rows() && cols() == o.
cols() &&
263 std::equal(begin(), end(), o.
begin());
271 std::fill(begin(), end(), val);
275 T *
begin(
size_t row = 0) {
return m_buf + row * cols(); }
276 T *
end() {
return m_buf + size(); }
277 const T *
begin(
size_t row = 0)
const {
return m_buf + row * cols(); }
278 const T *
end()
const {
return m_buf + size(); }
279 const T *
cbegin(
size_t row = 0)
const {
return m_buf + row * cols(); }
280 const T *
cend()
const {
return m_buf + size(); }
287 check_range(row, col);
288 return *(m_buf + row * m_cols + col);
296 check_range(row, col);
297 return *(m_buf + row * m_cols + col);
339 size_t rows()
const {
return m_rows; }
344 size_t cols()
const {
return m_cols; }
349 size_t size()
const {
return m_rows * m_cols; }
357 if (rows != m_rows || cols != m_cols) {
359 m_buf =
new T[rows * cols];
371 if (rows * cols == m_rows * m_cols) {
388 const T *
data()
const {
return m_buf; }
393 friend std::ostream &operator<<(std::ostream &os, const Matrix<T> &m)
395 T
const *d = m.data();
396 for (
size_t row = 0; row < m.rows(); row++) {
397 for (
size_t col = 0; col < m.cols(); col++) {
398 os << (col == 0 ?
"" :
",") << *d;
409 bool empty()
const {
return size() == 0; }
420 if (m_rows <= 1 || m_cols <= 1) {
421 throw std::invalid_argument(
422 "For calculation of a submatrix the dimension must be at least " 425 if (m_rows <= row || m_cols <= col) {
426 throw std::invalid_argument(
427 "Matrix too small for calculating the submatrix with given row " 433 for (
size_t i = 0; i < m_rows; i++) {
438 for (
size_t j = 0; j < m_cols; j++) {
442 subm(subi, subj) = *(m_buf + i * m_cols + j);
459 if (m_rows * m_cols == 0 || m_rows != m_cols) {
460 throw std::invalid_argument(
461 "Calculation of the determinant only valid for squared " 462 "matrices with dimension >=1!");
469 return (*(m_buf)) * (*(m_buf + 3)) -
470 (*(m_buf + 1)) * (*(m_buf + 2));
474 for (
size_t x = 0; x < dim; x++) {
475 T tmp = (*(m_buf + x));
477 T sign = x % 2 ? -1 : 1;
478 res += sign * tmp * submatrix(0, x).determinant();
493 if (m_rows * m_cols == 0 || m_rows != m_cols) {
494 throw std::invalid_argument(
495 "Calculation of the determinant only valid for squared " 496 "matrices with dimension >=1!");
503 for (
size_t x = 0; x < dim; x++) {
504 for (
size_t y = 0; y < dim; y++) {
505 T sign = (x + y) % 2 ? -1 : 1;
522 auto det = determinant();
524 throw std::invalid_argument(
525 "Could not calculate the inverse, as the determinant is zero!");
527 auto adj = adjugate();
529 for (
size_t i = 0; i < res.size(); i++) {
530 res[i] = double(adj[i]) / double(det);
536 template <
typename T,
size_t Rows,
size_t Cols>
542 template <
typename T>
548 template <
typename T>
559 for (
const auto &elem : init) {
Matrix(const std::vector< T > &init)
Definition: matrix.hpp:155
Matrix< double > inverse() const
Calculates the inverse of the matrix. As for the determinant, this runs into issues with unsigned typ...
Definition: matrix.hpp:520
Definition: matrix.hpp:549
Matrix< T > make_matrix(const std::array< std::array< T, Cols >, Rows > &init)
Definition: matrix.hpp:537
Matrix & operator=(const Matrix &o)
Definition: matrix.hpp:221
void resize(size_t s)
Definition: matrix.hpp:563
T & operator[](size_t i)
Definition: matrix.hpp:321
Matrix(const std::array< std::array< T, Cols >, Rows > &init)
Definition: matrix.hpp:132
T * data()
Definition: matrix.hpp:383
Matrix submatrix(size_t row, size_t col) const
Returns the submatrix not containing specified row and column.
Definition: matrix.hpp:418
Matrix(size_t rows, size_t cols, T *data, bool destroy)
Definition: matrix.hpp:204
void resize(size_t rows, size_t cols)
Definition: matrix.hpp:355
Vector()
Definition: matrix.hpp:551
const T & operator()(size_t i) const
Definition: matrix.hpp:312
size_t size() const
Definition: matrix.hpp:349
T determinant() const
Calculate the determinant of this matrix. Note that the type of the returned value is of the same typ...
Definition: matrix.hpp:457
T & operator()(size_t row, size_t col)
Definition: matrix.hpp:285
Matrix()
Definition: matrix.hpp:115
Definition: matrix.hpp:51
const T * data() const
Definition: matrix.hpp:388
size_t rows() const
Definition: matrix.hpp:339
T * begin(size_t row=0)
Definition: matrix.hpp:275
Matrix(Matrix &&o) noexcept
Definition: matrix.hpp:213
size_t cols() const
Definition: matrix.hpp:344
const T & operator[](size_t i) const
Definition: matrix.hpp:330
~Matrix()
Definition: matrix.hpp:243
bool operator==(const Matrix< T > &o) const
Definition: matrix.hpp:260
T & operator()(size_t i)
Definition: matrix.hpp:303
const T * end() const
Definition: matrix.hpp:278
void reshape(size_t rows, size_t cols)
Definition: matrix.hpp:369
Matrix(const Matrix &o)
Definition: matrix.hpp:207
const T & operator()(size_t row, size_t col) const
Definition: matrix.hpp:294
MatrixFlags
Definition: matrix.hpp:43
T * end()
Definition: matrix.hpp:276
Definition: brainscales_lib.hpp:39
Matrix & operator=(Matrix &&o) noexcept
Definition: matrix.hpp:231
const T * cend() const
Definition: matrix.hpp:280
const T * begin(size_t row=0) const
Definition: matrix.hpp:277
Vector(std::initializer_list< T > init)
Definition: matrix.hpp:556
Vector(size_t s, MatrixFlags flags=MatrixFlags::NONE)
Definition: matrix.hpp:552
Matrix< T > & fill(const T &val)
Definition: matrix.hpp:269
Matrix adjugate() const
Calculates the adjugate/adjunct matrix. As for the determinant, this runs into issues with unsigned t...
Definition: matrix.hpp:491
Matrix(const std::vector< std::vector< T >> &init)
Definition: matrix.hpp:142
const T * cbegin(size_t row=0) const
Definition: matrix.hpp:279
bool empty() const
Definition: matrix.hpp:409
Matrix(std::initializer_list< T > init)
Definition: matrix.hpp:120
Matrix(size_t rows, size_t cols, const T *data)
Definition: matrix.hpp:188
Matrix(size_t rows, size_t cols, MatrixFlags flags=MatrixFlags::NONE)
Definition: matrix.hpp:171