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