00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #ifndef _CJMATRIXIMPL_1D_H_
00021 #define _CJMATRIXIMPL_1D_H_ 1
00022
00023 #include "CjMatrix.hh"
00024 #include "CjMatrixImpl.hh"
00025 #include <iostream>
00026 #include <boost/tokenizer.hpp>
00027 #include <sstream>
00028
00029 #include <vector>
00030 #include <string>
00031 #include <fstream>
00032 #include <iterator>
00033 #include <algorithm>
00034 #include <cassert>
00035 #include "JLOG.hh"
00036 #include <boost/lexical_cast.hpp>
00037
00038 template <typename> class CjMatrix;
00039 template <typename> class CjMatrixImpl;
00040
00041 template <typename T> class CjMatrixImpl_1D: public CjMatrixImpl<T> {
00042
00043 protected:
00045 T * m_data;
00047 unsigned int m_width;
00049 unsigned int m_height;
00051 unsigned int m_size;
00053 T m_defaultValue;
00054 bool m_defaultValueSet;
00055
00056 public:
00057
00059
00066 CjMatrixImpl_1D ( const unsigned int width, const unsigned int height, const T * const defaultValue = 0 );
00068
00072 explicit CjMatrixImpl_1D (const CjMatrixImpl_1D<T> & cjm);
00073
00075
00083 CjMatrixImpl_1D (const CjMatrix<T> & cjm, const unsigned int width, const unsigned int height, const T * const defaultValue = 0);
00084
00086
00096 template <typename V> CjMatrixImpl_1D (V m, const unsigned int w, const unsigned int h, const unsigned int width, const unsigned int height, const T * const defaultValue = 0);
00097
00099 ~CjMatrixImpl_1D();
00100
00102
00107 void swap(CjMatrixImpl_1D & other);
00108
00110
00113 CjMatrixImpl<T> * clone() const;
00114
00115 void resizeImpl(const unsigned int width, const unsigned int height);
00116 void resize_with_copyImpl( const unsigned int width, const unsigned int height, const CjMatrix<T> * const cjm = (CjMatrix<T> *) 0);
00117 void setColumnValuesImpl( const unsigned int col, const T & val );
00118 void setRowValuesImpl( const unsigned int row, const T & val );
00119 void setAllValuesImpl(const T & val);
00120 void setDiagonalImpl(const T & val);
00121 void setDefaultValueImpl(const T & val);
00122 T getDefaultValueImpl() const;
00123 bool getDefaultValueSetImpl() const;
00124 bool equalElements(const CjMatrix<T> &) const;
00125 void transposeImpl();
00126 bool isSymmetricImpl() const;
00127 unsigned int getWidthImpl() const;
00128 unsigned int getHeightImpl() const;
00129 T & atImpl(unsigned int row, unsigned int col);
00130 const T & atImpl(unsigned int row, unsigned int col) const;
00131 T & getImpl (unsigned int row, unsigned int col);
00132 const T & getImpl (unsigned int row, unsigned int col) const;
00134
00135
00136 CjMatrixImpl_1D<T> & operator=(const CjMatrixImpl_1D<T> & );
00137
00138 private:
00139
00140 void resize_with_copyImpl(const unsigned int width, const unsigned int height, const CjMatrixImpl_1D<T> * const cjmi );
00141
00142 };
00143
00144 template <typename T> inline CjMatrixImpl<T> * CjMatrixImpl_1D<T>::clone() const {
00145 CjMatrixImpl_1D<T> * retval = new CjMatrixImpl_1D<T>(*this);
00146 return retval;
00147 }
00148
00150
00153 template <typename T> inline void CjMatrixImpl_1D<T>::swap(CjMatrixImpl_1D<T> & that) {
00154 std::swap(that.m_data, m_data);
00155 std::swap(that.m_width, m_width);
00156 std::swap(that.m_height, m_height);
00157 std::swap(that.m_size, m_size);
00158 std::swap(that.m_defaultValue, m_defaultValue);
00159 std::swap(that.m_defaultValueSet, m_defaultValueSet);
00160 }
00161
00163
00168 template <typename T> inline CjMatrixImpl_1D<T>::CjMatrixImpl_1D (const unsigned int width, const unsigned int height, const T * const defaultValue):m_data((T *)0),m_width(0),m_height(0),m_size(0),m_defaultValueSet(false) {
00169 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::CjMatrixImpl_1D (const unsigned int (" << width << "), const unsigned int (" << height << "), T defaultValue ) called." << std::endl; )
00170 if(defaultValue) setDefaultValueImpl(*defaultValue);
00171 resizeImpl(width,height);
00172 }
00173
00175
00178 template <typename T> inline CjMatrixImpl_1D<T>::CjMatrixImpl_1D (const CjMatrixImpl_1D<T> & cjmi):m_data((T *)0),m_width(0),m_height(0),m_size(0),m_defaultValueSet(false) {
00179 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::CjMatrixImpl_1D (const CjMatrixImpl_1D &) called." << std::endl; )
00180 operator=(cjmi);
00181 }
00182
00184
00187 template <typename T> inline CjMatrixImpl_1D<T> & CjMatrixImpl_1D<T>::operator=(const CjMatrixImpl_1D<T> & cjmi) {
00188 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::operator=(const CjMatrixImpl_1D<T> &) called." << std::endl;)
00189 if (this != &cjmi) {
00190 this->resize_with_copyImpl(cjmi.getWidthImpl(), cjmi.getHeightImpl(), &cjmi );
00191 }
00192 return *this;
00193 }
00194
00195 template <typename T> inline bool CjMatrixImpl_1D<T>::getDefaultValueSetImpl() const { return m_defaultValueSet; }
00196
00197
00198
00199 template <typename T> CjMatrixImpl_1D<T>::CjMatrixImpl_1D (const CjMatrix<T> & cjm, const unsigned int width, const unsigned int height, const T * const defaultValue):m_data((T *)0),m_width(0),m_height(0),m_size(0),m_defaultValueSet(false) {
00200 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::CjMatrixImpl_1D (const CjMatrixImpl_1D & cjm, unsigned int width, unsigned int height, T * defaultValue = 0) called." << std::endl; )
00201 if(defaultValue != 0) setDefaultValueImpl(*defaultValue);
00202 resize_with_copyImpl(width, height, &cjm );
00203 }
00204
00205
00206
00207
00208 template <typename T> template <typename V> CjMatrixImpl_1D<T>::CjMatrixImpl_1D (V m, const unsigned int w, const unsigned int h, const unsigned int width, const unsigned int height, const T * const defaultValue):m_data((T *)0),m_width(0),m_height(0),m_size(0),m_defaultValueSet(false) {
00209
00210 if((0==width)||(0==height)) throw E_CjMatrix_SizeError("Neither width nor height can be zero in CjMatrixImpl_1D (const T * const * const m, const unsigned int w, const unsigned int h, const unsigned int width, const unsigned int height, const T * const defaultValue = 0)");
00211
00212 unsigned int min_h = std::min(h,height);
00213 unsigned int min_w = std::min(w,width);
00214
00215 CjMatrixImpl_1D <T> tmp(width,height);
00216
00217 JLOG(4, std::cout << " min_w is " << min_w << " and min_h is " << min_h << std::endl; )
00218 for(unsigned int row=0; row < min_h; ++row)
00219 std::copy( &m[row][0], &m[row][min_w], tmp.m_data+(row*width) );
00220
00221 if(defaultValue != 0) tmp.setDefaultValueImpl(*defaultValue);
00222
00223 if(m_defaultValueSet) {
00224 for(unsigned int col=min_w; col < width; ++col) tmp.setColumnValuesImpl(col, m_defaultValue);
00225 for(unsigned int row=min_h; row < height; ++row) tmp.setRowValuesImpl(row, m_defaultValue);
00226 }
00227 swap(tmp);
00228 }
00229
00230 template <typename T> void CjMatrixImpl_1D<T>::resize_with_copyImpl(const unsigned int width, const unsigned int height, const CjMatrix<T> * const cjm ) {
00231
00232
00233 if((0==width)||(0==height)) throw E_CjMatrix_SizeError("Neither width nor height can be zero in CjMatrixImpl_1D<T>::resize_with_copyImpl");
00234
00235 unsigned int old_w = (cjm==0)?m_width:cjm->getWidth();
00236 unsigned int old_h = (cjm==0)?m_height:cjm->getHeight();
00237
00238 unsigned int min_h = std::min(old_h,height);
00239 unsigned int min_w = std::min(old_w,width);
00240
00241 CjMatrixImpl_1D <T> tmp(width,height);
00242
00243 JLOG(4, std::cout << " min_w is " << min_w << " and min_h is " << min_h << std::endl; )
00244 for(unsigned int row=0; row < min_h; ++row)
00245 if(cjm) std::copy( cjm->row(row).cbegin(), cjm->row(row).cbegin()+min_w, tmp.m_data+(row*width) );
00246 else std::copy( m_data+(row*m_width), m_data+(row*m_width)+min_w, tmp.m_data+(row*width) );
00247
00248 if(m_defaultValueSet) {
00249 for(unsigned int col=min_w; col < width; ++col) tmp.setColumnValuesImpl(col, m_defaultValue);
00250 for(unsigned int row=min_h; row < height; ++row) tmp.setRowValuesImpl(row, m_defaultValue);
00251 }
00252 swap(tmp);
00253 }
00254
00255 template <typename T> void CjMatrixImpl_1D<T>::resize_with_copyImpl(const unsigned int width, const unsigned int height, const CjMatrixImpl_1D<T> * const cjmi ) {
00256
00257
00258 if(cjmi == this) return;
00259 if((0==width)||(0==height)) throw E_CjMatrix_SizeError("Neither width nor height can be zero in CjMatrixImpl_1D<T>::resize_with_copyImpl");
00260
00261 unsigned int old_w = (cjmi==0)?m_width:cjmi->getWidthImpl();
00262 unsigned int old_h = (cjmi==0)?m_height:cjmi->getHeightImpl();
00263
00264 unsigned int min_h = std::min(old_h,height);
00265 unsigned int min_w = std::min(old_w,width);
00266
00267 CjMatrixImpl_1D <T> tmp(width,height);
00268
00269 JLOG(4, std::cout << " min_w is " << min_w << " and min_h is " << min_h << std::endl; )
00270 for(unsigned int row=0; row < min_h; ++row)
00271 if(cjmi) std::copy( cjmi->m_data+(row*width), cjmi->m_data+(row*width)+min_w, tmp.m_data+(row*width) );
00272 else std::copy( m_data+(row*m_width), m_data+(row*m_width)+min_w, tmp.m_data+(row*width) );
00273
00274 if(m_defaultValueSet) {
00275 for(unsigned int col=min_w; col < width; ++col) tmp.setColumnValuesImpl(col, m_defaultValue);
00276 for(unsigned int row=min_h; row < height; ++row) tmp.setRowValuesImpl(row, m_defaultValue);
00277 }
00278 swap(tmp);
00279 }
00280
00281 template <typename T> void CjMatrixImpl_1D<T>::setColumnValuesImpl(const unsigned int col, const T & val) {
00282 for(unsigned int i=0;i<m_height;++i) m_data[i*m_width+col] = val;
00283 }
00284
00285 template <typename T> void CjMatrixImpl_1D<T>::setRowValuesImpl(const unsigned int row, const T & val) {
00286 std::fill_n( m_data+(row*m_width), m_width, val );
00287 }
00288
00289 template <typename T> void CjMatrixImpl_1D<T>::setAllValuesImpl(const T & val) {
00290 std::fill( m_data, m_data+m_size, val );
00291 }
00292
00293 template <typename T> void CjMatrixImpl_1D<T>::setDiagonalImpl(const T & val) {
00294 for( unsigned int i=0 ; i < std::min(m_width, m_height) ; ++i ) m_data[i*m_width+i] = val;
00295 }
00296
00297 template <typename T> void CjMatrixImpl_1D<T>::resizeImpl(const unsigned int width, const unsigned int height) {
00298
00299 unsigned int new_size = width*height;
00300 if((0==width)||(0==height)) throw E_CjMatrix_SizeError("Neither width nor height can be zero in CjMatrixImpl_1D<T>::resizeImpl");
00301
00302 if((m_size==new_size)&&(m_data != (T *) 0)) {
00303 m_width = width;
00304 m_height = height;
00305 } else {
00306 try {
00307 T * new_arr = new T[new_size];
00308 std::swap(new_arr,m_data);
00309 m_size = new_size;
00310 m_width = width;
00311 m_height = height;
00312 delete [] new_arr;
00313 new_arr = (T *)0;
00314
00315 } catch (std::bad_alloc &) { throw E_CjMatrix_MemoryAllocFail(); }
00316 }
00317 if (m_defaultValueSet) setAllValuesImpl(m_defaultValue);
00318 }
00319
00320 template <typename T> void CjMatrixImpl_1D<T>::setDefaultValueImpl(const T & val) { m_defaultValue = val; m_defaultValueSet = true; }
00321 template <typename T> T CjMatrixImpl_1D<T>::getDefaultValueImpl() const { return m_defaultValue; }
00322
00323 template <typename T> unsigned int CjMatrixImpl_1D<T>::getWidthImpl() const { return m_width; };
00324 template <typename T> unsigned int CjMatrixImpl_1D<T>::getHeightImpl() const { return m_height; };
00325
00326 template <typename T> inline T & CjMatrixImpl_1D<T>::atImpl(const unsigned int row, const unsigned int col) {
00327 if((row>=m_height)||(col>=m_width)) {
00328 throw E_CjMatrix_BoundsError( "CjMatrixImpl_1D<T>::atImpl(const unsigned int row, const unsigned int col): Bounds error - (" + boost::lexical_cast<std::string>(row) + "," + boost::lexical_cast<std::string>(col) + ") was requested but height = " + boost::lexical_cast<std::string>(m_height) + " width = " + boost::lexical_cast<std::string>(m_width) );
00329 }
00330 return getImpl(row,col);
00331 }
00332
00333 template <typename T> inline const T & CjMatrixImpl_1D<T>::atImpl(const unsigned int row, const unsigned int col) const {
00334 if((row>=m_height)||(col>=m_width)) {
00335 throw E_CjMatrix_BoundsError( "CjMatrixImpl_1D<T>::atImpl(const unsigned int row, const unsigned int col) const: Bounds error - (" + boost::lexical_cast<std::string>(row) + "," + boost::lexical_cast<std::string>(col) + ") was requested but height = " + boost::lexical_cast<std::string>(m_height) + " width = " + boost::lexical_cast<std::string>(m_width) );
00336 }
00337 return getImpl(row,col);
00338 }
00339
00340 template <typename T> inline T & CjMatrixImpl_1D<T>::getImpl (const unsigned int row, const unsigned int col) {
00341 return *(m_data+col+(row*m_width));
00342 }
00343
00344 template <typename T> inline const T & CjMatrixImpl_1D<T>::getImpl (const unsigned int row, const unsigned int col) const {
00345 return *(m_data+col+(row*m_width));
00346 }
00347
00348 template <typename T> bool CjMatrixImpl_1D<T>::equalElements(const CjMatrix<T> & cjm) const {
00349 if ( ( cjm.getWidth() != m_width ) || ( cjm.getHeight() != m_height ) ) return false;
00350 bool different = false;
00351 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::equalElements: comparing " << m_width << "x" << m_height << " against " << cjm.getWidth() << "x" << cjm.getHeight() << std::endl; )
00352 for(unsigned int row=0;(row<m_height) && !different;++row)
00353 for(unsigned int col=0;col<m_width;++col)
00354 if(atImpl(row,col)!=cjm(row,col)) {
00355 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::equalElements: Element mismatch at " << row << "," << col << ": " << atImpl(row,col) << " vs " << cjm(row,col) << std::endl; )
00356 different = true;
00357 break;
00358 }
00359 JLOG(4, std::cout << "CjMatrixImpl_1D<T>::equalElements: end." << std::endl; )
00360 return !different;
00361 }
00362
00363
00364
00365 template <typename T> void CjMatrixImpl_1D<T>::transposeImpl(){
00366
00367
00368 if((m_height==1)||(m_width==1)) { std::swap(m_width,m_height); return; }
00369
00370 if(m_height==m_width) {
00371 for(unsigned int i=0;i<m_height;++i)
00372 for(unsigned int j=i+1;j<m_width;++j) {
00373 std::swap( *(m_data+j+(m_width*i)), *(m_data+i+(m_width*j)) );
00374 }
00375 return;
00376 } else {
00377
00378
00379 try {
00380 T * new_arr = new T[m_size];
00381 for(unsigned int i=0;i<m_height;++i)
00382 for(unsigned int j=0;j<m_width;++j) {
00383 std::swap( m_data[j+(m_width*i)], new_arr[i+(m_height*j)] );
00384 }
00385 std::swap(m_width,m_height);
00386 std::swap(new_arr,m_data);
00387 delete [] new_arr;
00388 } catch (std::bad_alloc &) { throw E_CjMatrix_MemoryAllocFail(); }
00389 }
00390
00391 }
00392
00393
00394 template <typename T> CjMatrixImpl_1D<T>::~CjMatrixImpl_1D() { delete [] m_data; m_data = (T *)0; }
00395
00396 template <typename T> bool CjMatrixImpl_1D<T>::isSymmetricImpl() const {
00397 if(m_width != m_height) return false;
00398 for(unsigned int i = 1; i < m_width; ++i)
00399 for(unsigned int j = i+1; j < m_height; ++j)
00400 if(getImpl(i,j) != getImpl(j,i)) return false;
00401 return true;
00402 }
00403
00404
00405
00406 template <typename T> CjMatrixImpl_1D <T> * makeCjMatrixImpl_1D(const char * const inputFileName, const char * const delim = ", \t", unsigned int max_width = 0, unsigned int max_height = 0, T * default_value = 0 ) {
00407 std::cout << "makeCjMatrixImpl_1D(const char *, const char *) called." << std::endl;
00408 std::string inputText;
00409 std::string buf;
00410 typedef std::vector<T> vectorT_t;
00411 typedef std::vector< vectorT_t > vec_VectorT_t;
00412 vec_VectorT_t rows;
00413
00414 T val;
00415
00416 int lineNo = 0;
00417 int ncols = -1;
00418 unsigned int j;
00419
00420 std::ifstream inFile(inputFileName);
00421
00422 if( !inFile ) {
00423 throw E_CjMatrix_FileError(std::string("makeCjMatrixImpl_1D(const char *, const char *): Couldn't open file for reading: ").append(inputFileName) );
00424 }
00425 std::vector <T> v;
00426 while( inFile.good() ) {
00427 std::getline(inFile, inputText);
00428 lineNo++;
00429 std::vector<std::string> tokens;
00430 boost::char_separator<char> sep (delim);
00431 boost::tokenizer< boost::char_separator<char> > tok(inputText, sep);
00432 std::copy( tok.begin(), tok.end(), std::back_inserter(tokens));
00433
00434 if(tokens.size()==0) {
00435
00436 continue;
00437 }
00438 if(tokens.front().compare("#") == 0) {
00439
00440 continue;
00441 }
00442 j = 1;
00443 v.clear();
00444 for(std::vector<std::string>::iterator it = tokens.begin(); it != tokens.end(); ++it, ++j) {
00445 std::istringstream ss(*it);
00446 ss >> std::noskipws >> val;
00447 if ( (!ss) && (!ss.eof()) ) {
00448
00449 std::ostringstream oss;
00450 oss << "makeCjMatrixImpl_1D(const char *, const char *): Invalid input in entry " << j << " on line " << lineNo << " in file " << inputFileName;
00451 throw E_CjMatrix_FileError(oss.str());
00452 }
00453 v.push_back(val);
00454
00455 }
00456
00457
00458 if( ncols == -1 ) ncols = v.size();
00459 else if( (int)v.size() != ncols) {
00460 std::ostringstream oss;
00461 oss << "makeCjMatrixImpl_1D(const char *, const char *): Incorrect number of entries in line " << lineNo << " - was expecting " << ncols << " but got " << v.size();
00462 throw E_CjMatrix_FileError(oss.str());
00463 }
00464 rows.push_back(v);
00465 }
00466 std::cout << "Just read " << ncols << " by " << rows.size() << " from file " << inputFileName << std::endl;
00467
00468 return new CjMatrixImpl_1D<T>(rows, ncols, rows.size(), (max_width!=0)?max_width:(unsigned int)ncols, (max_height!=0)?max_height:rows.size(), default_value);
00469 }
00470
00471 #endif // _CJMATRIXIMPL_1D_H_