Documentation for OpenFLUID 2.2.2
Loading...
Searching...
No Matches
Matrix.hpp
Go to the documentation of this file.
1/*
2
3 This file is part of OpenFLUID software
4 Copyright(c) 2021-2026, INRAE
5
6
7 == GNU General Public License Usage ==
8
9 OpenFLUID is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 OpenFLUID is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with OpenFLUID. If not, see <http://www.gnu.org/licenses/>.
21
22
23 == Other Usage ==
24
25 Other Usage means a use of OpenFLUID that is inconsistent with the GPL
26 license, and requires a written agreement between You and INRA.
27 Licensees for Other Usage of OpenFLUID may use this file in accordance
28 with the terms contained in the written agreement between You and INRA.
29
30*/
31
32
33/**
34 @file Matrix.hpp
35
36 @author Jean-Christophe FABRE <jean-christophe.fabre@inra.fr>
37 */
38
39
40#ifndef __OPENFLUID_CORE_MATRIX_HPP__
41#define __OPENFLUID_CORE_MATRIX_HPP__
42
43
44#include <memory>
45
48
49
50namespace openfluid { namespace core {
51
52
53/**
54 Template class for matrix data
55*/
56template <class T>
58{
59 protected :
60
61 std::unique_ptr<T[]> m_Data;
62
63 unsigned long m_ColsNbr;
64
65 unsigned long m_RowsNbr;
66
67 bool allocate(unsigned long ColsNbr, unsigned long RowsNbr);
68
69 void init();
70
71
72 public :
73
74 /**
75 Default constructor, creates an empty Matrix
76 */
78
79 /**
80 Copy constructor
81 */
82 Matrix(const Matrix& Other);
83
84 /**
85 Constructor, creates a Matrix containing Size elements
86 */
87 Matrix(unsigned long ColsNbr,unsigned long RowsNbr);
88
89 /**
90 Constructor, creates a Matrix containing Size elements, initialized with value InitValue
91 */
92 Matrix(unsigned long ColsNbr,unsigned long RowsNbr,const T& InitValue);
93
94 /**
95 Assignment operator
96 */
97 Matrix<T>& operator=(const Matrix& Other);
98
99 /**
100 Move assignment operator
101 */
103
104 /**
105 Destructor
106 */
107 virtual ~Matrix() = default;
108
109 /**
110 Returns the number of columns of the Matrix
111 @return number of columns
112 */
113 inline unsigned long getColsNbr() const
114 {
115 return m_ColsNbr;
116 }
117
118 /**
119 Returns the number of rows of the Matrix
120 @return number of rows
121 */
122 inline unsigned long getRowsNbr() const
123 {
124 return m_RowsNbr;
125 }
126
127 /**
128 Returns the full size of the Matrix (number of columns x number of rows)
129 @return size of the Matrix
130 */
131 inline unsigned long getSize() const
132 {
133 return (m_ColsNbr * m_RowsNbr);
134 }
135
136 /**
137 Returns the full size of the Matrix
138 */
139 inline unsigned long size() const
140 {
141 return (m_ColsNbr * m_RowsNbr);
142 }
143
144
145 /**
146 Returns a pointer to the content of the Matrix (like C arrays)
147 */
148 T* data() const
149 {
150 return static_cast<T*>(m_Data.get());
151 }
152
153 /**
154 Sets data from a pointer to a content (like C arrays)
155 */
156 void setData(T* Data, unsigned long ColsNbr, unsigned long RowsNbr);
157
158 /**
159 Returns the element of the Matrix for index Index
160 */
161 T getElement(unsigned long ColIndex, unsigned long RowIndex) const;
162
163 /**
164 Returns the element of the Matrix for index Index
165 */
166 inline T at(unsigned long ColIndex, unsigned long RowIndex) const
167 {
168 return getElement(ColIndex,RowIndex);
169 }
170
171 /**
172 Returns the element of the Matrix for index Index
173 */
174 inline T get(unsigned long ColIndex, unsigned long RowIndex) const
175 { return getElement(ColIndex,RowIndex); };
176
177
178 /**
179 Sets a new value for element at the given index
180 */
181 void setElement(unsigned long ColIndex, unsigned long RowIndex, const T& Val);
182
183 /**
184 Sets a new value for element at the given index
185 */
186 inline void set(unsigned long ColIndex, unsigned long RowIndex, const T& Val)
187 {
188 setElement(ColIndex,RowIndex,Val);
189 }
190
191 /**
192 Fills the Matrix with given value
193 */
194 void fill(const T& Val);
195
196 /**
197 Clears the Matrix (empty and size is 0)
198 */
199 void clear();
200
201};
202
203
204// =====================================================================
205// =====================================================================
206
207
208template <class T>
210 m_ColsNbr(0),m_RowsNbr(0)
211{
212 init();
213}
214
215
216// =====================================================================
217// =====================================================================
218
219
220template <class T>
222{
223 init();
224
225 if (!allocate(Other.m_ColsNbr,Other.m_RowsNbr))
226 {
227 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
228 }
229
230 std::copy(Other.m_Data.get(), Other.m_Data.get() + (Other.m_ColsNbr*Other.m_RowsNbr), m_Data.get());
231}
232
233
234// =====================================================================
235// =====================================================================
236
237
238template <class T>
239Matrix<T>::Matrix(unsigned long ColsNbr, unsigned long RowsNbr)
240{
241 init();
242
243 if (!allocate(ColsNbr,RowsNbr))
244 {
245 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
246 }
247}
248
249
250// =====================================================================
251// =====================================================================
252
253
254template <class T>
255Matrix<T>::Matrix(unsigned long ColsNbr, unsigned long RowsNbr, const T& InitValue)
256{
257 init();
258
259 if (!allocate(ColsNbr,RowsNbr))
260 {
261 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
262 }
263
264 fill(InitValue);
265}
266
267
268// =====================================================================
269// =====================================================================
270
271
272template <class T>
274{
275
276 if (this != &Other)
277 {
278 clear();
279
280 if (!allocate(Other.m_ColsNbr,Other.m_RowsNbr))
281 {
282 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
283 }
284
285 std::copy(Other.m_Data.get(), Other.m_Data.get() + (Other.m_ColsNbr*Other.m_RowsNbr), m_Data.get());
286 }
287
288 return *this;
289}
290
291
292// =====================================================================
293// =====================================================================
294
295
296template <class T>
298{
299
300 if (this != &Other)
301 {
302 clear();
303
304 m_ColsNbr = Other.m_ColsNbr;
305 m_RowsNbr = Other.m_RowsNbr;
306 m_Data = std::move(Other.m_Data);
307
308 Other.m_ColsNbr = 0;
309 Other.m_RowsNbr = 0;
310 }
311
312 return *this;
313}
314
315
316// =====================================================================
317// =====================================================================
318
319
320template <class T>
322{
323 m_Data.reset();
324 m_ColsNbr = 0;
325 m_RowsNbr = 0;
326}
327
328
329// =====================================================================
330// =====================================================================
331
332
333template <class T>
334bool Matrix<T>::allocate(unsigned long ColsNbr, unsigned long RowsNbr)
335{
336 if (ColsNbr > 0 && RowsNbr > 0)
337 {
338 m_Data.reset();
339 m_Data = std::move(std::make_unique<T[]>(ColsNbr*RowsNbr));
340 if (m_Data)
341 {
342 m_RowsNbr = RowsNbr;
343 m_ColsNbr = ColsNbr;
344 }
345 else
346 {
347 return false;
348 }
349 }
350
351 return true;
352}
353
354
355// =====================================================================
356// =====================================================================
357
358
359template <class T>
360void Matrix<T>::setData(T* Data, unsigned long ColsNbr, unsigned long RowsNbr)
361{
362 clear();
363
364 if (!allocate(ColsNbr,RowsNbr))
365 {
366 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"Cannot allocate memory");
367 }
368
369 std::copy(Data, Data + (ColsNbr*RowsNbr), m_Data.get());
370}
371
372
373// =====================================================================
374// =====================================================================
375
376
377template <class T>
378T Matrix<T>::getElement(unsigned long ColIndex, unsigned long RowIndex) const
379{
380 if (ColIndex >= m_ColsNbr || RowIndex >= m_RowsNbr)
381 {
382 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"element access range error");
383 }
384
385 return m_Data[ColIndex*m_RowsNbr+RowIndex];
386}
387
388
389// =====================================================================
390// =====================================================================
391
392
393template <class T>
394void Matrix<T>::setElement(unsigned long ColIndex, unsigned long RowIndex, const T& Val)
395{
396 if (ColIndex >= m_ColsNbr || RowIndex >= m_RowsNbr)
397 {
398 throw openfluid::base::FrameworkException(OPENFLUID_CODE_LOCATION,"element access range error");
399 }
400
401 m_Data[ColIndex*m_RowsNbr+RowIndex] = Val;
402}
403
404
405// =====================================================================
406// =====================================================================
407
408
409template <class T>
410void Matrix<T>::fill(const T& Val)
411{
412 std::fill(m_Data.get(), m_Data.get() + (m_ColsNbr*m_RowsNbr),Val);
413}
414
415
416// =====================================================================
417// =====================================================================
418
419
420template <class T>
422{
423 init();
424}
425
426
427} }
428
429#endif /* __OPENFLUID_CORE_MATRIX_HPP__ */
Definition FrameworkException.hpp:51
Definition Matrix.hpp:58
void fill(const T &Val)
Definition Matrix.hpp:410
unsigned long m_ColsNbr
Definition Matrix.hpp:63
bool allocate(unsigned long ColsNbr, unsigned long RowsNbr)
Definition Matrix.hpp:334
void setData(T *Data, unsigned long ColsNbr, unsigned long RowsNbr)
Definition Matrix.hpp:360
unsigned long getColsNbr() const
Definition Matrix.hpp:113
std::unique_ptr< T[]> m_Data
Definition Matrix.hpp:61
unsigned long m_RowsNbr
Definition Matrix.hpp:65
Matrix(unsigned long ColsNbr, unsigned long RowsNbr, const T &InitValue)
Definition Matrix.hpp:255
T * data() const
Definition Matrix.hpp:148
void set(unsigned long ColIndex, unsigned long RowIndex, const T &Val)
Definition Matrix.hpp:186
T getElement(unsigned long ColIndex, unsigned long RowIndex) const
Definition Matrix.hpp:378
Matrix< T > & operator=(Matrix &&Other)
Definition Matrix.hpp:297
void clear()
Definition Matrix.hpp:421
unsigned long size() const
Definition Matrix.hpp:139
T at(unsigned long ColIndex, unsigned long RowIndex) const
Definition Matrix.hpp:166
void init()
Definition Matrix.hpp:321
Matrix()
Definition Matrix.hpp:209
unsigned long getSize() const
Definition Matrix.hpp:131
virtual ~Matrix()=default
void setElement(unsigned long ColIndex, unsigned long RowIndex, const T &Val)
Definition Matrix.hpp:394
Matrix(const Matrix &Other)
Definition Matrix.hpp:221
Matrix(unsigned long ColsNbr, unsigned long RowsNbr)
Definition Matrix.hpp:239
Matrix< T > & operator=(const Matrix &Other)
Definition Matrix.hpp:273
unsigned long getRowsNbr() const
Definition Matrix.hpp:122
T get(unsigned long ColIndex, unsigned long RowIndex) const
Definition Matrix.hpp:174
#define OPENFLUID_API
Definition dllexport.hpp:86
Definition ApplicationException.hpp:47