cmtkMatrix.h

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2009 Torsten Rohlfing
00004 //
00005 //  Copyright 2004-2010 SRI International
00006 //
00007 //  This file is part of the Computational Morphometry Toolkit.
00008 //
00009 //  http://www.nitrc.org/projects/cmtk/
00010 //
00011 //  The Computational Morphometry Toolkit is free software: you can
00012 //  redistribute it and/or modify it under the terms of the GNU General Public
00013 //  License as published by the Free Software Foundation, either version 3 of
00014 //  the License, or (at your option) any later version.
00015 //
00016 //  The Computational Morphometry Toolkit is distributed in the hope that it
00017 //  will be useful, but WITHOUT ANY WARRANTY; without even the implied
00018 //  warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00019 //  GNU General Public License for more details.
00020 //
00021 //  You should have received a copy of the GNU General Public License along
00022 //  with the Computational Morphometry Toolkit.  If not, see
00023 //  <http://www.gnu.org/licenses/>.
00024 //
00025 //  $Revision: 2462 $
00026 //
00027 //  $LastChangedDate: 2010-10-19 08:59:01 -0700 (Tue, 19 Oct 2010) $
00028 //
00029 //  $LastChangedBy: torsten_at_home $
00030 //
00031 */
00032 
00033 #ifndef __cmtkMatrix_h_included_
00034 #define __cmtkMatrix_h_included_
00035 
00036 #include <cmtkconfig.h>
00037 
00038 #include <string.h>
00039 #include <vector>
00040 #include <iostream>
00041 
00042 #include <System/cmtkSmartPtr.h>
00043 #include <System/cmtkMemory.h>
00044 
00045 namespace
00046 cmtk
00047 {
00048 
00051 
00052 template<class TElement,size_t NDim>
00053 class Matrix
00054 {
00055 public:
00057   typedef Matrix<TElement,NDim> Self;
00058 
00060   typedef Matrix<TElement,NDim-1> Superclass;
00061 
00063   Matrix( const size_t (&dims)[NDim] )
00064     : m_SubMatrixArray( dims[0] )
00065   {
00066     size_t nItems = dims[0];
00067     for ( size_t i = 1; i < NDim; ++i )
00068       nItems *= dims[i];
00069 
00070     TElement* data = Memory::AllocateArray<TElement>( nItems );
00071   }
00072 
00074   ~Matrix() {};
00075 
00077   typedef typename Superclass::ElementPointerType* ElementPointerType;
00078 
00079   typename Self::ElementPointerType& operator[]( const size_t idx )
00080   {
00081     return this->m_SubMatrixArray[idx];
00082   }
00083   
00084   const typename Self::ElementPointerType& operator[]( const size_t idx ) const
00085   {
00086     return this->m_SubMatrixArray[idx];
00087   }
00088 
00089 protected:
00091   Matrix() {};
00092   
00093 private:
00095   std::vector<typename Self::ElementPointerType> m_SubMatrixArray;
00096 }; // class Matrix
00097 
00098 template<class TElement>
00099 class Matrix<TElement,1>
00100 {
00101 };
00102 
00104 template<class T>
00105 class Matrix2D :
00107   public std::vector<T*>
00108 {
00109 public:
00111   typedef std::vector<T*> Superclass;
00112 
00114   typedef Matrix2D<T> Self;
00115 
00117   typedef SmartPointer<Self> SmartPtr;
00118 
00120   typedef std::vector<T*> RowVectorType;  
00121   
00123   Matrix2D()
00124     : Superclass( 1 )
00125   { 
00126     this->m_NumberOfColumns = 0;
00127     this->m_NumberOfRows = 0;
00128     this->m_NumberOfElements = 0;
00129     
00130     (*this)[0] = NULL;
00131   }
00132   
00134   Matrix2D( const size_t dims1, const size_t dims0, const T* data = NULL )
00135     : Superclass( dims1 )
00136   { 
00137     this->m_NumberOfColumns = dims0;
00138     this->m_NumberOfRows = dims1;
00139     this->m_NumberOfElements = dims0 * dims1;
00140 
00141     (*this)[0] = Memory::AllocateArray<T>(  this->m_NumberOfElements  );
00142     for ( size_t i = 1; i < this->m_NumberOfRows; ++i )
00143       (*this)[i] = (*this)[i-1] + this->m_NumberOfColumns;
00144     
00145     if ( data )
00146       memcpy( (*this)[0], data, this->m_NumberOfElements * sizeof( T ) );
00147   }
00148   
00150   Matrix2D( const Matrix2D<T>& other ) :
00151     Superclass( other.size() )
00152   { 
00153     this->m_NumberOfColumns = other.m_NumberOfColumns;
00154     this->m_NumberOfRows = other.m_NumberOfRows;
00155     this->m_NumberOfElements = other.m_NumberOfElements;
00156 
00157     (*this)[0] = Memory::AllocateArray<T>(  this->m_NumberOfElements  );
00158     for ( size_t i = 1; i < this->m_NumberOfRows; ++i )
00159       (*this)[i] = (*this)[i-1] + this->m_NumberOfColumns;
00160     
00161     memcpy( (*this)[0], other[0], this->m_NumberOfElements * sizeof( T ) );
00162   }
00163 
00165   ~Matrix2D() 
00166   {
00167     if ( (*this)[0] )
00168       {
00169       Memory::DeleteArray( (*this)[0] );
00170       (*this)[0] = NULL;
00171       }
00172   }
00173 
00175   size_t GetNumberOfRows() const 
00176   { 
00177     return this->m_NumberOfRows;
00178   }
00179 
00183   size_t GetNumberOfColumns() const 
00184   { 
00185     return this->m_NumberOfColumns; 
00186   }
00187 
00189   void Resize( const size_t numberOfRows, const size_t numberOfColumns )
00190   {
00191     if ( (numberOfColumns != this->m_NumberOfColumns) ||
00192          (numberOfRows != this->m_NumberOfRows) )
00193       {
00194       if ( (*this)[0] )
00195         {
00196         Memory::DeleteArray( (*this)[0] );
00197         (*this)[0] = NULL;
00198         }
00199       
00200       this->m_NumberOfColumns = numberOfColumns;
00201       this->m_NumberOfRows = numberOfRows;
00202       this->m_NumberOfElements = numberOfColumns * numberOfRows;
00203       
00204       this->Superclass::resize( numberOfRows );
00205       (*this)[0] = Memory::AllocateArray<T>(  this->m_NumberOfElements  );
00206       for ( size_t i = 1; i < numberOfRows; ++i )
00207         (*this)[i] = (*this)[i-1] + numberOfColumns;
00208       }
00209   }
00210   
00212   void SetAllToZero() 
00213   {
00214     memset( (*this)[0], 0, this->m_NumberOfElements * sizeof( T ) );
00215   }
00216   
00218   void SetAll( const T value) 
00219   {
00220     for ( size_t i = 0; i < this->m_NumberOfElements; ++i ) 
00221       {
00222       (*this)[0][i] = value;
00223       }
00224   }
00225   
00227   Matrix2D<T>& operator= ( const Matrix2D<T>& other ) 
00228   {
00229     this->Resize( other.GetNumberOfColumns(), other.GetNumberOfRows() );
00230     memcpy( (*this)[0], other[0], this->m_NumberOfElements * sizeof( T ) );
00231     return *this;
00232   }
00233   
00234 private:
00236   size_t m_NumberOfElements;
00237 
00239   size_t m_NumberOfColumns;
00240 
00242   size_t m_NumberOfRows;
00243 };
00244 
00246 template<class T>
00247 class Matrix3D :
00249   public Matrix2D<T*>
00250 {
00251 public:
00253   typedef Matrix3D<T> Self;
00254 
00256   typedef SmartPointer<Self> SmartPtr;
00257 
00259   typedef Matrix2D<T*> Superclass;
00260 
00262   Matrix3D<T>
00263   ( const size_t dims2, const size_t dims1, const size_t dims0 )
00264     : Matrix2D<T*>( dims2, dims1 )
00265   {
00266     this->m_NumberOfPlanes = dims0;
00267     this->m_NumberOfElements = dims0 * dims1 * dims2;
00268     (*this)[0][0] = Memory::AllocateArray<T>( this->m_NumberOfElements );
00269 
00270     for ( size_t j = 0; j < this->GetNumberOfRows(); ++j )
00271       for ( size_t i = 0; i < this->GetNumberOfColumns(); ++i )
00272         if ( i && j )
00273           {
00274           (*this)[i][j] = (*this)[0][0] + this->GetNumberOfRows() * ( i + this->GetNumberOfColumns() * j );
00275           }
00276   }
00277 
00279   size_t GetNumberOfPlanes() const
00280   {
00281     return this->m_NumberOfPlanes;
00282   }
00283   
00285   void Resize( const size_t numberOfRows, const size_t numberOfColumns, const size_t numberOfPlanes )
00286   {
00287     if ( ( numberOfColumns != this->GetNumberOfColumns() ) ||
00288          ( numberOfRows != this->GetNumberOfRows() ) ||
00289          ( numberOfPlanes != this->GetNumberOfPlanes() ) )
00290       {
00291       if ( (*this)[0][0] )
00292         {
00293         Memory::DeleteArray( (*this)[0][0] );
00294         (*this)[0][0] = NULL;
00295         }
00296       
00297       this->m_NumberOfPlanes = numberOfPlanes;
00298       this->m_NumberOfElements = numberOfPlanes * numberOfRows * numberOfColumns;
00299 
00300       this->Superclass::Resize( numberOfRows, numberOfColumns );
00301       (*this)[0][0] = Memory::AllocateArray<T>( this->m_NumberOfElements );
00302       
00303       for ( size_t j = 0; j < this->GetNumberOfRows(); ++j )
00304         for ( size_t i = 0; i < this->GetNumberOfColumns(); ++i )
00305           if ( i && j )
00306             {
00307             (*this)[i][j] = (*this)[0][0] + this->GetNumberOfPlanes() * ( i + this->GetNumberOfColumns() * j );
00308             }
00309       }
00310   }
00311   
00313   void SetAllToZero() 
00314   {
00315     memset( (*this)[0][0], 0, this->m_NumberOfElements * sizeof( T ) );
00316   }
00317   
00319   void SetAll( const T value) 
00320   {
00321     for ( size_t i = 0; i < this->m_NumberOfElements; ++i ) 
00322       {
00323       (*this)[0][0][i] = value;
00324       }
00325   }
00326   
00328   Matrix2D<T>& operator= ( const Matrix2D<T>& other ) 
00329   {
00330     this->Resize( other.GetNumberOfColumns(), other.GetNumberOfRows(), other.GetNumberOfPlanes() );
00331     memcpy( (*this)[0], other[0], this->m_NumberOfElements * sizeof( T ) );
00332     return *this;
00333   }
00334   
00335 private:
00337   size_t m_NumberOfPlanes;
00338 
00340   size_t m_NumberOfElements;
00341 };
00342 
00344 
00345 } // namespace cmtk
00346 
00347 #endif // #ifndef __cmtkMatrix_h_included_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines