Go to the documentation of this file.00001 
00002 
00003 
00004 
00005 
00006 
00007 
00008 
00009 
00010 
00011 
00012 
00013 
00014 
00015 
00016 
00017 
00018 
00019 
00020 
00021 
00022 
00023 
00024 
00025 
00026 
00027 
00028 
00029 
00030 
00031 
00032 
00033 #ifndef __cmtkVector_h_included_
00034 #define __cmtkVector_h_included_
00035 
00036 #include <cmtkconfig.h>
00037 
00038 #include <stdio.h>
00039 #include <stdlib.h>
00040 #include <cassert>
00041 #include <math.h>
00042 #include <string.h>
00043 
00044 #include <algorithm>
00045 
00046 #include <Base/cmtkMathUtil.h>
00047 #include <Base/cmtkTypes.h>
00048 #include <System/cmtkSmartPtr.h>
00049 
00050 namespace
00051 cmtk
00052 {
00053 
00056 
00060 template<class T>
00061 class Vector
00062 {
00063 public:
00065   size_t Dim;
00066 
00068   T *Elements;
00069 
00071   typedef Vector<T> Self;
00072 
00074   typedef SmartPointer<Self> SmartPtr;
00075 
00078 
00079   Vector ( const size_t dim = 0, const T value = 0 ) 
00080   {
00081     Dim = dim;
00082     if ( Dim ) 
00083       {
00084       Elements = Memory::AllocateArray<T>( Dim );
00085       FreeElements = true;
00086       if ( value==0 )
00087         memset( Elements, 0, Dim * sizeof(T) );
00088       else
00089         for ( size_t i=0; i<Dim; ++i )
00090           Elements[i]=value;
00091       } 
00092     else
00093       {
00094       Elements = NULL;
00095       FreeElements = false;
00096       }
00097   }
00098 
00101   Vector ( const size_t dim, T *const elements, const bool freeElements = true ) 
00102   {
00103     Dim = dim;
00104     Elements = elements;
00105     FreeElements = freeElements;
00106   }
00107   
00109   Vector ( const Vector& other, const size_t len = 0, const size_t from = 0 ) 
00110   {
00111     if ( len )
00112       Dim = std::min( len, other.Dim - from );
00113     else
00114       Dim = other.Dim - from;
00115     
00116     Elements = Memory::AllocateArray<T>( Dim );
00117     FreeElements = true;
00118     memcpy( Elements, other.Elements + from, Dim * sizeof(T) );
00119   }
00121 
00123   Vector* Clone( const size_t len = 0, const size_t from = 0 ) const
00124   { 
00125     return new Vector( *this, len, from ); 
00126   }
00127   
00129   ~Vector () 
00130   {
00131     if ( Elements && FreeElements ) 
00132       {
00133       Memory::DeleteArray( this->Elements );
00134       }
00135   }
00136   
00148   Vector& SetDim ( const size_t dim, const bool zero = true ) 
00149   {
00150     if ( Dim != dim ) 
00151       {
00152       if ( Elements ) 
00153         {
00154         Memory::DeleteArray( this->Elements );
00155         }
00156 
00157       Dim = dim;
00158       
00159       if ( Dim ) 
00160         {
00161         Elements = Memory::AllocateArray<T>( Dim );
00162         } 
00163       else
00164         Elements = NULL;
00165       }
00166     
00167     if ( zero && Dim ) 
00168       {
00169       memset( Elements, 0, Dim * sizeof(T) );
00170       }
00171     
00172     return *this;
00173   }
00174   
00184   Vector& AdjustDimension( const size_t dim, const bool zero = true ) 
00185   {
00186     
00187     if ( Dim != dim ) 
00188       {
00189       T* newElements = Memory::AllocateArray<T>( dim );
00190       
00191       memcpy( newElements, this->Elements, sizeof(T) * std::min( dim, Dim ) );
00192 
00193       
00194       if ( zero && (dim > Dim) )
00195         {
00196         memset( newElements + Dim, 0, sizeof(T) * (dim-Dim) );
00197         }
00198 
00199       
00200       this->Dim = dim;
00201       if ( this->FreeElements )
00202         {
00203         Memory::DeleteArray( this->Elements );
00204         }
00205       this->Elements = newElements;
00206       this->FreeElements = true;
00207       } 
00208     
00209     return *this;
00210   }
00211   
00213   Vector& operator = ( const Vector& other ) 
00214   {
00215     if ( Dim != other.Dim ) {
00216     if (Elements) 
00217       {
00218       Memory::DeleteArray( this->Elements );
00219       Elements = NULL;
00220       }
00221     
00222     Dim = other.Dim;
00223     }
00224     
00225     if ( Elements == NULL ) 
00226       {
00227       Elements = Memory::AllocateArray<T>( Dim );
00228       }
00229     
00230     memcpy( Elements, other.Elements, Dim * sizeof(T) );
00231     return *this; 
00232   }
00233 
00241   void CopyToOffset( const Vector& other, const size_t offs = 0, size_t len = 0 )
00242   {
00243     if ( ! len ) 
00244       len = std::min( this->Dim - offs, other.Dim );
00245     for ( size_t idx=0; idx<len; ++idx )
00246       Elements[offs+idx] = other.Elements[idx];
00247   }
00248 
00250   int operator== ( const Vector& other ) const 
00251   {
00252     if ( Dim != other.Dim )
00253       return 0;
00254     
00255     for ( size_t i=0; i<Dim; ++i )
00256       if ( Elements[i] != other.Elements[i] )
00257         return 0;
00258     
00259     return 1;
00260   }
00261   
00263   int operator!= ( const Vector& other ) const 
00264   {
00265     return !(*this == other );
00266   }
00267   
00269   T EuclidNorm () const 
00270   { 
00271     T Result = 0;
00272     
00273 #ifndef __SUNPRO_CC
00274 #pragma omp parallel for if (Dim>1e4) reduction(+:Result)
00275 #endif
00276     for ( size_t i=0; i<this->Dim; ++i ) 
00277       {
00278       const T e = Elements[i];
00279       Result+=e*e;
00280       }
00281     
00282     return sqrt(Result);
00283   }
00284 
00286   T MaxNorm () const 
00287   { 
00288     T Result = 0;
00289     
00290     for ( size_t i=0; i<Dim; ++i ) 
00291       {
00292       Result = std::max<T>( Result, fabs( Elements[i] ) );
00293       }
00294     
00295     return Result;
00296   }
00297 
00299   void Clear() 
00300   { 
00301     memset( Elements, 0, Dim * sizeof( *Elements ) ); 
00302   }
00303 
00305   void SetAll( const T value )
00306   {
00307 #ifndef __SUNPRO_CC
00308 #pragma omp parallel for if (Dim>1e5)
00309 #endif
00310     for ( size_t i=0; i < this->Dim; ++i ) 
00311       this->Elements[i] = value;
00312   }
00313 
00315   T& operator [] ( const size_t index ) 
00316   {
00317     return this->Elements[index];
00318   }
00319 
00321   const T& operator [] ( const size_t index ) const 
00322   {
00323     return this->Elements[index];
00324   }
00325 
00327   Vector<T>& operator+= ( const Vector<T>& delta ) 
00328   {
00329     assert( Dim == delta.Dim );
00330 
00331 #ifndef __SUNPRO_CC
00332 #pragma omp parallel for if (Dim>1e4)
00333 #endif
00334     for ( size_t i=0; i<this->Dim; ++i )
00335       Elements[i] += delta.Elements[i];
00336     
00337     return *this;
00338   }
00339 
00341   Vector<T>& operator-= ( const Vector<T>& delta ) 
00342   {
00343     assert( Dim == delta.Dim );
00344     
00345 #ifndef __SUNPRO_CC
00346 #pragma omp parallel for if (Dim>1e4)
00347 #endif
00348     for ( size_t i=0; i < this->Dim; ++i )
00349       Elements[i] -= delta.Elements[i];
00350     
00351     return *this;
00352   }
00353 
00355   Vector<T>& operator*= ( const T a ) 
00356   {
00357 #ifndef __SUNPRO_CC
00358 #pragma omp parallel for if (Dim>1e4)
00359 #endif
00360     for ( size_t i=0; i<this->Dim; ++i )
00361       this->Elements[i] *= a;
00362     
00363     return *this;
00364   }
00365 
00366   void Print ( FILE *const fp = NULL, const char* format = " %f" ) const 
00367   {
00368     if ( fp ) 
00369       {
00370       for ( size_t idx=0; idx < Dim; ++idx )
00371         fprintf( fp, format, (float) Elements[idx] );
00372       fputs( "\n", fp );
00373       } 
00374     else
00375       {
00376       for ( size_t idx=0; idx < Dim; ++idx )
00377         printf( format, (float) Elements[idx] );
00378       puts( "" );
00379       }
00380   }
00381   
00389   void Sort( const size_t from = 0, const size_t len = 0 ) 
00390   {
00391     T *ptr = Elements+from;
00392     if ( len )
00393       qsort( ptr, len, sizeof( T ), Vector<T>::Compare );
00394     else
00395       qsort( ptr, Dim-from, sizeof( T ), Vector<T>::Compare );
00396   }
00397   
00398 private:
00400   bool FreeElements;
00401 
00403   static int Compare( const void* a, const void* b ) 
00404   {
00405     const T *Ta = (const T *) a;
00406     const T *Tb = (const T *) b;
00407     return (*Ta > *Tb) - (*Ta < *Tb);
00408   }
00409 };
00410 
00415 typedef Vector<Types::Coordinate> CoordinateVector;
00416 
00421 typedef Vector<float> FloatVector;
00422 
00424 
00425 } 
00426 
00427 #include "cmtkVector.txx"
00428 
00429 #endif // #ifndef __cmtkVector_h_included_