Quetzal-CoaTL
The Coalescence Template Library
Loading...
Searching...
No Matches
matrix.hpp
1/*
2 * Copyright (c) 2007 John Weaver
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 */
18
19/*
20Modified by Arnaud Becheler, 2016
21Removing cpp inclusion
22*/
23
24#ifndef _MATRIX_H_
25#define _MATRIX_H_
26
27#include <algorithm>
28#include <cassert>
29#include <cstdlib>
30#include <initializer_list>
31#include <ostream>
32
34{
35namespace fuzzy_transfer_distance
36{
37template <class T> class Matrix
38{
39 public:
40 Matrix();
41 Matrix(const size_t rows, const size_t columns);
42 Matrix(const std::initializer_list<std::initializer_list<T>> init);
43 Matrix(const Matrix<T> &other);
44 Matrix<T> &operator=(const Matrix<T> &other);
45 ~Matrix();
46
47 // all operations modify the matrix in-place.
48 void resize(const size_t rows, const size_t columns, const T default_value = 0);
49 void clear();
50
51 T &operator()(const size_t x, const size_t y);
52 const T &operator()(const size_t x, const size_t y) const;
53
54 const T min() const;
55 const T max() const;
56
57 inline size_t minsize()
58 {
59 return ((m_rows < m_columns) ? m_rows : m_columns);
60 }
61
62 inline size_t columns() const
63 {
64 return m_columns;
65 }
66 inline size_t rows() const
67 {
68 return m_rows;
69 }
70
71 friend std::ostream &operator<<(std::ostream &os, const Matrix &matrix)
72 {
73 os << "Matrix:" << std::endl;
74 for (size_t row = 0; row < matrix.rows(); row++)
75 {
76 for (size_t col = 0; col < matrix.columns(); col++)
77 {
78 os.width(8);
79 os << matrix(row, col) << ",";
80 }
81 os << std::endl;
82 }
83 return os;
84 }
85
86 private:
87 T **m_matrix;
88 size_t m_rows;
89 size_t m_columns;
90};
91
92template <class T> Matrix<T>::Matrix()
93{
94 m_rows = 0;
95 m_columns = 0;
96 m_matrix = nullptr;
97}
98
99template <class T> Matrix<T>::Matrix(const std::initializer_list<std::initializer_list<T>> init)
100{
101 m_matrix = nullptr;
102 m_rows = init.size();
103 if (m_rows == 0)
104 {
105 m_columns = 0;
106 }
107 else
108 {
109 m_columns = init.begin()->size();
110 if (m_columns > 0)
111 {
112 resize(m_rows, m_columns);
113 }
114 }
115
116 size_t i = 0, j;
117 for (auto row = init.begin(); row != init.end(); ++row, ++i)
118 {
119 assert(row->size() == m_columns && "All rows must have the same number of columns.");
120 j = 0;
121 for (auto value = row->begin(); value != row->end(); ++value, ++j)
122 {
123 m_matrix[i][j] = *value;
124 }
125 }
126}
127
128template <class T> Matrix<T>::Matrix(const Matrix<T> &other)
129{
130 if (other.m_matrix != nullptr)
131 {
132 // copy arrays
133 m_matrix = nullptr;
134 resize(other.m_rows, other.m_columns);
135 for (size_t i = 0; i < m_rows; i++)
136 {
137 for (size_t j = 0; j < m_columns; j++)
138 {
139 m_matrix[i][j] = other.m_matrix[i][j];
140 }
141 }
142 }
143 else
144 {
145 m_matrix = nullptr;
146 m_rows = 0;
147 m_columns = 0;
148 }
149}
150
151template <class T> Matrix<T>::Matrix(const size_t rows, const size_t columns)
152{
153 m_matrix = nullptr;
154 resize(rows, columns);
155}
156
157template <class T> Matrix<T> &Matrix<T>::operator=(const Matrix<T> &other)
158{
159 if (other.m_matrix != nullptr)
160 {
161 // copy arrays
162 resize(other.m_rows, other.m_columns);
163 for (size_t i = 0; i < m_rows; i++)
164 {
165 for (size_t j = 0; j < m_columns; j++)
166 {
167 m_matrix[i][j] = other.m_matrix[i][j];
168 }
169 }
170 }
171 else
172 {
173 // free arrays
174 for (size_t i = 0; i < m_columns; i++)
175 {
176 delete[] m_matrix[i];
177 }
178
179 delete[] m_matrix;
180
181 m_matrix = nullptr;
182 m_rows = 0;
183 m_columns = 0;
184 }
185
186 return *this;
187}
188
189template <class T> Matrix<T>::~Matrix()
190{
191 if (m_matrix != nullptr)
192 {
193 // free arrays
194 for (size_t i = 0; i < m_rows; i++)
195 {
196 delete[] m_matrix[i];
197 }
198
199 delete[] m_matrix;
200 }
201 m_matrix = nullptr;
202}
203
204template <class T> void Matrix<T>::resize(const size_t rows, const size_t columns, const T default_value)
205{
206 assert(rows > 0 && columns > 0 && "Columns and rows must exist.");
207
208 if (m_matrix == nullptr)
209 {
210 // alloc arrays
211 m_matrix = new T *[rows]; // rows
212 for (size_t i = 0; i < rows; i++)
213 {
214 m_matrix[i] = new T[columns]; // columns
215 }
216
217 m_rows = rows;
218 m_columns = columns;
219 clear();
220 }
221 else
222 {
223 // save array pointer
224 T **new_matrix;
225 // alloc new arrays
226 new_matrix = new T *[rows]; // rows
227 for (size_t i = 0; i < rows; i++)
228 {
229 new_matrix[i] = new T[columns]; // columns
230 for (size_t j = 0; j < columns; j++)
231 {
232 new_matrix[i][j] = default_value;
233 }
234 }
235
236 // copy data from saved pointer to new arrays
237 size_t minrows = std::min(rows, m_rows);
238 size_t mincols = std::min(columns, m_columns);
239 for (size_t x = 0; x < minrows; x++)
240 {
241 for (size_t y = 0; y < mincols; y++)
242 {
243 new_matrix[x][y] = m_matrix[x][y];
244 }
245 }
246
247 // delete old arrays
248 if (m_matrix != nullptr)
249 {
250 for (size_t i = 0; i < m_rows; i++)
251 {
252 delete[] m_matrix[i];
253 }
254
255 delete[] m_matrix;
256 }
257
258 m_matrix = new_matrix;
259 }
260
261 m_rows = rows;
262 m_columns = columns;
263}
264
265template <class T> void Matrix<T>::clear()
266{
267 assert(m_matrix != nullptr);
268
269 for (size_t i = 0; i < m_rows; i++)
270 {
271 for (size_t j = 0; j < m_columns; j++)
272 {
273 m_matrix[i][j] = 0;
274 }
275 }
276}
277
278template <class T> inline T &Matrix<T>::operator()(const size_t x, const size_t y)
279{
280 assert(x < m_rows);
281 assert(y < m_columns);
282 assert(m_matrix != nullptr);
283 return m_matrix[x][y];
284}
285
286template <class T> inline const T &Matrix<T>::operator()(const size_t x, const size_t y) const
287{
288 assert(x < m_rows);
289 assert(y < m_columns);
290 assert(m_matrix != nullptr);
291 return m_matrix[x][y];
292}
293
294template <class T> const T Matrix<T>::min() const
295{
296 assert(m_matrix != nullptr);
297 assert(m_rows > 0);
298 assert(m_columns > 0);
299 T min = m_matrix[0][0];
300
301 for (size_t i = 0; i < m_rows; i++)
302 {
303 for (size_t j = 0; j < m_columns; j++)
304 {
305 min = std::min<T>(min, m_matrix[i][j]);
306 }
307 }
308
309 return min;
310}
311
312template <class T> const T Matrix<T>::max() const
313{
314 assert(m_matrix != nullptr);
315 assert(m_rows > 0);
316 assert(m_columns > 0);
317 T max = m_matrix[0][0];
318
319 for (size_t i = 0; i < m_rows; i++)
320 {
321 for (size_t j = 0; j < m_columns; j++)
322 {
323 max = std::max<T>(max, m_matrix[i][j]);
324 }
325 }
326
327 return max;
328}
329} // end namespace fuzzy_transfer_distance
330} // namespace quetzal::polymorphism
331
332#endif
Generic components for polymorphism analysis.
Definition polymorphism.hpp:16