cmtkVector.h

Go to the documentation of this file.
00001 /*
00002 //
00003 //  Copyright 1997-2010 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: 2752 $
00026 //
00027 //  $LastChangedDate: 2011-01-17 11:33:31 -0800 (Mon, 17 Jan 2011) $
00028 //
00029 //  $LastChangedBy: torstenrohlfing $
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     // If old and new size are the same, there is nothing to do.
00187     if ( Dim != dim ) 
00188       {
00189       T* newElements = Memory::AllocateArray<T>( dim );
00190       // copy common elements
00191       memcpy( newElements, this->Elements, sizeof(T) * std::min( dim, Dim ) );
00192 
00193       // reset new elements if so desired
00194       if ( zero && (dim > Dim) )
00195         {
00196         memset( newElements + Dim, 0, sizeof(T) * (dim-Dim) );
00197         }
00198 
00199       // new set new array.
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 } // namespace cmtk
00426 
00427 #include "cmtkVector.txx"
00428 
00429 #endif // #ifndef __cmtkVector_h_included_
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines