00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021 #ifndef TYPES_INCLUDES
00022 #error "You can't include matrixdata.h directly; Instead, You have to include types.h"
00023
00024 #define MATRIXDATA_H
00025 #endif
00026
00027 #ifndef MATRIXDATA_H
00028 #define MATRIXDATA_H
00029
00034 #include "memutils.h"
00035 #include "vectordata.h"
00036
00037
00038 namespace nnfw {
00039
00046 template<class T, class Vec = VectorData<T> >
00047 class NNFW_TEMPLATE MatrixData : private Observer, private Observable {
00048 public:
00051
00054 MatrixData( u_int rows, u_int cols )
00055 : Observer(), Observable(), data(rows*cols), rowView(rows) {
00056 data.zeroing();
00057 nrows = rows;
00058 ncols = cols;
00059 tsize = nrows*ncols;
00060 for( u_int i=0; i<nrows; i++ ) {
00061 rowView[i].convertToView( data, i*ncols, (i+1)*ncols );
00062 }
00063
00064 view = false;
00065 };
00066
00080 MatrixData( Vec& src, u_int rstart, u_int rend, u_int rows, u_int cols )
00081 : Observer(), Observable(), data(src, rstart, rend), rowView() {
00082
00083 if ( data.size() != rows*cols ) {
00084 nError() << "Wrongs dimensions specified in MatrixData view constructor; This MatrixData will be invalidate" ;
00085 rows = 0;
00086 cols = 0;
00087 }
00088
00089 view = true;
00090
00091 data.addObserver( this );
00092 nrows = rows;
00093 ncols = cols;
00094 tsize = nrows*ncols;
00095 rowView.resize( tsize );
00096 for( u_int i=0; i<nrows; i++ ) {
00097 rowView[i].convertToView( data, i*ncols, (i+1)*ncols );
00098 }
00099 };
00100
00103 ~MatrixData() {
00104
00105 };
00106
00108
00110
00112 u_int rows() const {
00113 return nrows;
00114 };
00116 u_int cols() const {
00117 return ncols;
00118 };
00120 u_int size() const {
00121 return tsize;
00122 };
00123
00126 bool isView() const {
00127 return view;
00128 };
00129
00132 bool operator==( const MatrixData<T,Vec>& b ) {
00133
00134
00135
00136 if ( this->size() != b.size() ) return false;
00137 for( u_int i=0; i<size(); i++ ) {
00138 if ( this->data[i] != b.data[i] ) {
00139 return false;
00140 }
00141 }
00142 return true;
00143 };
00144
00147 bool operator!=( const VectorData<T>& b ) {
00148 return !( *this == b );
00149 };
00150
00152 void resize( u_int rows, u_int cols ) {
00153 if ( view ) {
00154 nError() << "you can't resize a MatrixData view - use setView instead" ;
00155 return;
00156 }
00157 nrows = rows;
00158 ncols = cols;
00159 tsize = nrows*ncols;
00160 data.resize( tsize );
00161 rowView.resize( nrows );
00162
00163 for( u_int i=0; i<nrows; i++ ) {
00164 if ( rowView[i].isView() ) {
00165 rowView[i].setView( i*ncols, (i+1)*ncols );
00166 } else {
00167 rowView[i].convertToView( data, i*ncols, (i+1)*ncols );
00168 }
00169 }
00170
00171
00172
00173
00174 };
00175
00177
00179
00181 T& at( u_int row, u_int col ) {
00182 #ifdef NNFW_DEBUG
00183 if ( row >= nrows ) {
00184 nError() << "Accessing an element beyond Row boundary of matrix" ;
00185 return data[0];
00186 }
00187 if ( col >= ncols ) {
00188 nError() << "Accessing an element beyond Column boundary of matrix" ;
00189 return data[0];
00190 }
00191 #endif
00192 return rowView[row][col];
00193 };
00194
00196 const T& at( u_int row, u_int col ) const {
00197 #ifdef NNFW_DEBUG
00198 if ( row >= nrows ) {
00199 nError() << "Accessing an element beyond Row boundary of matrix" ;
00200 return data[0];
00201 }
00202 if ( col >= ncols ) {
00203 nError() << "Accessing an element beyond Column boundary of matrix" ;
00204 return data[0];
00205 }
00206 #endif
00207 return rowView[row][col];
00208 };
00209
00213 Vec& operator[]( u_int row ) {
00214 #ifdef NNFW_DEBUG
00215 if( row >= nrows ) {
00216 nError() << "Accessing elements outside boundary" ;
00217 return rowView[0];
00218 }
00219 #endif
00220 return rowView[row];
00221 };
00222
00226 const Vec& operator[]( u_int row ) const {
00227 #ifdef NNFW_DEBUG
00228 if( row >= nrows ) {
00229 nError() << "Accessing elements outside boundary" ;
00230 return rowView[0];
00231 }
00232 #endif
00233 return rowView[row];
00234 };
00235
00238 MatrixData& assign( const MatrixData& src ) {
00239 #ifdef NNFW_DEBUG
00240 if( rows() != src.rows() || cols() != src.cols() ) {
00241 nError() << "Different dimension" ;
00242 return (*this);
00243 }
00244 #endif
00245 data.assign( src.data, tsize );
00246 return (*this);
00247 };
00248
00251 void zeroing() {
00252 data.zeroing();
00253 };
00254
00255
00257
00259
00260 class matrixdataIterator;
00261 friend class matrixdataIterator;
00262
00264 typedef T value_type;
00266 typedef T& reference;
00268 typedef const T& const_reference;
00270 typedef matrixdataIterator iterator;
00272 typedef const matrixdataIterator const_iterator;
00274 typedef size_t size_type;
00276 typedef ptrdiff_t difference_type;
00277
00280 size_type max_size() {
00281 return 300000;
00282 };
00283
00286 bool empty() {
00287 return (tsize==0);
00288 };
00289
00292 void clear() {
00293 if ( view ) {
00294 nError() << "you can't clear a MatrixData view" ;
00295 } else {
00296 resize( 0, 0 );
00297 }
00298 };
00299
00302 iterator begin() {
00303 return matrixdataIterator( *this );
00304 };
00307 const_iterator begin() const {
00308 return matrixdataIterator( ((MatrixData&)*this) );
00309 };
00310
00313 iterator end() {
00314 return matrixdataIterator( *this, tsize );
00315 };
00318 const_iterator end() const {
00319 return matrixdataIterator( ((MatrixData&)*this), tsize );
00320 };
00321
00324 class matrixdataIterator : public std::iterator<std::bidirectional_iterator_tag,T,ptrdiff_t> {
00325 public:
00327 matrixdataIterator( MatrixData& data, u_int startId = 0 ) : vecdata(data.data), id(startId), tsize(data.tsize) { };
00329 matrixdataIterator( const matrixdataIterator& src ) : vecdata(src.vecdata), id(src.id), tsize(src.tsize) { };
00331 matrixdataIterator& operator=( const matrixdataIterator& src ) {
00332 vecdata = src.vecdata;
00333 id = src.id;
00334 tsize = src.tsize;
00335 return (*this);
00336 };
00338 bool operator==( const matrixdataIterator& x ) const {
00339 return ( &vecdata == &(x.vecdata) && id == x.id );
00340 };
00342 bool operator!=( const matrixdataIterator& x ) const {
00343 return ( &vecdata != &(x.vecdata) || id != x.id );
00344 };
00346 const T& operator*() const {
00347 return vecdata[id];
00348 };
00350 T& operator*() {
00351 return vecdata[id];
00352 };
00354 matrixdataIterator& operator++() {
00355 id = (id < tsize) ? id+1 : tsize;
00356 return (*this);
00357 };
00359 const matrixdataIterator& operator++() const {
00360 id = (id < tsize) ? id+1 : tsize;
00361 return (*this);
00362 };
00364 matrixdataIterator& operator--() {
00365 id = ( id > 0 ) ? id-1 : 0;
00366 return (*this);
00367 };
00369 const matrixdataIterator& operator--() const {
00370 id = ( id > 0 ) ? id-1 : 0;
00371 return (*this);
00372 };
00374 u_int getIndex() {
00375 return id;
00376 };
00377 private:
00379 Vec& vecdata;
00381 u_int id;
00383 u_int tsize;
00384 };
00386
00387 protected:
00388 friend class RealVec;
00389
00392 Vec& rawdata() const {
00393 return (Vec&)data;
00394 };
00395
00396 private:
00398 u_int nrows;
00400 u_int ncols;
00402 u_int tsize;
00404 Vec data;
00406 VectorData< Vec > rowView;
00407
00409 bool view;
00410
00412 virtual void notify( const NotifyEvent& event ) {
00413 switch( event.type() ) {
00414 case Vec::datachanged:
00415 #ifdef NNFW_DEBUG
00416 nWarning() << "Arrange a MatrixData view after a VectorData resizing can lead to inconsistent settings - see documentation if you not sure" ;
00417 #endif
00418 ncols = data.size() / nrows ;
00419 if ( ncols == 0 ) {
00420 nrows = 0;
00421 ncols = 0;
00422 tsize = 0;
00423 rowView.clear();
00424 } else {
00425 tsize = ncols*nrows;
00426
00427 for( u_int i=0; i<nrows; i++ ) {
00428 rowView[i].setView( i*ncols, (i+1)*ncols );
00429 }
00430 }
00431 break;
00432 case Vec::datadestroying:
00433 #ifdef NNFW_DEBUG
00434 nWarning() << "Destroying a VectorData before its views!!!" ;
00435 #endif
00436
00437 view = false;
00438 nrows = 0;
00439 ncols = 0;
00440 tsize = 0;
00441 rowView.clear();
00442 break;
00443 default:
00444 break;
00445 }
00446
00447
00448
00449 };
00450
00452 MatrixData( const MatrixData& src )
00453 : Observer(), Observable(), data(0), rowView(0) {
00454 };
00455
00456 };
00457
00458 }
00459
00460 #endif
00461