Open
Graph Drawing
Framework

 v. 2023.09 (Elderberry)
 

Loading...
Searching...
No Matches
Array2D.h
Go to the documentation of this file.
1
33#pragma once
34
35#include <ogdf/basic/basic.h>
37
38#include <cmath>
39#include <cstdlib>
40#include <new>
41#include <type_traits>
42
43namespace ogdf {
44
45
47
52template<class E>
53class Array2D {
54public:
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
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
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
189private:
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
203 void initialize(const E& x);
204
206
207 void copy(const Array2D<E>& array2);
208};
209
211template<class E>
212void 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
237template<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
254template<class E>
255void 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
271template<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
282template<class E>
283void 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
296template<class E>
297float 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}
Basic declarations, included by all source files.
The parameterized class Array2D implements dynamic two-dimensional arrays.
Definition Array2D.h:53
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
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
E * m_vpStart
The virtual start of the array (address of A[0,0]).
Definition Array2D.h:190
int size2() const
Returns the length of the index interval (number of entries) in dimension 2.
Definition Array2D.h:113
int high2() const
Returns the maximal array index in dimension 2.
Definition Array2D.h:104
Array2D(Array2D< E > &&A)
Creates a two-dimensional array containing the elements of A (move semantics).
Definition Array2D.h:79
int m_d
The highest index in dimension 2.
Definition Array2D.h:198
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
E * m_pStop
Successor of last element (address of A[high1,high2+1]).
Definition Array2D.h:193
void initialize()
Initializes the array with default constructor of E.
Definition Array2D.h:238
int m_lenDim2
The number of elements in dimension 2.
Definition Array2D.h:191
void deconstruct()
Call destructor of all elements.
Definition Array2D.h:272
int m_c
The lowest index in dimension 2.
Definition Array2D.h:197
E * m_pStart
The real start of the array (address of A[low1,low2]).
Definition Array2D.h:192
int high1() const
Returns the maximal array index in dimension 1.
Definition Array2D.h:98
const E & operator()(int i, int j) const
Returns a reference to the element with index (i,j).
Definition Array2D.h:120
void copy(const Array2D< E > &array2)
Copy array2.
Definition Array2D.h:283
float det() const
Returns the determinant of the matrix.
Definition Array2D.h:297
Array2D< E > & operator=(const Array2D< E > &array2)
Assignment operator.
Definition Array2D.h:155
int size1() const
Returns the length of the index interval (number of entries) in dimension 1.
Definition Array2D.h:110
void initialize(const E &x)
Initializes the array with x.
Definition Array2D.h:255
int low1() const
Returns the minimal array index in dimension 1.
Definition Array2D.h:95
E & operator()(int i, int j)
Returns a reference to the element with index (i,j).
Definition Array2D.h:129
Array2D< E > & operator=(Array2D< E > &&A)
Assignment operator (move semantics).
Definition Array2D.h:165
Array2D(const Array2D< E > &A)
Creates a two-dimensional array that is a copy of A.
Definition Array2D.h:73
void init()
Reinitializes the array to an array with empty index set.
Definition Array2D.h:138
~Array2D()
Destructor.
Definition Array2D.h:92
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
int size() const
Returns the size (number of elements) of the array.
Definition Array2D.h:107
Array2D()
Creates a two-dimensional array with empty index set.
Definition Array2D.h:58
void construct(int a, int b, int c, int d)
Constructs the array with index set [a, ..., b]*[c, ..., d].
Definition Array2D.h:212
int m_b
The highest index in dimension 1.
Definition Array2D.h:196
int low2() const
Returns the minimal array index in dimension 2.
Definition Array2D.h:101
int m_a
The lowest index in dimension 1.
Definition Array2D.h:195
void fill(const E &x)
Sets all elements to x.
Definition Array2D.h:182
Exception thrown when not enough memory is available to execute an algorithm.
Definition exceptions.h:209
Definition of exception classes.
#define OGDF_THROW(CLASS)
Replacement for throw.
Definition exceptions.h:67
#define OGDF_ASSERT(expr)
Assert condition expr. See doc/build.md for more information.
Definition basic.h:52
The namespace for all OGDF objects.