// -*- c++ -*- // // $COPYRIGHT$ // // #ifndef ENTRY_H #define ENTRY_H #include #include "mtl/mtl_config.h" namespace mtl { //: // Definintion for entries in sparse matrices // // There is one index stored with the element. //!category: utilities //!component: type template struct entry1 { /* This is kind of bad because it gets padded out to 16 bytes, which wastes space/bandwidth */ typedef entry1 self; typedef T value_type; int index; mutable value_type value; inline entry1() : index(-1), value(0.0) { } inline entry1(int i, value_type v = value_type()) : index(i), value(v) { } inline entry1(const self& x) : index(x.index), value(x.value) { } inline self& operator=(const self& x) { index = x.index; value = x.value; return *this; } inline bool operator < (const entry1& e) const { return index < e.index; } inline bool operator == (const entry1& e) const { return index == e.index; } inline bool operator != (const entry1& e) const { return index != e.index; } }; template std::ostream& operator<<(std::ostream& os, const entry1& e) { os << "(" << e.index << "," << e.value << ") "; return os; } //: blah //!noindex: template class elt_ref { typedef elt_ref self; public: typedef typename OneD::value_type value_type; inline elt_ref() : vec(OneD()), i(-1) { } inline elt_ref(OneD& m, int i_) : vec(m), i(i_) { iter = vec.find(i); if (iter != vec.end()) { if (iter.index() == i) val = *iter; else val = value_type(); } else val = value_type(); } inline operator value_type() const { return val; } inline value_type operator=(value_type v) { if (iter != vec.end() && iter.index() == i) { *iter = val = v; } else { val = v; iter = vec.insert(iter, i, v); } return val; } inline value_type operator+=(value_type v) { if (iter != vec.end() && iter.index() == i) { *iter = val += v; } else { val = v; iter = vec.insert(iter, i, v); } return val; } inline value_type operator*=(value_type v) { if (iter != vec.end() && iter.index() == i) *iter = val *= v; return val; } inline value_type operator/=(const self& v) { if (iter != vec.end() && iter.index() == i) *iter = val /= v.val; return val; } inline value_type operator/=(value_type v) { if (iter != vec.end() && iter.index() == i) *iter = val /= val; return val; } inline value_type operator-=(value_type v) { if (iter != vec.end() && iter.index() == i) *iter = val -= v; else { val = -v; iter = vec.insert(iter, i, val); } return val; } inline value_type operator=(const self& a) { if (iter != vec.end() && iter.index() == i) *iter = val = a.val; else iter = vec.insert(iter, i, a.val); return val; } /*protected: */ OneD vec; /* JGS, value_typeobably performance issue here, want OneD& vec; but vec may be temporary object in the 2D, like comvalue_typeessed2D */ typename OneD::iterator iter; int i; value_type val; }; //: blah //!noindex: template class const_elt_ref { typedef const_elt_ref self; public: typedef typename OneD::value_type value_type; /* inline const_elt_ref() : vec(0), i(0) { }*/ template inline const_elt_ref(const EltRef& elt) { typename OneD::const_iterator iter = elt.vec.find(elt.i); if (iter != elt.vec.end()) { if (iter.index() == elt.i) val = *iter; else val = value_type(); } else val = value_type(); } inline const_elt_ref(const OneD& vec, int i) { typename OneD::const_iterator iter = vec.find(i); if (iter != vec.end()) { if (iter.index() == i) val = *iter; else val = value_type(); } else val = value_type(); } inline operator value_type() const { return val; } protected: value_type val; }; #if (__GNUC__ < 9) /* let the conversion operator handle all these ops */ template std::ostream& operator<<(std::ostream& os, const elt_ref& er) { typedef typename elt_ref::value_type value_type; os << value_type(er); return os; } template std::ostream& operator<<(std::ostream& os, const const_elt_ref& er) { typedef typename const_elt_ref::value_type value_type; os << value_type(er); return os; } #define ELTREF_BINARY_OP(OP) \ template \ T operator OP (const T& a, const elt_ref& e) { \ return a OP T(e); \ } \ template \ T operator OP (const elt_ref& e, const T& a) { \ return T(e) OP a; \ } \ template \ typename elt_ref::value_type \ operator OP (const elt_ref& f, const elt_ref& e) { \ typedef elt_ref::value_type T; \ return T(f) OP T(e); \ } ELTREF_BINARY_OP(+) ELTREF_BINARY_OP(-) ELTREF_BINARY_OP(*) ELTREF_BINARY_OP(/) #define ELTREF_COMPARISON_OP(OP) \ template \ bool operator OP (const T& a, const elt_ref& e) { \ return a OP T(e); \ } \ template \ bool operator OP (const elt_ref& e, const T& a) { \ return T(e) OP a; \ } \ template \ bool operator OP (const elt_ref& f, const elt_ref& e) { \ typedef elt_ref::value_type T; \ return T(f) OP T(e); \ } ELTREF_COMPARISON_OP(==) ELTREF_COMPARISON_OP(!=) ELTREF_COMPARISON_OP(<) ELTREF_COMPARISON_OP(>) ELTREF_COMPARISON_OP(<=) ELTREF_COMPARISON_OP(>=) #define CONST_ELTREF_BINARY_OP(OP) \ template \ T operator OP (const T& a, const const_elt_ref& e) { \ return a OP T(e); \ } \ template \ T operator OP (const const_elt_ref& e, const T& a) { \ return T(e) OP a; \ } \ template \ typename const_elt_ref::value_type \ operator OP (const const_elt_ref& f, const const_elt_ref& e) { \ typedef const_elt_ref::value_type T; \ return T(f) OP T(e); \ } CONST_ELTREF_BINARY_OP(+) CONST_ELTREF_BINARY_OP(-) CONST_ELTREF_BINARY_OP(*) CONST_ELTREF_BINARY_OP(/) #define CONST_ELTREF_COMPARISON_OP(OP) \ template \ bool operator OP (const T& a, const const_elt_ref& e) { \ return a OP T(e); \ } \ template \ bool operator OP (const const_elt_ref& e, const T& a) { \ return T(e) OP a; \ } \ template \ bool \ operator OP (const const_elt_ref& f, const const_elt_ref& e) { \ typedef const_elt_ref::value_type T; \ return T(f) OP T(e); \ } CONST_ELTREF_COMPARISON_OP(==) CONST_ELTREF_COMPARISON_OP(!=) CONST_ELTREF_COMPARISON_OP(<) CONST_ELTREF_COMPARISON_OP(>) CONST_ELTREF_COMPARISON_OP(<=) CONST_ELTREF_COMPARISON_OP(>=) #endif //: // two indices stored with each element. template struct entry2 { typedef entry2 self; typedef T value_type; int row, col; value_type value; inline entry2() : row(-1), col(-1), value(0.0) { } inline entry2(int r, int c, value_type v = value_type()) : row(r), col(c), value(v) { } inline entry2(const self& x) : row(x.row), col(x.col), value(x.value) { } inline self& operator =(const self& x) { row = x.row; col = x.col; value = x.value; return *this; } inline bool operator == (const entry2& e) const { return row == e.row && col == e.col; } }; } /* namespace mtl */ #endif