GestureRecognitionToolkit  Version: 0.2.5
The Gesture Recognition Toolkit (GRT) is a cross-platform, open-source, c++ machine learning library for real-time gesture recognition.
Matrix.h
Go to the documentation of this file.
1 
8 /*
9  GRT MIT License
10  Copyright (c) <2012> <Nicholas Gillian, Media Lab, MIT>
11 
12  Permission is hereby granted, free of charge, to any person obtaining a copy of this software
13  and associated documentation files (the "Software"), to deal in the Software without restriction,
14  including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
15  and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so,
16  subject to the following conditions:
17 
18  The above copyright notice and this permission notice shall be included in all copies or substantial
19  portions of the Software.
20 
21  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22  LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
23  IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
25  SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26  */
27 
28 #ifndef GRT_MATRIX_HEADER
29 #define GRT_MATRIX_HEADER
30 
31 #include "../Util/GRTTypedefs.h"
32 #include "Vector.h"
33 #include <exception>
34 #include "../Util/GRTException.h"
35 #include "../Util/ErrorLog.h"
36 
37 GRT_BEGIN_NAMESPACE
38 
39 template <class T> class Matrix{
40 public:
44  Matrix():errorLog("[ERROR Matrix]"){
45  rows = 0;
46  cols = 0;
47  size = 0;
48  capacity = 0;
49  dataPtr = NULL;
50  rowPtr = NULL;
51  }
52 
59  Matrix(const unsigned int rows,const unsigned int cols):errorLog("[ERROR Matrix]"){
60  dataPtr = NULL;
61  rowPtr = NULL;
62  resize(rows,cols);
63  }
64 
72  Matrix(const unsigned int rows,const unsigned int cols, const T &data ):errorLog("[ERROR Matrix]"){
73  dataPtr = NULL;
74  rowPtr = NULL;
75  resize(rows,cols,data);
76  }
77 
83  Matrix(const Matrix &rhs):errorLog("[ERROR Matrix]"){
84  this->dataPtr = NULL;
85  this->rowPtr = NULL;
86  this->rows = 0;
87  this->cols = 0;
88  this->size = 0;
89  this->capacity = 0;
90  this->copy( rhs );
91  }
92 
100  Matrix( const Vector< Vector< T > > &data ):errorLog("[ERROR Matrix]"){
101  this->dataPtr = NULL;
102  this->rowPtr = NULL;
103  this->rows = 0;
104  this->cols = 0;
105  this->size = 0;
106  this->capacity = 0;
107 
108  unsigned int tempRows = data.getSize();
109  unsigned int tempCols = 0;
110 
111  //If there is no data then return
112  if( tempRows == 0 ) return;
113 
114  //Check to make sure all the columns are the same size
115  for(unsigned int i=0; i<tempRows; i++){
116  if( i == 0 ) tempCols = data[i].getSize();
117  else{
118  if( data[i].getSize() != tempCols ){
119  return;
120  }
121  }
122  }
123 
124  if( tempCols == 0 ) return;
125 
126  //Resize the matrix and copy the data
127  if( resize(tempRows,tempCols) ){
128  for(unsigned int i=0; i<tempRows; i++){
129  for(unsigned int j=0; j<tempCols; j++){
130  dataPtr[(i*cols)+j] = data[i][j];
131  }
132  }
133  }
134 
135  }
136 
140  virtual ~Matrix(){
141  clear();
142  }
143 
150  Matrix& operator=(const Matrix &rhs){
151  if(this!=&rhs){
152  this->clear();
153  this->copy( rhs );
154  }
155  return *this;
156  }
157 
164  inline T* operator[](const unsigned int r){
165  return rowPtr[r];
166  }
167 
174  inline const T* operator[](const unsigned int r) const{
175  return rowPtr[r];
176  }
177 
184  Vector< T > getRowVector(const unsigned int r) const{
185  Vector< T > rowVector(cols);
186  for(unsigned int c=0; c<cols; c++)
187  rowVector[c] = dataPtr[r*cols+c];
188  return rowVector;
189  }
190 
197  Vector<T> getColVector(const unsigned int c) const{
198  Vector<T> columnVector(rows);
199  for(unsigned int r=0; r<rows; r++)
200  columnVector[r] = dataPtr[r*cols+c];
201  return columnVector;
202  }
203 
213  Vector<T> getConcatenatedVector(const bool concatByRow = true) const{
214 
215  if( rows == 0 || cols == 0 ) return Vector<T>();
216 
217  Vector<T> vectorData(rows*cols);
218 
219  unsigned int i,j =0;
220 
221  if( concatByRow ){
222  for( i=0; i<rows; i++){
223  for(j=0; j<cols; j++){
224  vectorData[ (i*cols)+j ] = dataPtr[i*cols+j];
225  }
226  }
227  }else{
228  for(j=0; j<cols; j++){
229  for(i=0; i<rows; i++){
230  vectorData[ (i*cols)+j ] = dataPtr[i*cols+j];
231  }
232  }
233  }
234 
235  return vectorData;
236  }
237 
245  virtual bool resize(const unsigned int r,const unsigned int c){
246 
247  if( r + c == 0 ){
248  errorLog << "resize(...) - Failed to resize matrix, rows and cols == zero!" << std::endl;
249  return false;
250  }
251 
252  //If the rows and cols are unchanged then do not resize the data
253  if( r == rows && c == cols ){
254  return true;
255  }
256 
257  //Clear any previous memory
258  clear();
259 
260  if( r > 0 && c > 0 ){
261  try{
262  rows = r;
263  cols = c;
264  size = r * c;
265  capacity = r;
266 
267  dataPtr = new T[size];
268  rowPtr = new T*[rows];
269 
270  if( dataPtr == NULL ){
271  rows = 0;
272  cols = 0;
273  size = 0;
274  capacity = 0;
275  errorLog << "resize(const unsigned r,const unsigned int c) - Failed to allocate memory! r: " << r << " c: " << c << std::endl;
276  throw GRT::Exception("Matrix::resize(const unsigned int r,const unsigned int c) - Failed to allocate memory!");
277  return false;
278  }
279 
280  if( rowPtr == NULL ){
281  rows = 0;
282  cols = 0;
283  size = 0;
284  capacity = 0;
285  errorLog << "resize(const unsigned r,const unsigned int c) - Failed to allocate memory! r: " << r << " c: " << c << std::endl;
286  throw Exception("Matrix::resize(const unsigned int r,const unsigned int c) - Failed to allocate memory!");
287  return false;
288  }
289 
290  //Setup the row pointers
291  unsigned int i=0;
292  T *p = &(dataPtr[0]);
293  for(i=0; i<rows; i++){
294  rowPtr[i] = p;
295  p += cols;
296  }
297 
298  return true;
299 
300  }catch( std::exception& e ){
301  errorLog << "resize: Failed to allocate memory. Error: " << e.what() << " rows: " << r << " cols: " << c << std::endl;
302  clear();
303  return false;
304  }catch( ... ){
305  errorLog << "resize: Failed to allocate memory." << std::endl;
306  clear();
307  return false;
308  }
309  }
310  return false;
311  }
312 
321  virtual bool resize(const unsigned int r,const unsigned int c,const T &value){
322 
323  if( !resize( r, c) ){
324  return false;
325  }
326 
327  return setAll( value );
328  }
329 
336  virtual bool copy( const Matrix<T> &rhs ){
337 
338  if( this != &rhs ){
339 
340  if( this->size != rhs.size ){
341  if( !this->resize( rhs.rows, rhs.cols ) ){
342  throw Exception("Matrix::copy( const Matrix<T> &rhs ) - Failed to allocate resize matrix!");
343  return false;
344  }
345  }
346 
347  //Copy the data
348  unsigned int i = 0;
349  for(i=0; i<size; i++){
350  this->dataPtr[i] = rhs.dataPtr[i];
351  }
352  }
353 
354  return true;
355  }
356 
366  bool setAllValues(const T &value){
367  return setAll( value );
368  }
369 
376  bool setAll(const T &value){
377  if(dataPtr!=NULL){
378  unsigned int i =0;
379  for(i=0; i<size; i++)
380  dataPtr[i] = value;
381  return true;
382  }
383  return false;
384  }
385 
394  bool setRowVector(const Vector<T> &row,const unsigned int rowIndex){
395  if( dataPtr == NULL ) return false;
396  if( row.size() != cols ) return false;
397  if( rowIndex >= rows ) return false;
398 
399  unsigned int j = 0;
400  for(j=0; j<cols; j++)
401  dataPtr[ rowIndex * cols + j ] = row[ j ];
402  return true;
403  }
404 
413  bool setColVector(const Vector<T> &column,const unsigned int colIndex){
414  if( dataPtr == NULL ) return false;
415  if( column.size() != rows ) return false;
416  if( colIndex >= cols ) return false;
417 
418  for(unsigned int i=0; i<rows; i++)
419  dataPtr[ i * cols + colIndex ] = column[ i ];
420  return true;
421  }
422 
431  bool push_back(const Vector<T> &sample){
432 
433  unsigned int i,j = 0;
434 
435  //If there is no data, but we know how many cols are in a sample then we simply create a new buffer of size 1 and add the sample
436  if(dataPtr==NULL){
437  cols = (unsigned int)sample.size();
438  if( !resize(1,cols) ){
439  clear();
440  return false;
441  }
442  for(j=0; j<cols; j++)
443  dataPtr[ j ] = sample[j];
444  return true;
445  }
446 
447  //If there is data and the sample size does not match the number of columns then return false
448  if(sample.size() != cols ){
449  return false;
450  }
451 
452  //Check to see if we have reached the capacity, if not then simply add the new data as there are unused rows
453  if( rows < capacity ){
454  //Add the new sample at the end
455  for(j=0; j<cols; j++)
456  dataPtr[rows * cols + j] = sample[j];
457 
458  }else{ //Otherwise we copy the existing data from the data ptr into a new buffer of size (rows+1) and add the sample at the end
459 
460  const unsigned int tmpRows = rows + 1;
461  T* tmpDataPtr = new T[tmpRows*cols];
462  T** tmpRowPtr = new T*[tmpRows];
463 
464  if( tmpDataPtr == NULL || tmpRowPtr == NULL ){//If NULL then we have run out of memory
465  return false;
466  }
467 
468  //Setup the row pointers
469  T *p = &(tmpDataPtr[0]);
470  for(i=0; i<tmpRows; i++){
471  tmpRowPtr[i] = p;
472  p += cols;
473  }
474 
475  //Copy the original data into the tmp buffer
476  for(i=0; i<rows*cols; i++)
477  tmpDataPtr[i] = dataPtr[i];
478 
479  //Add the new sample at the end of the tmp buffer
480  for(j=0; j<cols; j++)
481  tmpDataPtr[rows*cols+j] = sample[j];
482 
483  //Delete the original data and copy the pointer
484  delete[] dataPtr;
485  delete[] rowPtr;
486  dataPtr = tmpDataPtr;
487  rowPtr = tmpRowPtr;
488 
489  //Increment the capacity so it matches the number of rows
490  capacity++;
491  }
492 
493  //Increment the number of rows
494  rows++;
495 
496  //Update the size
497  size = rows * cols;
498 
499  //Finally return true to signal that the data was added correctly
500  return true;
501  }
502 
510  bool reserve( const unsigned int capacity ){
511 
512  //If the number of columns has not been set, then we can not do anything
513  if( cols == 0 ) return false;
514 
515  //Reserve the data and copy and existing data
516  unsigned int i=0;
517  T* tmpDataPtr = new T[ capacity * cols ];
518  T** tmpRowPtr = new T*[ capacity ];
519  if( tmpDataPtr == NULL || tmpRowPtr == NULL ){//If NULL then we have run out of memory
520  return false;
521  }
522 
523  //Setup the row pointers
524  T *p = &(tmpDataPtr[0]);
525  for(i=0; i<capacity; i++){
526  tmpRowPtr[i] = p;
527  p += cols;
528  }
529 
530  //Copy the existing data into the new memory
531  for(i=0; i<size; i++)
532  tmpDataPtr[i] = dataPtr[i];
533 
534  //Delete the original data and copy the pointer
535  delete[] dataPtr;
536  delete[] rowPtr;
537  dataPtr = tmpDataPtr;
538  rowPtr = tmpRowPtr;
539 
540  //Store the new capacity
541  this->capacity = capacity;
542 
543  //Store the size
544  size = rows * cols;
545 
546  return true;
547  }
548 
553  bool clear(){
554  if( dataPtr != NULL ){
555  delete[] dataPtr;
556  dataPtr = NULL;
557  }
558  if( rowPtr != NULL ){
559  delete[] rowPtr;
560  rowPtr = NULL;
561  }
562  rows = 0;
563  cols = 0;
564  size = 0;
565  capacity = 0;
566  return true;
567  }
568 
574  inline unsigned int getNumRows() const{ return rows; }
575 
581  inline unsigned int getNumCols() const{ return cols; }
582 
589  inline unsigned int getCapacity() const{ return capacity; }
590 
596  inline unsigned int getSize() const{ return size; }
597 
603  T** getDataPointer() const{
604  if( rowPtr == NULL ){
605  throw Exception("Matrix::getDataPointer() - Matrix has not been initialized!");
606  }
607  return &(rowPtr[0]);
608  }
609 
615  T* getData() const {
616  return dataPtr;
617  }
618 
619 protected:
620  unsigned int rows;
621  unsigned int cols;
622  unsigned int size;
623  unsigned int capacity;
624  T *dataPtr;
625  T **rowPtr;
626  ErrorLog errorLog;
627 };
628 
629 GRT_END_NAMESPACE
630 
631 #endif //Header guard
unsigned int getSize() const
Definition: Matrix.h:596
The Vector class is a basic class for storing any type of data. The default Vector is an interface fo...
T * operator[](const unsigned int r)
Definition: Matrix.h:164
bool setRowVector(const Vector< T > &row, const unsigned int rowIndex)
Definition: Matrix.h:394
bool setAll(const T &value)
Definition: Matrix.h:376
Matrix(const Matrix &rhs)
Definition: Matrix.h:83
Matrix(const unsigned int rows, const unsigned int cols, const T &data)
Definition: Matrix.h:72
T * getData() const
Definition: Matrix.h:615
unsigned int getCapacity() const
Definition: Matrix.h:589
bool clear()
Definition: Matrix.h:553
T ** rowPtr
A pointer to each row in the data.
Definition: Matrix.h:625
Matrix()
Definition: Matrix.h:44
bool setAllValues(const T &value)
Definition: Matrix.h:366
bool reserve(const unsigned int capacity)
Definition: Matrix.h:510
virtual ~Matrix()
Definition: Matrix.h:140
Matrix & operator=(const Matrix &rhs)
Definition: Matrix.h:150
bool setColVector(const Vector< T > &column, const unsigned int colIndex)
Definition: Matrix.h:413
Vector< T > getRowVector(const unsigned int r) const
Definition: Matrix.h:184
unsigned int rows
The number of rows in the Matrix.
Definition: Matrix.h:620
Vector< T > getConcatenatedVector(const bool concatByRow=true) const
Definition: Matrix.h:213
unsigned int getNumRows() const
Definition: Matrix.h:574
unsigned int getNumCols() const
Definition: Matrix.h:581
Matrix(const Vector< Vector< T > > &data)
Definition: Matrix.h:100
T ** getDataPointer() const
Definition: Matrix.h:603
virtual bool copy(const Matrix< T > &rhs)
Definition: Matrix.h:336
unsigned int size
Stores rows * cols.
Definition: Matrix.h:622
Definition: Matrix.h:39
Vector< T > getColVector(const unsigned int c) const
Definition: Matrix.h:197
const T * operator[](const unsigned int r) const
Definition: Matrix.h:174
T * dataPtr
A pointer to the raw data.
Definition: Matrix.h:624
unsigned int cols
The number of columns in the Matrix.
Definition: Matrix.h:621
Matrix(const unsigned int rows, const unsigned int cols)
Definition: Matrix.h:59
virtual bool resize(const unsigned int r, const unsigned int c)
Definition: Matrix.h:245
virtual bool resize(const unsigned int r, const unsigned int c, const T &value)
Definition: Matrix.h:321
Definition: Vector.h:41
bool push_back(const Vector< T > &sample)
Definition: Matrix.h:431
unsigned int capacity
The capacity of the Matrix, this will be the number of rows, not the actual memory size...
Definition: Matrix.h:623