Open
Graph Drawing
Framework

 v.2012.05
 

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