Open
Graph Drawing
Framework

 v.2010.10
 

Array2D.h

Go to the documentation of this file.
00001 /*
00002  * $Revision: 2030 $
00003  * 
00004  * last checkin:
00005  *   $Author: gutwenger $ 
00006  *   $Date: 2010-09-03 10:29:11 +0200 (Fri, 03 Sep 2010) $ 
00007  ***************************************************************/
00008  
00053 #ifdef _MSC_VER
00054 #pragma once
00055 #endif
00056 
00057 #ifndef OGDF_ARRAY2D_H
00058 #define OGDF_ARRAY2D_H
00059 
00060 
00061 #include <ogdf/basic/basic.h>
00062 #include <math.h>
00063 
00064 
00065 namespace ogdf {
00066 
00067 
00069 template<class E> class Array2D
00070 {
00071 public:
00072     // constructors
00073 
00075     Array2D() { construct(0,-1,0,-1); }
00076 
00078     Array2D(int a, int b, int c, int d) {
00079         construct(a,b,c,d); initialize();
00080     }
00081 
00083     Array2D(int a, int b, int c, int d, const E &x) {
00084         construct(a,b,c,d); initialize(x);
00085     }
00086 
00088     Array2D(const Array2D<E> &array2) {
00089         copy(array2);
00090     }
00091 
00092     // destructor
00093      ~Array2D() {
00094          deconstruct();
00095     }
00096 
00098     int low1() const { return m_a; }
00099 
00101     int high1() const { return m_b; }
00102 
00104     int low2() const { return m_c; }
00105 
00107     int high2() const { return m_d; }
00108 
00110     int size() const { return size1() * size2(); }
00111 
00113     int size1() const { return m_b - m_a + 1; }
00114 
00116     int size2() const { return m_lenDim2; }
00117 
00119 
00120     float det();
00121 
00123     const E &operator()(int i, int j) const {
00124         OGDF_ASSERT(m_a <= i && i <= m_b && m_c <= j && j <= m_d);
00125         return m_vpStart[(i-m_a)*m_lenDim2+j];
00126     }
00127 
00129     E &operator()(int i, int j) {
00130         OGDF_ASSERT(m_a <= i && i <= m_b && m_c <= j && j <= m_d);
00131         return m_vpStart[(i-m_a)*m_lenDim2+j];
00132     }
00133 
00135     void init() { init(0,-1,0,-1); }
00136 
00138     void init(int a, int b, int c, int d) {
00139         deconstruct();
00140         construct(a,b,c,d);
00141         initialize();
00142     }
00143 
00145     void init(int a, int b, int c, int d, const E &x) {
00146         deconstruct();
00147         construct(a,b,c,d);
00148         initialize(x);
00149     }
00150 
00152     Array2D<E> &operator=(const Array2D<E> &array2) {
00153         deconstruct();
00154         copy(array2);
00155         return *this;
00156     }
00157 
00159     void fill(const E &x) {
00160         E *pDest = m_pStop;
00161         while(pDest > m_pStart)
00162             *--pDest = x;
00163     }
00164 
00165 private:
00166     E   *m_vpStart; 
00167     int  m_a; 
00168     int  m_lenDim2; 
00169     E   *m_pStart; 
00170     E   *m_pStop; 
00171     int  m_b; 
00172     int  m_c; 
00173     int  m_d; 
00174 
00175     void construct(int a, int b, int c, int d);
00176 
00177     void initialize();
00178     void initialize(const E &x);
00179 
00180     void deconstruct();
00181 
00182     void copy(const Array2D<E> &array2);
00183 
00184 };
00185 
00186 
00187 
00188 template<class E>
00189 void Array2D<E>::construct(int a, int b, int c, int d)
00190 {
00191     m_a = a;
00192     m_b = b;
00193     m_c = c;
00194     m_d = d;
00195 
00196     int lenDim1 = b-a+1;
00197     m_lenDim2   = d-c+1;
00198     
00199     if (lenDim1 < 1 || m_lenDim2 < 1) {
00200         m_pStart = m_vpStart = m_pStop = 0;
00201 
00202     } else {
00203         int len = lenDim1*m_lenDim2;
00204         m_pStart = (E *)malloc(len*sizeof(E));
00205         if (m_pStart == 0)
00206             OGDF_THROW(InsufficientMemoryException);
00207 
00208         m_vpStart = m_pStart - c;
00209         m_pStop   = m_pStart + len;
00210     }
00211 }
00212 
00213 
00214 template<class E>
00215 void Array2D<E>::initialize()
00216 {
00217     E *pDest = m_pStart;
00218     try {
00219         for (; pDest < m_pStop; pDest++)
00220             new(pDest) E;
00221     } catch (...) {
00222         while(--pDest >= m_pStart)
00223             pDest->~E();
00224         free(m_pStart);
00225         throw;
00226     }
00227 }
00228 
00229 
00230 template<class E>
00231 void Array2D<E>::initialize(const E &x)
00232 {
00233     E *pDest = m_pStart;
00234     try {
00235         for (; pDest < m_pStop; pDest++)
00236             new(pDest) E(x);
00237     } catch (...) {
00238         while(--pDest >= m_pStart)
00239             pDest->~E();
00240         free(m_pStart);
00241         throw;
00242     }
00243 }
00244 
00245 
00246 template<class E>
00247 void Array2D<E>::deconstruct()
00248 {
00249     if (doDestruction((E*)0)) {
00250         for (E *pDest = m_pStart; pDest < m_pStop; pDest++)
00251             pDest->~E();
00252     }
00253     free(m_pStart);
00254 }
00255 
00256 
00257 template<class E>
00258 void Array2D<E>::copy(const Array2D<E> &array2)
00259 {
00260     construct(array2.m_a, array2.m_b, array2.m_c, array2.m_d);
00261 
00262     if (m_pStart != 0) {
00263         E *pSrc  = array2.m_pStop;
00264         E *pDest = m_pStop;
00265         while(pDest > m_pStart)
00266             new (--pDest) E(*--pSrc);
00267     }
00268 }
00269 
00270 
00271 
00272 template<class E>
00273 float Array2D<E>::det()
00274 {
00275   int a = m_a;
00276   int b = m_b;
00277   int c = m_c;
00278   int d = m_d;
00279   int m = m_b - m_a + 1;
00280   int n = m_lenDim2;
00281 
00282   int i, j;
00283   int rem_i, rem_j, column;
00284 
00285   float determinant = 0.0;
00286 
00287   OGDF_ASSERT(m == n);
00288 
00289   switch(n) {
00290   case 0:
00291     break;
00292   case 1:
00293     determinant = (float)((*this)(a, c));
00294     break;
00295   case 2:
00296     determinant = (float)((*this)(a, c) * (*this)(b, d) - (*this)(a, d) * (*this)(b, c));
00297     break;
00298 
00299   // Expanding along the first row (Laplace's Formula)
00300   default:
00301     Array2D<E> remMatrix(0, n-2, 0, n-2);             // the remaining matrix
00302     for(column = c; column <= d; column++) {
00303       rem_i = 0;
00304       rem_j = 0;
00305       for(i = a; i <= b; i++) {
00306     for(j = c; j <= d; j++) {
00307       if(i != a && j != column) {
00308         remMatrix(rem_i, rem_j) = (*this)(i, j);
00309         if(rem_j < n-2) {
00310           rem_j++;
00311         }
00312         else {
00313           rem_i++;
00314           rem_j = 0;
00315         }
00316       }
00317     }
00318       }
00319       determinant += pow(-1,(a+column)) * (*this)(a,column) * remMatrix.det();
00320     }
00321   }  
00322   return determinant;
00323 }
00324 
00325 
00326 
00327 } // end namespace ogdf
00328 
00329 
00330 #endif