#ifndef MATRIX_EXPRESSION_H #define MATRIX_EXPRESSION_H #include #include "range.h" class matrix; // forward declaration to avoid circular includes class matrix_proxy; // forward declaration to avoid circular includes /*********************************************************** * matrix_expression class * * This is an "abstract" class in that it is impossible * to directly create instances of this class. Its * purpose is to serve as a base class for concrete * implementations (e.g., matrix, matrix_proxy). * * As such, you cannot declare a standard value variable * of the form: * * matrix_expression A; * * But can instead declare reference variables of this type, assigned * to expressions that evaluate to said type, as in * * matrix_expression &A = B(range(2,5), range(3,8)); * *********************************************************/ class matrix_expression { public: /*********************************************************** * The following two definitions are pure virtual functions * that must be overridden by each child class. *********************************************************/ // Provides read-only access via indexing operator virtual double operator()(int r, int c) const = 0; // Provides write-access through indexing operator virtual double& operator()(int r, int c) = 0; // Returns the number of rows virtual int numRows() const =0; // Returns the number of columns virtual int numColumns() const =0; /*********************************************************** * The remaining definitions are functions that can be shared * by all child classes (although they are free to override * them if desired). * * Generic implementations for these are provided in * matrix_expression.cpp *********************************************************/ // assignment operator supports syntax: A = B; // For generic expressions, this is only well defined if dimensions agree. virtual matrix_expression& operator=(const matrix_expression& other); // Returns a 1x2 matrix describing the number of rows and columns respectively virtual matrix size() const; // element-wise test of equality. virtual bool operator==(const matrix_expression &other) const; // element-wise test of inequality virtual bool operator!=(const matrix_expression &other) const; // provides read-only access to a submatrix via a proxy virtual const matrix_proxy operator()(range rows, range cols) const; // provides write access to a submatrix via a proxy virtual matrix_proxy operator()(range rows, range cols); //----------------------------------------------- // addition //----------------------------------------------- // returns new matrix instance based on sum of two expressions virtual matrix operator+(const matrix_expression& other) const; // in-place addition with another matrix expression virtual matrix_expression& operator+=(const matrix_expression& other); // returns new matrix instance based on element-wise addition virtual matrix operator+(double scalar) const; // in-place element-wise addition with a scalar virtual matrix_expression& operator+=(double scalar); //----------------------------------------------- // multiplication //----------------------------------------------- // returns a new matrix based on element-wise multiplication by a scalar // e.g., C = A*B; virtual matrix operator*(double scalar) const; // in-place element-wise multiplication with a scalar // e.g., C = A*4; virtual matrix_expression& operator*=(double scalar); // returns a new matrix based on product of expressions virtual matrix operator*(const matrix_expression& other) const; //----------------------------------------------- // destructor (a formality in this case) //----------------------------------------------- virtual ~matrix_expression() { } }; // support for outputting a matrix expression std::ostream& operator<<(std::ostream& out, const matrix_expression& m); // support for left-hand side scalar operations matrix operator+(double scalar, const matrix_expression& m); matrix operator*(double scalar, const matrix_expression& m); #endif