00001
00002
00003
00004
00005
00006
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
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
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
00290 default:
00291 Array2D<E> remMatrix(0, n-2, 0, n-2);
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 }
00318
00319
00320 #endif