Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Array2D.h
Go to the documentation of this file.
1 
33 #pragma once
34 
35 #include <ogdf/basic/basic.h>
36 #include <ogdf/basic/exceptions.h>
37 
38 #include <cmath>
39 #include <cstdlib>
40 #include <new>
41 #include <type_traits>
42 
43 namespace ogdf {
44 
45 
47 
52 template<class E>
53 class Array2D {
54 public:
55  // constructors
56 
58  Array2D() { construct(0, -1, 0, -1); }
59 
61  Array2D(int a, int b, int c, int d) {
62  construct(a, b, c, d);
63  initialize();
64  }
65 
67  Array2D(int a, int b, int c, int d, const E& x) {
68  construct(a, b, c, d);
69  initialize(x);
70  }
71 
73  Array2D(const Array2D<E>& A) { copy(A); }
74 
76 
83  , m_pStop(A.m_pStop)
84  , m_a(A.m_a)
85  , m_b(A.m_b)
86  , m_c(A.m_c)
87  , m_d(A.m_d) {
88  A.construct(0, -1, 0, -1);
89  }
90 
93 
95  int low1() const { return m_a; }
96 
98  int high1() const { return m_b; }
99 
101  int low2() const { return m_c; }
102 
104  int high2() const { return m_d; }
105 
107  int size() const { return size1() * size2(); }
108 
110  int size1() const { return m_b - m_a + 1; }
111 
113  int size2() const { return m_lenDim2; }
114 
116 
117  float det() const;
118 
120  const E& operator()(int i, int j) const {
121  OGDF_ASSERT(m_a <= i);
122  OGDF_ASSERT(i <= m_b);
123  OGDF_ASSERT(m_c <= j);
124  OGDF_ASSERT(j <= m_d);
125  return m_vpStart[size_t(i - m_a) * m_lenDim2 + j];
126  }
127 
129  E& operator()(int i, int j) {
130  OGDF_ASSERT(m_a <= i);
131  OGDF_ASSERT(i <= m_b);
132  OGDF_ASSERT(m_c <= j);
133  OGDF_ASSERT(j <= m_d);
134  return m_vpStart[size_t(i - m_a) * m_lenDim2 + j];
135  }
136 
138  void init() { init(0, -1, 0, -1); }
139 
141  void init(int a, int b, int c, int d) {
142  deconstruct();
143  construct(a, b, c, d);
144  initialize();
145  }
146 
148  void init(int a, int b, int c, int d, const E& x) {
149  deconstruct();
150  construct(a, b, c, d);
151  initialize(x);
152  }
153 
155  Array2D<E>& operator=(const Array2D<E>& array2) {
156  deconstruct();
157  copy(array2);
158  return *this;
159  }
160 
162 
166  deconstruct();
167 
168  m_vpStart = A.m_vpStart;
169  m_pStart = A.m_pStart;
170  m_pStop = A.m_pStop;
171  m_lenDim2 = A.m_lenDim2;
172  m_a = A.m_a;
173  m_b = A.m_b;
174  m_c = A.m_c;
175  m_d = A.m_d;
176 
177  A.construct(0, -1, 0, -1);
178  return *this;
179  }
180 
182  void fill(const E& x) {
183  E* pDest = m_pStop;
184  while (pDest > m_pStart) {
185  *--pDest = x;
186  }
187  }
188 
189 private:
191  int m_lenDim2;
192  E* m_pStart;
193  E* m_pStop;
194 
195  int m_a;
196  int m_b;
197  int m_c;
198  int m_d;
199 
200  void construct(int a, int b, int c, int d);
201 
202  void initialize();
203  void initialize(const E& x);
204 
205  void deconstruct();
206 
207  void copy(const Array2D<E>& array2);
208 };
209 
211 template<class E>
212 void Array2D<E>::construct(int a, int b, int c, int d) {
213  m_a = a;
214  m_b = b;
215  m_c = c;
216  m_d = d;
217 
218  size_t lenDim1 = b - a + 1;
219  m_lenDim2 = d - c + 1;
220 
221  if (lenDim1 < 1 || m_lenDim2 < 1) {
222  m_pStart = m_vpStart = m_pStop = nullptr;
223 
224  } else {
225  size_t len = lenDim1 * m_lenDim2;
226  m_pStart = static_cast<E*>(malloc(len * sizeof(E)));
227  if (m_pStart == nullptr) {
229  }
230 
231  m_vpStart = m_pStart - c;
232  m_pStop = m_pStart + len;
233  }
234 }
235 
237 template<class E>
239  E* pDest = m_pStart;
240  try {
241  for (; pDest < m_pStop; pDest++) {
242  new (pDest) E;
243  }
244  } catch (...) {
245  while (--pDest >= m_pStart) {
246  pDest->~E();
247  }
248  free(m_pStart);
249  throw;
250  }
251 }
252 
254 template<class E>
255 void Array2D<E>::initialize(const E& x) {
256  E* pDest = m_pStart;
257  try {
258  for (; pDest < m_pStop; pDest++) {
259  new (pDest) E(x);
260  }
261  } catch (...) {
262  while (--pDest >= m_pStart) {
263  pDest->~E();
264  }
265  free(m_pStart);
266  throw;
267  }
268 }
269 
271 template<class E>
273  if (!std::is_trivially_destructible<E>::value) {
274  for (E* pDest = m_pStart; pDest < m_pStop; pDest++) {
275  pDest->~E();
276  }
277  }
278  free(m_pStart);
279 }
280 
282 template<class E>
283 void Array2D<E>::copy(const Array2D<E>& array2) {
284  construct(array2.m_a, array2.m_b, array2.m_c, array2.m_d);
285 
286  if (m_pStart != 0) {
287  E* pSrc = array2.m_pStop;
288  E* pDest = m_pStop;
289  while (pDest > m_pStart) {
290  new (--pDest) E(*--pSrc);
291  }
292  }
293 }
294 
296 template<class E>
297 float Array2D<E>::det() const {
298  // matrix must be quadratic
299  OGDF_ASSERT(size1() == size2());
300 
301  int a = m_a;
302  int b = m_b;
303  int c = m_c;
304  int d = m_d;
305  int n = m_lenDim2;
306 
307  int i, j;
308  int column;
309 
310  float determinant = 0.0;
311 
312  switch (n) {
313  case 0:
314  break;
315  case 1:
316  determinant = (float)((*this)(a, c));
317  break;
318  case 2:
319  determinant = (float)((*this)(a, c) * (*this)(b, d) - (*this)(a, d) * (*this)(b, c));
320  break;
321 
322  // Expanding along the first row (Laplace's Formula)
323  default:
324  Array2D<E> remMatrix(0, n - 2, 0, n - 2); // the remaining matrix
325  for (column = c; column <= d; column++) {
326  int rem_i = 0;
327  int rem_j = 0;
328  for (i = a; i <= b; i++) {
329  for (j = c; j <= d; j++) {
330  if (i != a && j != column) {
331  remMatrix(rem_i, rem_j) = (*this)(i, j);
332  if (rem_j < n - 2) {
333  rem_j++;
334  } else {
335  rem_i++;
336  rem_j = 0;
337  }
338  }
339  }
340  }
341  determinant += pow(-1.0, (a + column)) * (*this)(a, column) * remMatrix.det();
342  }
343  }
344 
345  return determinant;
346 }
347 
348 }
ogdf::Array2D::Array2D
Array2D()
Creates a two-dimensional array with empty index set.
Definition: Array2D.h:58
ogdf
The namespace for all OGDF objects.
Definition: multilevelmixer.cpp:39
ogdf::Array2D::size
int size() const
Returns the size (number of elements) of the array.
Definition: Array2D.h:107
ogdf::Array2D::det
float det() const
Returns the determinant of the matrix.
Definition: Array2D.h:297
ogdf::Array2D::high2
int high2() const
Returns the maximal array index in dimension 2.
Definition: Array2D.h:104
ogdf::Array2D::Array2D
Array2D(int a, int b, int c, int d, const E &x)
Creates a two-dimensional array with index set [a, ..., b]*[c, ..., d] and initailizes all elements w...
Definition: Array2D.h:67
exceptions.h
Definition of exception classes.
ogdf::Array2D::deconstruct
void deconstruct()
Call destructor of all elements.
Definition: Array2D.h:272
ogdf::Array2D::construct
void construct(int a, int b, int c, int d)
Constructs the array with index set [a, ..., b]*[c, ..., d].
Definition: Array2D.h:212
ogdf::Array2D::size2
int size2() const
Returns the length of the index interval (number of entries) in dimension 2.
Definition: Array2D.h:113
ogdf::InsufficientMemoryException
Exception thrown when not enough memory is available to execute an algorithm.
Definition: exceptions.h:209
OGDF_ASSERT
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition: basic.h:66
ogdf::Array2D::m_c
int m_c
The lowest index in dimension 2.
Definition: Array2D.h:197
ogdf::whaType::A
@ A
ogdf::Array2D::Array2D
Array2D(const Array2D< E > &A)
Creates a two-dimensional array that is a copy of A.
Definition: Array2D.h:73
ogdf::Array2D
The parameterized class Array2D implements dynamic two-dimensional arrays.
Definition: Array2D.h:53
ogdf::Array2D::initialize
void initialize()
Initializes the array with default constructor of E.
Definition: Array2D.h:238
ogdf::Array2D::Array2D
Array2D(int a, int b, int c, int d)
Creates a two-dimensional array with index set [a, ..., b]*[c, ..., d].
Definition: Array2D.h:61
ogdf::Array2D::fill
void fill(const E &x)
Sets all elements to x.
Definition: Array2D.h:182
ogdf::Array2D::operator()
E & operator()(int i, int j)
Returns a reference to the element with index (i,j).
Definition: Array2D.h:129
ogdf::Array2D::Array2D
Array2D(Array2D< E > &&A)
Creates a two-dimensional array containing the elements of A (move semantics).
Definition: Array2D.h:79
ogdf::Array2D::init
void init()
Reinitializes the array to an array with empty index set.
Definition: Array2D.h:138
ogdf::Array2D::high1
int high1() const
Returns the maximal array index in dimension 1.
Definition: Array2D.h:98
ogdf::Array2D::m_a
int m_a
The lowest index in dimension 1.
Definition: Array2D.h:195
ogdf::Array2D::m_b
int m_b
The highest index in dimension 1.
Definition: Array2D.h:196
OGDF_THROW
#define OGDF_THROW(CLASS)
Replacement for throw.
Definition: exceptions.h:74
ogdf::Array2D::low1
int low1() const
Returns the minimal array index in dimension 1.
Definition: Array2D.h:95
ogdf::Array2D::operator=
Array2D< E > & operator=(const Array2D< E > &array2)
Assignment operator.
Definition: Array2D.h:155
ogdf::Array2D::m_d
int m_d
The highest index in dimension 2.
Definition: Array2D.h:198
ogdf::Array2D::m_pStart
E * m_pStart
The real start of the array (address of A[low1,low2]).
Definition: Array2D.h:192
ogdf::Array2D::init
void init(int a, int b, int c, int d, const E &x)
Reinitializes the array to an array with index set [a, ..., b]*[c, ..., d] and initializes all entrie...
Definition: Array2D.h:148
ogdf::Array2D::size1
int size1() const
Returns the length of the index interval (number of entries) in dimension 1.
Definition: Array2D.h:110
ogdf::Array2D::copy
void copy(const Array2D< E > &array2)
Copy array2.
Definition: Array2D.h:283
ogdf::Array2D::low2
int low2() const
Returns the minimal array index in dimension 2.
Definition: Array2D.h:101
basic.h
Basic declarations, included by all source files.
ogdf::Array2D::m_vpStart
E * m_vpStart
The virtual start of the array (address of A[0,0]).
Definition: Array2D.h:190
ogdf::Array2D::init
void init(int a, int b, int c, int d)
Reinitializes the array to an array with index set [a, ..., b]*[c, ..., d].
Definition: Array2D.h:141
ogdf::Array2D::operator()
const E & operator()(int i, int j) const
Returns a reference to the element with index (i,j).
Definition: Array2D.h:120
ogdf::Array2D::m_pStop
E * m_pStop
Successor of last element (address of A[high1,high2+1]).
Definition: Array2D.h:193
ogdf::Array2D::~Array2D
~Array2D()
Destructor.
Definition: Array2D.h:92
ogdf::Array2D::m_lenDim2
int m_lenDim2
The number of elements in dimension 2.
Definition: Array2D.h:191
ogdf::Array2D::operator=
Array2D< E > & operator=(Array2D< E > &&A)
Assignment operator (move semantics).
Definition: Array2D.h:165