&m1, const Matrix &m2);
template
inline Matrix operator+(const Matrix &m1, const Matrix &m2);
template
inline Matrix operator-(const Matrix &m1, const Matrix &m2);
template
inline Matrix operator*(const Matrix &m1, float factor);
template
inline Matrix operator/(const Matrix &m1, float factor);
template
Matrix operator*(float factor, const Matrix &m1);
template
Matrix operator-(const Matrix &m);
template
bool operator==(const Matrix &m1, const Matrix &m2);
template
bool operator!=(const Matrix &m1, const Matrix &m2);
// Constructors
template
MatrixBase::MatrixBase() {
for (int i = 0; i < rows * cols; ++i) {
_values[i] = 0.f;
}
}
template
MatrixBase::MatrixBase(const float *data) {
setData(data);
}
template
MatrixBase::MatrixBase(const MatrixBase &m) {
setData(m._values);
}
template
MatrixBase &MatrixBase::operator=(const MatrixBase &m) {
setData(m._values);
return *this;
}
// Data management
template
float *MatrixBase::getData() {
return _values;
}
template
const float *MatrixBase::getData() const {
return _values;
}
template
void MatrixBase::setData(const float *data) {
::memcpy(_values, data, rows * cols * sizeof(float));
}
template
float MatrixBase::getValue(int row, int col) const {
assert(rows > row && cols > col && row >= 0 && col >= 0);
return _values[row * cols + col];
}
template
void MatrixBase::setValue(int row, int col, float v) {
operator()(row, col) = v;
}
// Operations helpers
template
bool MatrixBase::isZero() const {
for (int i = 0; i < rows * cols; ++i) {
if (_values[i] != 0.f) {
return false;
}
}
return true;
}
template
Matrix MatrixBase::getNegative() const {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = -_values[i];
}
return result;
}
template
Matrix MatrixBase::sum(const Matrix &m1, const Matrix &m2) {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = m1._values[i] + m2._values[i];
}
return result;
}
template
Matrix MatrixBase::difference(const Matrix &m1, const Matrix &m2) {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = m1._values[i] - m2._values[i];
}
return result;
}
template
Matrix MatrixBase::product(const Matrix &m1, float factor) {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = m1._values[i] * factor;
}
return result;
}
template
Matrix MatrixBase::product(const Matrix &m1, const Matrix &m2) {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = m1._values[i] * m2._values[i];
}
return result;
}
template
Matrix MatrixBase::quotient(const Matrix &m1, float factor) {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = m1._values[i] / factor;
}
return result;
}
template
Matrix MatrixBase::quotient(const Matrix &m1, const Matrix &m2) {
Matrix result;
for (int i = 0; i < r * c; ++i) {
result._values[i] = m1._values[i] / m2._values[i];
}
return result;
}
// Member operators
template
float &MatrixBase::operator()(int row, int col) {
assert(rows > row && cols > col && row >= 0 && col >= 0);
return _values[row * cols + col];
}
template
float MatrixBase::operator()(int row, int col) const {
return getValue(row, col);
}
template
Matrix &MatrixBase::operator=(const Matrix &m) {
setData(m._values);
return getThis();
}
template
Matrix &MatrixBase::operator+=(const Matrix &m) {
for (int i = 0; i < rows * cols; ++i) {
_values[i] += m._values[i];
}
return getThis();
}
template
Matrix &MatrixBase::operator-=(const Matrix &m) {
for (int i = 0; i < rows * cols; ++i) {
_values[i] -= m._values[i];
}
return getThis();
}
template
Matrix &MatrixBase::operator*=(float factor) {
for (int i = 0; i < rows * cols; ++i) {
_values[i] *= factor;
}
return getThis();
}
template
Matrix &MatrixBase::operator/=(float factor) {
for (int i = 0; i < rows * cols; ++i) {
_values[i] /= factor;
}
return getThis();
}
// Row
template
typename MatrixBase::Row MatrixBase::getRow(int row) {
return Row(this, row);
}
template
MatrixBase::Row::Row(MatrixBase *m, int row) :
_matrix(m), _row(row), _col(0) {
}
template
typename MatrixBase::Row &MatrixBase::Row::operator<<(float value) {
assert(_col < cols);
_matrix->setValue(_row, _col++, value);
return *this;
}
// Global operators
template
Matrix operator*(const Matrix &m1, const Matrix &m2) {
Matrix result;
for (int row = 0; row < m; ++row) {
for (int col = 0; col < n; ++col) {
float sum(0.0f);
for (int j = 0; j < p; ++j)
sum += m1(row, j) * m2(j, col);
result(row, col) = sum;
}
}
return result;
}
template
inline Matrix operator+(const Matrix &m1, const Matrix &m2) {
return Matrix::sum(m1, m2);
}
template
inline Matrix operator-(const Matrix &m1, const Matrix &m2) {
return Matrix::difference(m1, m2);
}
template
inline Matrix operator*(const Matrix &m1, const Matrix &m2) {
return Matrix::product(m1, m2);
}
template
inline Matrix operator*(const Matrix &m1, float factor) {
return Matrix::product(m1, factor);
}
template
inline Matrix operator/(const Matrix &m1, const Matrix &m2) {
return Matrix::quotient(m1, m2);
}
template
inline Matrix operator/(const Matrix &m1, float factor) {
return Matrix::quotient(m1, factor);
}
template
Matrix operator*(float factor, const Matrix &m1) {
return Matrix::product(m1, factor);
}
template
Matrix operator-(const Matrix &m) {
return m.getNegative();
}
template
bool operator==(const Matrix &m1, const Matrix &m2) {
for (int row = 0; row < r; ++row) {
for (int col = 0; col < c; ++col) {
if (m1(row, col) != m2(row, col)) {
return false;
}
}
}
return true;
}
template
bool operator!=(const Matrix &m1, const Matrix &m2) {
return !(m1 == m2);
}
template
Common::StreamDebug &operator<<(Common::StreamDebug &dbg, const Math::Matrix &m) {
dbg.nospace() << "Matrix<" << r << ", " << c << ">(";
for (int col = 0; col < c; ++col) {
dbg << m(0, col) << ", ";
}
for (int row = 1; row < r; ++row) {
dbg << "\n ";
for (int col = 0; col < c; ++col) {
dbg << m(row, col) << ", ";
}
}
dbg << ')';
return dbg.space();
}
}
#endif