29 #include <core/exceptions/software.h>
37 # include <opencv/cv.h>
103 float *data,
bool manage_own_memory)
107 m_num_elements = m_num_rows * m_num_cols;
109 if (!m_num_elements) printf(
"WTF?\n");
111 if (data == NULL || manage_own_memory)
113 m_data = (
float*) malloc(
sizeof(
float) * m_num_elements);
121 for (
unsigned int i = 0; i < m_num_elements; ++i) m_data[i] = data[i];
125 for (
unsigned int i = 0; i < m_num_elements; ++i) m_data[i] = 0.f;
131 m_own_memory =
false;
140 m_num_rows = tbc.m_num_rows;
141 m_num_cols = tbc.m_num_cols;
142 m_num_elements = tbc.m_num_elements;
146 m_data = (
float*) malloc(
sizeof(
float) * m_num_elements);
147 for (
unsigned int i = 0; i < m_num_elements; ++i) m_data[i] = tbc.m_data[i];
153 if (m_own_memory) free(m_data);
174 for (
unsigned int row = 0; row <
num_rows(); ++row)
176 for (
unsigned int col = 0; col <
num_cols(); ++col)
178 data(row, col) = (row == col) ? 1.0 : 0.0;
195 return get_diag(size, 1.f, data_buffer);
209 Matrix res(size, size, data_buffer, data_buffer == NULL);
211 if (data_buffer != NULL)
213 unsigned int diag_elem = 0;
214 for (
unsigned int i = 0; i < size *
size; ++i)
218 diag_elem += size + 1;
219 data_buffer[i] = value;
221 else data_buffer[i] = 0.f;
224 else for (
unsigned int i = 0; i <
size; ++i) res.data(i, i) = value;
236 if (m_num_cols == m_num_rows)
238 CvMat cvmat = cvMat(m_num_rows, m_num_cols, CV_32FC1, m_data);
239 cvTranspose(&cvmat, &cvmat);
244 if (m_num_cols == m_num_rows)
246 for (
unsigned int row = 0; row < m_num_rows - 1; ++row)
248 for (
unsigned int col = row + 1; col < m_num_cols; ++col)
250 float &a = data(row, col);
251 float &b = data(col, row);
260 float *new_data = (
float*) malloc(
sizeof(
float) * m_num_elements);
261 float *cur = new_data;
263 for (
unsigned int col = 0; col < m_num_cols; ++col)
265 for (
unsigned int row = 0; row < m_num_rows; ++row)
267 *cur++ = data(row, col);
271 unsigned int cols = m_num_cols;
272 m_num_cols = m_num_rows;
282 for (
unsigned int i = 0; i < m_num_elements; ++i) m_data[i] = new_data[i];
296 Matrix res(m_num_cols, m_num_rows);
299 for (
unsigned int col = 0; col < m_num_cols; ++col)
301 for (
unsigned int row = 0; row < m_num_rows; ++row)
303 *cur++ = data(row, col);
319 if (m_num_rows != m_num_cols)
321 throw fawkes::Exception(
"Matrix::invert(): Trying to compute inverse of non-quadratic matrix!");
325 CvMat cvmat = cvMat(m_num_rows, m_num_cols, CV_32FC1, m_data);
326 cvInv(&cvmat, &cvmat, CV_LU);
331 for (
unsigned int col = 0; col < m_num_cols; ++col)
335 float factor = 1.f / data(col, col);
336 i.mult_row(col, factor);
337 this->mult_row(col, factor);
341 for (
unsigned int row = 0; row < m_num_rows; ++row)
345 float factor2 = data(row, col);
346 i.sub_row(row, col, factor2);
347 this->sub_row(row, col, factor2);
376 if (m_num_rows != m_num_cols)
378 throw fawkes::Exception(
"Matrix::det(): The determinant can only be calculated for quadratic matrices.");
382 CvMat cvmat = cvMat(m_num_rows, m_num_cols, CV_32FC1, m_data);
384 return (
float)cvDet(&cvmat);
390 for (
unsigned int col = 0; col < m_num_cols; ++col)
392 float diag_elem = tmp_matrix.data(col, col);
396 tmp_matrix.mult_row(col, (1.f / diag_elem));
397 for (
unsigned int row = col + 1; row < m_num_rows; ++row)
399 tmp_matrix.sub_row(row, col, tmp_matrix.data(row, col));
416 unsigned int num_rows,
unsigned int num_cols)
const
418 if ((m_num_rows < row + num_rows) || (m_num_cols < col + num_cols))
420 throw fawkes::OutOfBoundsException(
"Matrix::get_submatrix(): The current matrix doesn't contain a submatrix of the requested dimension at the requested position.");
423 Matrix res(num_rows, num_cols);
426 for (
unsigned int r = 0; r <
num_rows; ++r)
428 for (
unsigned int c = 0; c <
num_cols; ++c)
430 *res_data++ = data(row + r, col + c);
447 unsigned int max_row = std::min(m_num_rows, over.m_num_rows + row);
448 unsigned int max_col = std::min(m_num_cols, over.m_num_cols + col);
450 for (
unsigned int r = row; r < max_row; ++r)
452 for (
unsigned int c = col; c < max_col; ++c)
454 data(r, c) = over.data(r - row, c - col);
474 if (row >= m_num_rows || col >= m_num_cols)
479 return data(row, col);
492 if (row >= m_num_rows || col >= m_num_cols)
494 throw fawkes::OutOfBoundsException(
"Matrix::operator() The requested element (%d, %d) is not within the dimension of the %dx%d matrix.");
497 return data(row, col);
508 if (m_num_elements != m.m_num_elements)
512 throw fawkes::OutOfBoundsException(
"Matrix::operator=(): The rhs matrix has not the same number of elements. This isn't possible if not self managing memory.");
515 m_num_elements = m.m_num_elements;
517 m_data = (
float*) malloc(
sizeof(
float) * m_num_elements);
520 m_num_rows = m.m_num_rows;
521 m_num_cols = m.m_num_cols;
523 for (
unsigned int i = 0; i < m_num_elements; ++i) m_data[i] = m.m_data[i];
537 if (m_num_cols != rhs.m_num_rows)
539 throw fawkes::Exception(
"Matrix::operator*(...): Dimension mismatch: a %d x %d matrix can't be multiplied "
540 "with a %d x %d matrix.\n",
544 unsigned int res_rows = m_num_rows;
545 unsigned int res_cols = rhs.m_num_cols;
547 Matrix res(res_rows, res_cols);
549 for (
unsigned int r = 0; r < res_rows; ++r)
551 for (
unsigned int c = 0; c < res_cols; ++c)
555 for (
unsigned int i = 0; i < m_num_cols; ++i)
557 t += data(r, i) * rhs.data(i, c);
574 if (m_num_cols != rhs.m_num_rows)
576 throw fawkes::Exception(
"Matrix::operator*(...): Dimension mismatch: a %d x %d matrix can't be multiplied "
577 "with a %d x %d matrix.\n",
581 unsigned int res_rows = m_num_rows;
582 unsigned int res_cols = rhs.m_num_cols;
583 unsigned int res_num_elem = res_rows * res_cols;
585 if (!m_own_memory && (m_num_elements != res_num_elem))
587 throw fawkes::Exception(
"Matrix::operator*=(): The resulting matrix has not the same number of elements. This doesn't work if not self managing memory.");
590 float *new_data = (
float*) malloc(
sizeof(
float) * res_num_elem);
591 float *cur = new_data;
593 for (
unsigned int r = 0; r < res_rows; ++r)
595 for (
unsigned int c = 0; c < res_cols; ++c)
599 for (
unsigned int i = 0; i < m_num_cols; ++i)
601 t += data(r, i) * rhs.data(i, c);
615 for (
unsigned int i = 0; i < m_num_elements; ++i) m_data[i] = new_data[i];
629 unsigned int cols = v.
size();
631 if (m_num_cols != cols)
633 throw fawkes::Exception(
"Matrix::operator*(...): Dimension mismatch: a %d x %d matrix can't be multiplied "
638 const float *vector_data = v.
data_ptr();
640 for (
unsigned int r = 0; r <
num_rows(); ++r)
642 float row_result = 0.f;
644 for (
unsigned int c = 0; c < cols; ++c)
646 row_result += data(r, c) * vector_data[c];
664 for (
unsigned int i = 0; i < res.m_num_elements; ++i)
679 for (
unsigned int i = 0; i < m_num_elements; ++i)
697 for (
unsigned int i = 0; i < res.m_num_elements; ++i)
712 for (
unsigned int i = 0; i < m_num_elements; ++i)
728 if ((m_num_rows != rhs.m_num_rows) || (m_num_cols != rhs.m_num_cols))
730 throw fawkes::Exception(
"Matrix::operator+(...): Dimension mismatch: a %d x %d matrix can't be added to a %d x %d matrix\n",
735 const float *rhs_d = rhs.
get_data();
738 for (
unsigned int i = 0; i < m_num_elements; ++i)
740 res_d[i] += rhs_d[i];
753 if ((m_num_rows != rhs.m_num_rows) || (m_num_cols != rhs.m_num_cols))
755 throw fawkes::Exception(
"Matrix::operator+(...): Dimension mismatch: a %d x %d matrix can't be added to a %d x %d matrix\n",
759 const float *rhs_d = rhs.
get_data();
761 for (
unsigned int i = 0; i < m_num_elements; ++i)
763 m_data[i] += rhs_d[i];
779 throw fawkes::Exception(
"Matrix::operator-(...): Dimension mismatch: a %d x %d matrix can't be subtracted from a %d x %d matrix\n",
785 const float *rhs_d = rhs.
get_data();
788 for (
unsigned int i = 0; i < m_num_elements; ++i)
790 res_d[i] -= rhs_d[i];
805 throw fawkes::Exception(
"Matrix::operator-=(...): Dimension mismatch: a %d x %d matrix can't be subtracted from a %d x %d matrix\n",
809 const float *rhs_d = rhs.
get_data();
811 for (
unsigned int i = 0; i < m_num_elements; ++i)
813 m_data[i] -= rhs_d[i];
832 const float *rhs_d = rhs.
get_data();
834 for (
unsigned int i = 0; i < m_num_elements; ++i)
836 if (m_data[i] != rhs_d[i])
return false;
847 Matrix::mult_row(
unsigned int row,
float factor)
849 if (row >= m_num_rows)
854 for (
unsigned int col = 0; col < m_num_cols; ++col)
856 data(row, col) *= factor;
867 Matrix::sub_row(
unsigned int row_a,
unsigned int row_b,
float factor)
869 if (row_a >= m_num_rows)
873 if (row_b >= m_num_rows)
878 for (
unsigned int col = 0; col < m_num_cols; ++col)
880 data(row_a, col) -= factor * data(row_b, col);
894 printf(
"%s:\n", name);
897 for (
unsigned int r = 0; r <
num_rows(); ++r)
899 printf((r == 0 ?
"[" :
" "));
900 for (
unsigned int c = 0; c <
num_cols(); ++c)
902 printf(
"%f", (*
this)(r, c));
905 if (col_sep) printf(
"%s", col_sep);
911 if (row_sep) printf(
"%s", row_sep);
914 else printf(
"]\n\n");
float * data_ptr()
Get pointer to the internal data container.
Matrix & id()
Sets the diagonal elements to 1.0 and all other to 0.0.
unsigned int num_cols() const
Return the number of columns in the Matrix.
Matrix operator*(const Matrix &rhs) const
Matrix multiplication operator.
Matrix & operator-=(const Matrix &rhs)
Subtract-assign operator.
Matrix & operator*=(const Matrix &rhs)
Combined matrix-multipliation and assignement operator.
Fawkes library namespace.
float det() const
Computes the determinant of the matrix.
Matrix operator/(const float &f) const
Divide every element of the matrix with the given scalar.
Matrix & operator/=(const float &f)
Combined scalar division and assignment operator.
unsigned int num_rows() const
Return the number of rows in the Matrix.
Matrix operator+(const Matrix &rhs) const
Addition operator.
void print_info(const char *name=0, const char *col_sep=0, const char *row_sep=0) const
Print matrix to standard out.
Matrix & operator+=(const Matrix &rhs)
Add-assign operator.
unsigned int size() const
Get the number of elements.
void overlay(unsigned int row, unsigned int col, const Matrix &m)
Overlays another matrix over this matrix.
const float * get_data() const
Returns the const data pointer.
void size(unsigned int &num_rows, unsigned int &num_cols) const
Determines the dimensions of the matrix.
static Matrix get_id(unsigned int size, float *data_buffer=0)
Creates a quadratic matrix with dimension size and sets the diagonal elements to 1.0.
bool operator==(const Matrix &rhs) const
Comparison operator.
Matrix & transpose()
Transposes the matrix.
Matrix get_inverse() const
Computes a matrix that is the inverse of this matrix.
Base class for exceptions in Fawkes.
Matrix & invert()
Inverts the matrix.
Matrix get_submatrix(unsigned int row, unsigned int col, unsigned int num_rows, unsigned int num_cols) const
Returns a submatrix of the matrix.
float operator()(unsigned int row, unsigned int col) const
(Read-only) Access-operator.
Matrix operator-(const Matrix &rhs) const
Subtraction operator.
Matrix get_transpose() const
Computes a matrix that is the transposed of this matrix.
Matrix & operator=(const Matrix &rhs)
Assignment operator.
Matrix(unsigned int num_rows=0, unsigned int num_cols=0, float *data=0, bool manage_own_memory=true)
Constructor.
static Matrix get_diag(unsigned int size, float value, float *data_buffer=0)
Creates a quadratic matrix with dimension size and sets the diagonal elements to value.