C++ Upper Triangular Matrix Bracket Operator -
i've hit road block project of mine. want create upper triangle matrix (all elements below diagonal zero) allocates memory necessary hold nonzero elements. problem i'm having indexing matrix. rather not have redesign matrix, if solution, can accept it. side note, vector own implementation, not stl vector.
so far have class declared follows:
template <class t> class umatrix : public abstractmatrix<t> { private: vector<t>* m_data; int m_size; public: //lots of member functions };
the constructor of upper triangle matrix:
template <class t> umatrix<t>(const int size) { m_size = size; if(size < 1) throw(rangeerr(size)); m_data = new vector<t> [size]; for(int = 0; < size; i++) { vector<t> init(i + 1); m_data[i] = init; } }
and code i'm having trouble with:
template <class t> vector<t>& operator[] (const int index) { if(m_data != null && index >= 0 && index < m_rows) { // insert dark magic here } else { throw(rangeerr(index)); } }
this results in array of staggered vectors, each vector being 1 length larger previous.
i attempting implement bracket operator such umatrix[a][b]
accesses row a, column b of true upper triangular matrix. means umatrix[a][b] == 0
when a > b
.
the bracket operator virtual function abstract base class, , must return vector&. also, implementation must use bracket operator, not function () operator, compatible written code. aware simpler use dense matrix, limited necessary memory usage.
my first attempt involved using 1 vector storage, similar 1d array matrix. however, bracket operator seemingly impossible write implementation well.
my question: possible implement bracket operator?
well, don't know if accepted solution since have not provided vector
class. can create class let's call sparsevector<u>
, have code this
virtual u& operator[](int i) { if(m_data != nullptr) { if(m_nnzb <= && <= m_nnze) { return m_data[i - m_nnzb]; } } throw std::runtime_error("bad index: in sparsevector::operator[]"); }
here idea of implementation. vector of size m_size
store non-zero elements in range m_nnzb
m_nnze
. , use class subscript operator in matrix class. here full code small example.
#include <iostream> #include <exception> #include <stdexcept> /* vector interface */ template<typename t> class ivector { public: virtual t& operator[](int i) = 0; }; /* matrix interface */ template<typename t> class imatrix { public: virtual ivector<t>& operator[](int i) = 0; }; /* implementation upper triangular matrix */ template<typename t> class uppermatrix : public imatrix<t> { public: /* implementation sparse vector */ template<typename u> class sparsevector : public ivector<u> { public: sparsevector() { m_size = m_nnzb = m_nnze = 0; m_data = nullptr; } sparsevector(int size, int b, int e) { m_size = size; m_nnzb = b; m_nnze = e; m_data = new u[e - b]; } sparsevector(const sparsevector<u>& other) { m_size = other.m_size; m_nnzb = other.m_nnzb; m_nnze = other.m_nnze; m_data = new u[m_nnze - m_nnzb]; for(int = 0; < m_nnze - m_nnzb; ++i) { m_data[i] = other.m_data[i]; } } virtual u& operator[](int i) { if(m_data != nullptr) { if(m_nnzb <= && <= m_nnze) { return m_data[i - m_nnzb]; } } throw std::runtime_error("bad index: in sparsevector::operator[]"); } protected: int m_size; int m_nnzb; int m_nnze; u* m_data; }; uppermatrix(int n) { m_size = n; m_data = new sparsevector<t>[n]; for(int = 0; < n; ++i) { m_data[i] = sparsevector<t>(n, i, n); } } virtual ivector<t>& operator[](int i) { if(i < m_size && m_data != nullptr) { return m_data[i]; } throw std::runtime_error("bad index in uppermatrix::operator[]"); } protected: int m_size; sparsevector<t>* m_data; }; int main(int argc, char** argv) { uppermatrix<int> m1(3); /* correct index */ for(int = 0; < 3; ++i) { for(int j = i; j < 3; ++j) { m1[i][j] = + j; } } for(int = 0; < 3; ++i) { for(int j = i; j < 3; ++j) { std::cout << m1[i][j] << " "; } std::cout << std::endl; } /* incorrect index */ try { for(int = 0; < 3; ++i) { for(int j = 0; j < 3; ++j) { m1[i][j] = + j; } } } catch(const std::exception& ex) { std::cout << "error occured: " << ex.what() << std::endl; } }
Comments
Post a Comment