00001
00002
00003
00004
00005
00006
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
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
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
00300 default:
00301 Array2D<E> remMatrix(0, n-2, 0, n-2);
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 }
00328
00329
00330 #endif