#include #include #include "matrix_proxy.h" using namespace std; matrix_proxy::matrix_proxy(matrix_expression& src, const matrix_expression& rows, const matrix_expression& cols) : _src(src), _rows(rows), _cols(cols) { if (min(rows.numColumns(), rows.numRows()) != 1) throw invalid_argument("rows must be one-dimensional."); if (min(cols.numColumns(), cols.numRows()) != 1) throw invalid_argument("cols must be one-dimensional."); for (int k=0; k < numRows(); k++) if (_rows[k] < 0 || _rows[k] >= src.numRows()) throw out_of_range("invalid row specified"); for (int k=0; k < numColumns(); k++) if (_cols[k] < 0 || _cols[k] >= src.numColumns()) throw out_of_range("invalid column specified"); } // cannot do traditional assignment on proxies, since we cannot rebind the source matrix. // We will only support value-based assignments matrix_proxy& matrix_proxy::operator=(const matrix_proxy& other) { if (this != &other) matrix_expression::operator=(other); return *this; } int matrix_proxy::numRows() const { return _rows.numRows()*_rows.numColumns(); } int matrix_proxy::numColumns() const { return _cols.numRows()*_cols.numColumns(); } // Determine source of underlying storage const matrix_expression& matrix_proxy::underlyingStorage() const { return _src.underlyingStorage(); } // read-only version of indexing operator double matrix_proxy::operator()(int r, int c) const { return _src(_rows[r], _cols[c]); } // write-access version of indexing operator double& matrix_proxy::operator()(int r, int c) { return _src(_rows[r], _cols[c]); }