Open
Graph Drawing
Framework

 v.2012.07
 

Array2D.h
Go to the documentation of this file.
1 /*
2  * $Revision: 2615 $
3  *
4  * last checkin:
5  * $Author: gutwenger $
6  * $Date: 2012-07-16 14:23:36 +0200 (Mo, 16. Jul 2012) $
7  ***************************************************************/
8 
44 #ifdef _MSC_VER
45 #pragma once
46 #endif
47 
48 #ifndef OGDF_ARRAY2D_H
49 #define OGDF_ARRAY2D_H
50 
51 
52 #include <ogdf/basic/basic.h>
53 #include <math.h>
54 
55 
56 namespace ogdf {
57 
58 
60 
63 template<class E> class Array2D
64 {
65 public:
66  // constructors
67 
69  Array2D() { construct(0,-1,0,-1); }
70 
72  Array2D(int a, int b, int c, int d) {
73  construct(a,b,c,d); initialize();
74  }
75 
77  Array2D(int a, int b, int c, int d, const E &x) {
78  construct(a,b,c,d); initialize(x);
79  }
80 
82  Array2D(const Array2D<E> &array2) {
83  copy(array2);
84  }
85 
86  // destructor
88  deconstruct();
89  }
90 
92  int low1() const { return m_a; }
93 
95  int high1() const { return m_b; }
96 
98  int low2() const { return m_c; }
99 
101  int high2() const { return m_d; }
102 
104  int size() const { return size1() * size2(); }
105 
107  int size1() const { return m_b - m_a + 1; }
108 
110  int size2() const { return m_lenDim2; }
111 
113 
114  float det() const;
115 
117  const E &operator()(int i, int j) const {
118  OGDF_ASSERT(m_a <= i && i <= m_b && m_c <= j && j <= m_d);
119  return m_vpStart[(i-m_a)*m_lenDim2+j];
120  }
121 
123  E &operator()(int i, int j) {
124  OGDF_ASSERT(m_a <= i && i <= m_b && m_c <= j && j <= m_d);
125  return m_vpStart[(i-m_a)*m_lenDim2+j];
126  }
127 
129  void init() { init(0,-1,0,-1); }
130 
132  void init(int a, int b, int c, int d) {
133  deconstruct();
134  construct(a,b,c,d);
135  initialize();
136  }
137 
139  void init(int a, int b, int c, int d, const E &x) {
140  deconstruct();
141  construct(a,b,c,d);
142  initialize(x);
143  }
144 
146  Array2D<E> &operator=(const Array2D<E> &array2) {
147  deconstruct();
148  copy(array2);
149  return *this;
150  }
151 
153  void fill(const E &x) {
154  E *pDest = m_pStop;
155  while(pDest > m_pStart)
156  *--pDest = x;
157  }
158 
159 private:
161  int m_a;
162  int m_lenDim2;
163  E *m_pStart;
164  E *m_pStop;
165  int m_b;
166  int m_c;
167  int m_d;
168 
169  void construct(int a, int b, int c, int d);
170 
171  void initialize();
172  void initialize(const E &x);
173 
174  void deconstruct();
175 
176  void copy(const Array2D<E> &array2);
177 
178 };
179 
180 
181 
182 template<class E>
183 void Array2D<E>::construct(int a, int b, int c, int d)
184 {
185  m_a = a;
186  m_b = b;
187  m_c = c;
188  m_d = d;
189 
190  int lenDim1 = b-a+1;
191  m_lenDim2 = d-c+1;
192 
193  if (lenDim1 < 1 || m_lenDim2 < 1) {
194  m_pStart = m_vpStart = m_pStop = 0;
195 
196  } else {
197  int len = lenDim1*m_lenDim2;
198  m_pStart = (E *)malloc(len*sizeof(E));
199  if (m_pStart == 0)
201 
202  m_vpStart = m_pStart - c;
203  m_pStop = m_pStart + len;
204  }
205 }
206 
207 
208 template<class E>
210 {
211  E *pDest = m_pStart;
212  try {
213  for (; pDest < m_pStop; pDest++)
214  new(pDest) E;
215  } catch (...) {
216  while(--pDest >= m_pStart)
217  pDest->~E();
218  free(m_pStart);
219  throw;
220  }
221 }
222 
223 
224 template<class E>
225 void Array2D<E>::initialize(const E &x)
226 {
227  E *pDest = m_pStart;
228  try {
229  for (; pDest < m_pStop; pDest++)
230  new(pDest) E(x);
231  } catch (...) {
232  while(--pDest >= m_pStart)
233  pDest->~E();
234  free(m_pStart);
235  throw;
236  }
237 }
238 
239 
240 template<class E>
242 {
243  if (doDestruction((E*)0)) {
244  for (E *pDest = m_pStart; pDest < m_pStop; pDest++)
245  pDest->~E();
246  }
247  free(m_pStart);
248 }
249 
250 
251 template<class E>
252 void Array2D<E>::copy(const Array2D<E> &array2)
253 {
254  construct(array2.m_a, array2.m_b, array2.m_c, array2.m_d);
255 
256  if (m_pStart != 0) {
257  E *pSrc = array2.m_pStop;
258  E *pDest = m_pStop;
259  while(pDest > m_pStart)
260  new (--pDest) E(*--pSrc);
261  }
262 }
263 
264 
265 
266 template<class E>
267 float Array2D<E>::det() const
268 {
269  int a = m_a;
270  int b = m_b;
271  int c = m_c;
272  int d = m_d;
273  int m = m_b - m_a + 1;
274  int n = m_lenDim2;
275 
276  int i, j;
277  int rem_i, rem_j, column;
278 
279  float determinant = 0.0;
280 
281  OGDF_ASSERT(m == n);
282 
283  switch(n) {
284  case 0:
285  break;
286  case 1:
287  determinant = (float)((*this)(a, c));
288  break;
289  case 2:
290  determinant = (float)((*this)(a, c) * (*this)(b, d) - (*this)(a, d) * (*this)(b, c));
291  break;
292 
293  // Expanding along the first row (Laplace's Formula)
294  default:
295  Array2D<E> remMatrix(0, n-2, 0, n-2); // the remaining matrix
296  for(column = c; column <= d; column++) {
297  rem_i = 0;
298  rem_j = 0;
299  for(i = a; i <= b; i++) {
300  for(j = c; j <= d; j++) {
301  if(i != a && j != column) {
302  remMatrix(rem_i, rem_j) = (*this)(i, j);
303  if(rem_j < n-2) {
304  rem_j++;
305  }
306  else {
307  rem_i++;
308  rem_j = 0;
309  }
310  }
311  }
312  }
313  determinant += pow(-1.0,(a+column)) * (*this)(a,column) * remMatrix.det();
314  }
315  }
316 
317  return determinant;
318 }
319 
320 
321 
322 } // end namespace ogdf
323 
324 
325 #endif