// NumericMatrix.cpp // // Numeric matrix class. // This is a matrix class for numerical data. Derived from Matrix and // it adds mathematical functions. // // 2 february 1999 RD Started // 2002-4-9 DD removed functions that belong elsewhere // 2005-12-4 DD bug fix m1 + and - m2 // 2005-12-17 DD size_t -> I // 2006-8-10 DD fix a bug mat*mat // 2009-4-10 DD Transpose function; fix in mat*mat // // (C) Datasim Component Technology 1999-2006 #ifndef NumericMatrix_cpp #define NumericMatrix_cpp #include "NumericMatrix.hpp" // Constructors & destructor template NumericMatrix::NumericMatrix(): Matrix() { // Default constructor } template NumericMatrix::NumericMatrix(I rows, I columns): Matrix(rows, columns) { // Constructor with size. Start index=0. } template NumericMatrix::NumericMatrix(I rows, I columns, I rowStart, I columnStart): Matrix(rows, columns, rowStart, columnStart) { // Constructor with size & start index } template NumericMatrix::NumericMatrix(const Matrix& source): Matrix(source) { // Constructor with matrix } template NumericMatrix::NumericMatrix(const NumericMatrix& source): Matrix(source) { // Copy constructor } template NumericMatrix::~NumericMatrix() { // Destructor } // Selectors template Vector NumericMatrix::Row(I row) const { // Return row. Overloads Matrix::Row() to return Vector instead of Array //return Vector(Matrix::Row(row)); // We make a copy in this version Vector result(Columns(), MinColumnIndex()); for (I j = result.MinIndex(); j <= result.MaxIndex(); ++j) { result[j] = (*this)(row, j); } return result; } template Vector NumericMatrix::Column(I column) const { // Return Column. Overloads Matrix::Row() to return Vector instead of Array return Vector(Matrix::Column(column)); } // Modifiers template void NumericMatrix::Row(I row, const Array& val) { // Replace row. Overloaded because Row() selector is overloaded thus hiding Matrix::Row() modifier. // Matrix::Row(row, val); for (I c=MinColumnIndex(); c<=MaxColumnIndex(); c++) { (*this)(row,c) = val[c]; } } /* template void NumericMatrix::Column(I column, const Array& val) { // Replace column. Overloaded because Column() selector is overloaded thus hiding Matrix::Column() modifier. Matrix::Column(column, val); } */ // Operators template NumericMatrix& NumericMatrix::operator = (const NumericMatrix& source) { // Assignment operator // Exit if same object if (this==&source) return *this; // Call base class assignment Matrix::operator = (source); return *this; } template NumericMatrix NumericMatrix::operator - () const { // Unary minus // Create new matrix with same size and same starting index NumericMatrix result(Rows(), Columns(), MinRowIndex(), MinColumnIndex()); // Copy all elements negative for (I r=MinRowIndex(); r<=MaxRowIndex(); r++) { for (I c=MinColumnIndex(); c<=MaxColumnIndex(); c++) { result(r,c) = -(*this)(r,c); } } // Return the result return result; } template NumericMatrix NumericMatrix::operator + (const NumericMatrix& m) const { // Add the elements // Create new matrix with same size and same starting index NumericMatrix result(Rows(), Columns(), MinRowIndex(), MinColumnIndex()); // Add all elements for (I r1=MinRowIndex(); r1<=MaxRowIndex(); r1++) { for (I c1=MinColumnIndex(); c1<=MaxColumnIndex(); c1++) result(r1, c1) = (*this)(r1, c1) + m(r1, c1); } // Return the result return result; } template NumericMatrix NumericMatrix::operator - (const NumericMatrix& m) const { // Subtract the elements // Create new matrix with same size and same starting index NumericMatrix result(Rows(), Columns(), MinRowIndex(), MinColumnIndex()); print(result); // Add all elements for (I r1 = MinRowIndex(); r1<=MaxRowIndex(); r1++) { for (I c1=MinColumnIndex(); c1<=MaxColumnIndex(); c1++) result(r1, c1) = (*this)(r1, c1) - m(r1, c1); } // Return the result return result; } template NumericMatrix NumericMatrix::operator * (const NumericMatrix& m) const { // Multiply the matrix. // This function can be optimized by calculating the inner product ourselfs instead of // using the InnerProduct function of Vector. This saves a couple of row and column copies. // Create new matrix with same row size of first matrix and column size of second matrix and same starting index as first matrix NumericMatrix result(Rows(), m.Columns(), MinRowIndex(), MinColumnIndex()); I r1, c2, rr, cr; // Element of resulting array is dot/inner product of corresponding row m1 and corresponding column m2 for (I rr=result.MinRowIndex(); rr<=result.MaxRowIndex(); ++rr) { for (I cr = result.MinColumnIndex(); cr <= result.MaxColumnIndex(); ++cr) { result(rr, cr) = 0.0; for (I k = result.MinColumnIndex(); k <= result.MaxColumnIndex(); ++k) { result(rr, cr) += (*this)(rr, k) * m(k,cr); } cout << "*" << rr << "," << cr << "," << result(rr, cr)<< endl; } } // Return the result return result; } template Vector NumericMatrix::operator * (const Vector& v) const { // Result has same number of rows as m and same start index as v Vector result(Rows(), v.MinIndex()); V r(0.0); // sum of rows for (I i = MinRowIndex(); i <= MaxRowIndex(); i++) { r = 0.0; for (I j = MinColumnIndex(); j<= MaxColumnIndex(); j++) { r += (*this)(i,j) * v[j]; } result[i] = r; } return result; } template NumericMatrix NumericMatrix::Transpose() const { // Switch rows and columns NumericMatrix result(Columns(), Rows()); for (I i = result.MinRowIndex(); i <= result.MaxRowIndex(); ++i) { for (I j = result.MinColumnIndex(); j<= result.MaxColumnIndex(); ++j) { result(i,j) = (*this)(j,i); } } return result; } #endif // NumericMatrix_cpp