#ifndef _MTL_BANDED_INDEXER_ #define _MTL_BANDED_INDEXER_ #include "mtl/orien.h" // for row/column_orien? #include "mtl/matrix_traits.h" namespace mtl { template class banded_indexer { public: enum { M = 0, N = 0 } ; typedef dimension dim_type; typedef dimension band_type; // need negatives for unit upper dim_type dim; band_type bandwidth; typedef typename Orien::orientation orientation; typedef banded_tag shape; typedef banded_indexer transpose_type; typedef banded_indexer strided_type; //JGS VC++ doesn't like friend class transpose_type; typedef Orien orienter; class OneDIndexer { public: inline OneDIndexer() { } inline OneDIndexer(size_type majornum, size_type s) : major_num(majornum), start(s) { } inline OneDIndexer(const OneDIndexer& x) : major_num(x.major_num), start(x.start) { } template inline size_type row(OneDIterator i) const { return Orien::row(coords(i)); } template inline size_type column(OneDIterator i) const { return Orien::column(coords(i)); } template inline size_type minor(OneDIterator i) const { return coords(i).second(); } template inline OneDIterator begin(OneDIterator i) const { return i; } inline size_type at(size_type i) const { return i - start; } protected: template inline dim_type coords(OneDIterator i) const { #if 0 cout << endl; cout << "i.index: " << i.index() << " "; cout << "major num: " << major_num << " "; cout << "start: " << start << endl; #endif return dim_type(major_num, i.index() + start); } size_type major_num; size_type start; }; inline banded_indexer() { } inline banded_indexer(dim_type d, band_type band) : dim(d), bandwidth(band) { } inline banded_indexer(const banded_indexer& x) : dim(x.dim), bandwidth(x.bandwidth) { } inline banded_indexer(const strided_type& x, strideable) : dim(x.dim.transpose()), bandwidth(x.bandwidth.transpose()) { } inline banded_indexer(const transpose_type& x, not_strideable) : dim(x.dim), bandwidth(x.bandwidth) { } template inline OneDIndexer deref(TwoDIterator iter) const { int i = iter.index(); int l = bandwidth.first(); // cout << "l: " << l << endl; // int u = bandwidth.second(); size_type start = MTL_MAX(i - int(l), 0); return OneDIndexer(i, start); } inline OneDIndexer deref(size_type i) const { int l = bandwidth.first(); // cout << "l: " << l << endl; // int u = bandwidth.second(); size_type start = MTL_MAX(int(i) - int(l), 0); return OneDIndexer(i, start); } inline dim_type at(dim_type p) const { dim_type m = Orien::map(p); return dim_type(m.first(), m.second() - MTL_MAX(int(m.first()) - int(bandwidth.first()), 0)); } inline static dim_type twod_dim(dim_type d, band_type ) { return d; } inline static band_type twod_band(dim_type , band_type bw) { return bw; } inline size_type nrows() const { return Orien::row(dim); } inline size_type ncols() const { return Orien::column(dim); } inline int sub() const { return Orien::row(bandwidth); } inline int super() const { return Orien::column(bandwidth); } }; //: blah //!noindex: template struct gen_banded_indexer { typedef dimension twod_dim_type; // no static twod's with banded typedef gen_banded_indexer< typename Orien::transpose_type, MM, NN, size_type> transpose_type; typedef gen_banded_indexer< typename Orien::transpose_type, NN, MM, size_type> strided_type; // bogus Orien typedef banded_indexer type; template struct bind { typedef gen_banded_indexer other; }; typedef Orien orienter; }; } /* namespace mtl */ #endif