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_