Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <string>
- #include <sstream>
- #include <stdexcept>
- #include <cstdlib>
- class Matrix { //derived from example on page 450
- //wacky mix of C and C++ techniques
- //should really be using the Boost class instead of writing my own
- private:
- //choosing to use a two dimensional array because of the instructions
- //using a one dimensional array and managing the 'end' of the columns might be more efficient
- int ** m_; //pointer to array
- int rows_;
- int cols_;
- int check_bounds(int r, int c) {
- if(r >= rows_ || r < 0 || c >= cols_ || c < 0)
- throw std::runtime_error("Out of bounds");
- }
- public:
- Matrix(int r, int c): rows_(r), cols_(c) {
- m_ = new int*[r]; //first dimension
- for(int i=0; i<r; i++)
- m_[i] = new int[c]; //second dimension
- for(int i=0; i<r; i++)
- for(int j=0; j<c; j++)
- m_[i][j] = 0; //initialize to 0
- }
- ~Matrix() {
- for(int i=0; i<rows_; i++)
- delete[] m_[i];
- delete[] m_;
- }
- int rows() const { return rows_; }
- int cols() const { return cols_; }
- //return a reference to the variable for editting
- //we choose to use the () operator instead of [] because () can take multiple arguments
- //using [] would only allow us to return a row, two [] could get a row and a column, but it's an awkward construct
- //in other words m[1][2] would first evaluate m[1] for a row, then [2] for that position in the resultant array
- //this is much cleaner
- int & operator() (int r, int c) { check_bounds(r,c); return m_[r][c]; }
- bool exists(int r, int c) {
- try { check_bounds(r,c); return true; }
- catch(...) { return false; }
- }
- std::string to_str() const {
- std::stringstream ss;
- for(int i=0; i<rows_; i++) {
- for(int j=0; j<cols_; j++) {
- ss<<m_[i][j]<<" ";
- }
- if(i < rows_-1) ss << "\n"; // don't break after the last row
- }
- return ss.str();
- }
- Matrix operator-(Matrix & m2) {
- Matrix m( std::max(this->rows(), m2.rows()), std::max(this->cols(), m2.cols()));
- //terribly inefficient way to approach this, should probably be a functor
- //DRY violation for -
- for(int i=0; i < m.rows(); i++) {
- for(int j=0; j < m.cols(); j++) {
- if( (*this).exists(i,j) && m2.exists(i,j) )
- m(i,j) = (*this)(i,j) - m2(i,j);
- else if( (*this).exists(i,j) )
- m(i,j) = (*this)(i,j);
- else if( m2.exists(i,j) )
- m(i,j) = m2(i,j);
- else
- m(i,j) = 0;
- }
- }
- return m;
- }
- Matrix operator+(Matrix & m2) {
- Matrix m( std::max(this->rows(), m2.rows()), std::max(this->cols(), m2.cols()));
- //terribly inefficient way to approach
- //DRY violation for
- for(int i=0; i < m.rows(); i++) {
- for(int j=0; j < m.cols(); j++) {
- if( (*this).exists(i,j) && m2.exists(i,j) )
- m(i,j) = (*this)(i,j) + m2(i,j);
- else if( (*this).exists(i,j) )
- m(i,j) = (*this)(i,j);
- else if( m2.exists(i,j) )
- m(i,j) = m2(i,j);
- else
- m(i,j) = 0;
- }
- }
- return m;
- }
- Matrix operator*(Matrix & m2) {
- if(this->cols() != m2.rows())
- throw std::runtime_error("Invalid matrix sizes, cols dont match rows");
- Matrix m(this->rows(), m2.cols());
- for(int i=0; i < this->rows(); i++)
- for(int j=0; j < m2.cols(); j++)
- for(int k=0; k < this->cols(); k++)
- m(i,j) += (*this)(i,k) * m2(k,j);
- return m;
- }
- Matrix operator/(Matrix & m2) {
- if(this->cols() != m2.rows())
- throw std::runtime_error("Invalid matrix sizes, cols dont match rows");
- Matrix m(this->rows(), m2.cols());
- for(int i=0; i < this->rows(); i++)
- for(int j=0; j < m2.cols(); j++)
- for(int k=0; k < this->cols(); k++)
- if((*this)(i,k) && m2(k,j))
- m(i,j) += (*this)(i,k) / m2(k,j);
- return m;
- }
- };
- int main(int argc, char** argv)
- {
- //data set 1
- Matrix m1(2,3);
- Matrix m2(3,3);
- m1(0,0) = 1; m1(0,1) = 2; m1(0,2) = 3;
- m1(1,0) = 4; m1(1,1) = 5; m1(1,2) = 6;
- m2(0,0) = 1; m2(0,1) = 0; m2(0,2) = 0;
- m2(1,0) = 0; m2(1,1) = 1; m2(1,2) = 0;
- m2(2,0) = 0; m2(2,1) = 0; m2(2,2) = 1;
- std::cout << "m1: " << std::endl;
- std::cout << m1.to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m2: " << std::endl;
- std::cout << m2.to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m1 + m2: " << std::endl;
- std::cout << (m1 + m2).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m1 - m2: " << std::endl;
- std::cout << (m1 - m2).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m1 * m2: " << std::endl;
- std::cout << (m1 * m2).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m1 / m2: " << std::endl;
- std::cout << (m1 / m2).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- //data set 2
- Matrix m3(2,3);
- Matrix m4(3,2);
- m3(0,0) = 1; m3(0,1) = 0; m3(0,2) = -2;
- m3(1,0) = 0; m3(1,1) = 3; m3(1,2) = -1;
- m4(0,0) = 0; m4(0,1) = 3;
- m4(1,0) = -2; m4(1,1) = -1;
- m4(2,0) = 0; m4(2,1) = 4;
- std::cout << "m3: " << std::endl;
- std::cout << m3.to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m4: " << std::endl;
- std::cout << m4.to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m3 + m4: " << std::endl;
- std::cout << (m3 + m4).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m3 - m4: " << std::endl;
- std::cout << (m3 - m4).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m3 * m4: " << std::endl;
- std::cout << (m3 * m4).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- std::cout << "m3 / m4: " << std::endl;
- std::cout << (m3 / m4).to_str() << std::endl;
- std::cout << "--------" << std::endl;
- }
Add Comment
Please, Sign In to add comment