Zivid C++ API 2.11.1+de9b5dae-1
Matrix.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of the Zivid API
3 *
4 * Copyright 2015-2024 (C) Zivid AS
5 * All rights reserved.
6 *
7 * Zivid Software License, v1.0
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are met:
11 *
12 * 1. Redistributions of source code must retain the above copyright notice,
13 * this list of conditions and the following disclaimer.
14 *
15 * 2. Redistributions in binary form must reproduce the above copyright notice,
16 * this list of conditions and the following disclaimer in the documentation
17 * and/or other materials provided with the distribution.
18 *
19 * 3. Neither the name of Zivid AS nor the names of its contributors may be used
20 * to endorse or promote products derived from this software without specific
21 * prior written permission.
22 *
23 * 4. This software, with or without modification, must not be used with any
24 * other 3D camera than from Zivid AS.
25 *
26 * 5. Any software provided in binary form under this license must not be
27 * reverse engineered, decompiled, modified and/or disassembled.
28 *
29 * THIS SOFTWARE IS PROVIDED BY ZIVID AS "AS IS" AND ANY EXPRESS OR IMPLIED
30 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
31 * MERCHANTABILITY, NONINFRINGEMENT, AND FITNESS FOR A PARTICULAR PURPOSE ARE
32 * DISCLAIMED. IN NO EVENT SHALL ZIVID AS OR CONTRIBUTORS BE LIABLE FOR ANY
33 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
34 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
35 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
36 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
37 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
38 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
39 *
40 * Contact: Zivid Customer Success Team <customersuccess@zivid.com>
41 * Info: http://www.zivid.com
42 ******************************************************************************/
43
44#pragma once
45
47
48#include <array>
49#include <exception>
50#include <functional>
51#include <iterator>
52#include <ostream>
53#include <sstream>
54#include <string>
55
56namespace Zivid
57{
61 template<typename T, size_t rowCount, size_t colCount>
62 class Matrix
63 {
64 static_assert(rowCount > 0 && colCount > 0, "rowCount and colCount must be > 0");
65
66 private:
67 using Storage = std::array<T, rowCount * colCount>;
68
69 static constexpr bool invertSupported = ((rowCount == 4 && colCount == 4) || (rowCount == 3 && colCount == 3))
70 && (std::is_same<T, float>::value || std::is_same<T, double>::value);
71
72 public:
76 using ValueType = T;
77
81 using Iterator = typename Storage::iterator;
82
86 using ConstIterator = typename Storage::const_iterator;
87
91 static constexpr size_t rows{ rowCount };
92
96 static constexpr size_t cols{ colCount };
97
99 Matrix() = default;
100
102 Matrix(const std::string &fileName)
103 {
104 load(fileName);
105 }
106
108 explicit Matrix(const std::array<T, colCount * rowCount> &arrArr)
109 : m_mat{ arrArr }
110 {}
111
113 template<typename Iterator>
114 Matrix(Iterator beginIt, Iterator endIt)
115 {
116 if(std::distance(beginIt, endIt) != rows * cols)
117 {
118 /* NOLINT */ throw std::out_of_range(
119 "Matrix constructor got input that does not match matrix size. Expected "
120 + std::to_string(rows * cols) + " items, got " + std::to_string(std::distance(beginIt, endIt))
121 + " items.");
122 }
123
124 std::copy(beginIt, endIt, m_mat.begin());
125 }
126
128 explicit Matrix(std::initializer_list<T> values)
129 : Matrix{ values.begin(), values.end() }
130 {}
131
133 explicit Matrix(std::initializer_list<std::initializer_list<T>> values)
134 {
135 if(values.size() != rows)
136 {
137 throw std::out_of_range(
138 "Matrix constructor got input that does not match matrix size. Expected " + std::to_string(rows)
139 + " rows, got " + std::to_string(values.size()) + " rows");
140 }
141
142 auto iterator = begin();
143 for(const auto &row : values)
144 {
145 if(row.size() != cols)
146 {
147 throw std::out_of_range(
148 "Matrix constructor got input that does not match matrix size. Expected all rows to be of size "
149 + std::to_string(cols) + ", got row with " + std::to_string(row.size()) + " values");
150 }
151 std::copy(std::begin(row), std::end(row), iterator);
152 std::advance(iterator, cols);
153 }
154 }
155
158 {
159 return m_mat.begin();
160 }
161
164 {
165 return m_mat.end();
166 }
167
170 {
171 return m_mat.begin();
172 }
173
176 {
177 return m_mat.end();
178 }
179
182 {
183 return m_mat.cbegin();
184 }
185
188 {
189 return m_mat.cend();
190 }
191
193 T &at(size_t row, size_t col)
194 {
195 throwIfOutOfBounds(row, col);
196 return m_mat[row * cols + col];
197 }
198
200 const T &at(size_t row, size_t col) const
201 {
202 throwIfOutOfBounds(row, col);
203 return m_mat[row * cols + col];
204 }
205
207 T &operator()(size_t row, size_t col)
208 {
209 return m_mat[row * cols + col];
210 }
211
213 const T &operator()(size_t row, size_t col) const
214 {
215 return m_mat[row * cols + col];
216 }
217
219 T *data()
220 {
221 return m_mat.data();
222 }
223
225 const T *data() const
226 {
227 return m_mat.data();
228 }
229
234 void save(const std::string &fileName) const;
235
241 void load(const std::string &fileName);
242
248 template<typename Q = T, typename = typename std::enable_if<invertSupported, Q>::type>
250
253 std::string toString() const
254 {
255 std::stringstream ss;
256 ss << "[ ";
257 for(size_t row = 0; row < rowCount; row++)
258 {
259 ss << (row == 0 ? "[" : "\n [");
260 for(size_t col = 0; col < colCount; col++)
261 {
262 const auto value{ m_mat[row * colCount + col] };
263 ss << (value >= 0 ? " " : "") << std::to_string(value);
264 ss << (col == colCount - 1 ? "" : ", ");
265 }
266 ss << (row == rowCount - 1 ? "]" : "], ");
267 }
268 ss << " ]";
269 return ss.str();
270 }
271
272 private:
273 static void throwIfOutOfBounds(size_t row, size_t col)
274 {
275 if(row >= rows)
276 {
277 throw std::out_of_range{ "Trying to access row with index " + std::to_string(row)
278 + ", but allowed range is [0, " + std::to_string(rows - 1) + "]" };
279 }
280 if(col >= cols)
281 {
282 throw std::out_of_range{ "Trying to access column with index " + std::to_string(col)
283 + ", but allowed range is [0, " + std::to_string(cols - 1) + "]" };
284 }
285 }
286
287 Storage m_mat{};
288 };
289
291 template<typename T, size_t rowCount, size_t colCount>
292 std::ostream &operator<<(std::ostream &stream, const Matrix<T, rowCount, colCount> &matrix)
293 {
294 return stream << matrix.toString();
295 }
296
301
306
311
316
317#ifndef NO_DOC
319 namespace Detail
320 {
322 saveFloatMatrix(const float *data, size_t rowCount, size_t colCount, const std::string &fileName);
323
325 loadFloatMatrix(float *data, size_t rowCount, size_t colCount, const std::string &fileName);
326 } // namespace Detail
327#endif
328
329#ifndef NO_DOC
330 extern template ZIVID_CORE_EXPORT Matrix<float, 4, 4> Matrix<float, 4, 4>::inverse<float, float>() const;
331
332 extern template ZIVID_CORE_EXPORT Matrix<double, 4, 4> Matrix<double, 4, 4>::inverse<double, double>() const;
333
334 extern template ZIVID_CORE_EXPORT Matrix<float, 3, 3> Matrix<float, 3, 3>::inverse<float, float>() const;
335
336 extern template ZIVID_CORE_EXPORT Matrix<double, 3, 3> Matrix<double, 3, 3>::inverse<double, double>() const;
337
338 template<typename T, size_t rowCount, size_t colCount>
339 void Matrix<T, rowCount, colCount>::save(const std::string &fileName) const
340 {
341 static_assert(std::is_same<T, float>::value, "Saving matrices of this type is not supported");
342
343 Detail::saveFloatMatrix(data(), rowCount, colCount, fileName);
344 }
345
346 template<typename T, size_t rowCount, size_t colCount>
347 void Matrix<T, rowCount, colCount>::load(const std::string &fileName)
348 {
349 static_assert(std::is_same<T, float>::value, "Loading matrices of this type is not supported");
350
351 Detail::loadFloatMatrix(data(), rowCount, colCount, fileName);
352 }
353
354#endif
355
356} // namespace Zivid
#define ZIVID_CORE_EXPORT
Definition CoreExport.h:56
A fixed size matrix in row major order.
Definition Matrix.h:63
static constexpr size_t rows
The number of rows in the matrix.
Definition Matrix.h:91
T ValueType
The type stored in the matrix.
Definition Matrix.h:76
T * data()
Pointer to the underlying data.
Definition Matrix.h:219
void load(const std::string &fileName)
Load the matrix from the given file.
ConstIterator begin() const
Iterator to the beginning of the matrix.
Definition Matrix.h:169
void save(const std::string &fileName) const
Save the matrix to the given file.
typename Storage::iterator Iterator
The matrix iterator type for mutable access. It iterates over individual matrix elements in row major...
Definition Matrix.h:81
Matrix(Iterator beginIt, Iterator endIt)
Constructor.
Definition Matrix.h:114
Matrix(std::initializer_list< T > values)
Constructor.
Definition Matrix.h:128
Matrix(const std::array< T, colCount *rowCount > &arrArr)
Constructor.
Definition Matrix.h:108
Matrix(const std::string &fileName)
Load the matrix from a file.
Definition Matrix.h:102
const T * data() const
Pointer to the underlying data.
Definition Matrix.h:225
static constexpr size_t cols
The number of columns in the matrix.
Definition Matrix.h:96
Iterator begin()
Iterator to the beginning of the matrix.
Definition Matrix.h:157
Matrix()=default
Constructor.
ConstIterator cbegin() const
Iterator to the beginning of the matrix.
Definition Matrix.h:181
T & at(size_t row, size_t col)
Access specified element with bounds checking.
Definition Matrix.h:193
std::string toString() const
Get string representation of the Matrix.
Definition Matrix.h:253
ConstIterator end() const
Iterator to the end of the matrix.
Definition Matrix.h:175
Matrix(std::initializer_list< std::initializer_list< T > > values)
Constructor.
Definition Matrix.h:133
const T & at(size_t row, size_t col) const
Access specified element with bounds checking.
Definition Matrix.h:200
const T & operator()(size_t row, size_t col) const
Access specified element without bounds checking.
Definition Matrix.h:213
Iterator end()
Iterator to the end of the matrix.
Definition Matrix.h:163
ZIVID_CORE_EXPORT Matrix inverse() const
Get the inverse of this matrix.
ConstIterator cend() const
Iterator to the end of the matrix.
Definition Matrix.h:187
T & operator()(size_t row, size_t col)
Access specified element without bounds checking.
Definition Matrix.h:207
typename Storage::const_iterator ConstIterator
The matrix iterator type for immutable access. It iterates over individual matrix elements in row maj...
Definition Matrix.h:86
The main Zivid namespace. All Zivid code is found here.
Definition Application.h:54
std::ostream & operator<<(std::ostream &stream, const Array2D< T > &array)
Serialize array information to a stream.
Definition Array2D.h:285