Zivid C++ API 2.15.0+5fcc365b-1
Matrix.h
Go to the documentation of this file.
1/*******************************************************************************
2 * This file is part of the Zivid API
3 *
4 * Copyright 2015-2025 (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 <iterator>
50#include <ostream>
51#include <sstream>
52#include <string>
53
54namespace Zivid
55{
59 template<typename T, size_t rowCount, size_t colCount>
60 class Matrix
61 {
62 static_assert(rowCount > 0 && colCount > 0, "rowCount and colCount must be > 0");
63
64 private:
65 using Storage = std::array<T, rowCount * colCount>;
66
67 static constexpr bool invertSupported = ((rowCount == 4 && colCount == 4) || (rowCount == 3 && colCount == 3))
68 && (std::is_same<T, float>::value || std::is_same<T, double>::value);
69
70 static constexpr bool identitySupported = (rowCount == colCount) && (std::is_arithmetic<T>::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 U>
114 explicit Matrix(const Matrix<U, rowCount, colCount> &sourceMatrix)
115 : Matrix(sourceMatrix.begin(), sourceMatrix.end())
116 {}
117
119 template<typename Iterator>
120 Matrix(Iterator beginIt, Iterator endIt)
121 {
122 if(std::distance(beginIt, endIt) != rows * cols)
123 {
124 /* NOLINT */ throw std::out_of_range(
125 "Matrix constructor got input that does not match matrix size. Expected "
126 + std::to_string(rows * cols) + " items, got " + std::to_string(std::distance(beginIt, endIt))
127 + " items.");
128 }
129
130 std::copy(beginIt, endIt, m_mat.begin());
131 }
132
134 explicit Matrix(std::initializer_list<T> values)
135 : Matrix{ values.begin(), values.end() }
136 {}
137
139 explicit Matrix(std::initializer_list<std::initializer_list<T>> values)
140 {
141 if(values.size() != rows)
142 {
143 throw std::out_of_range(
144 "Matrix constructor got input that does not match matrix size. Expected " + std::to_string(rows)
145 + " rows, got " + std::to_string(values.size()) + " rows");
146 }
147
148 auto iterator = begin();
149 for(const auto &row : values)
150 {
151 if(row.size() != cols)
152 {
153 throw std::out_of_range(
154 "Matrix constructor got input that does not match matrix size. Expected all rows to be of size "
155 + std::to_string(cols) + ", got row with " + std::to_string(row.size()) + " values");
156 }
157 std::copy(std::begin(row), std::end(row), iterator);
158 std::advance(iterator, cols);
159 }
160 }
161
164 template<typename Q = T, typename = typename std::enable_if_t<identitySupported, Q>>
166 {
167 auto matrix = Matrix();
168 for(size_t i = 0; i < Matrix::rows; ++i)
169 {
170 matrix(i, i) = T{ 1 };
171 }
172 return matrix;
173 }
174
177 {
178 return m_mat.begin();
179 }
180
183 {
184 return m_mat.end();
185 }
186
189 {
190 return m_mat.begin();
191 }
192
195 {
196 return m_mat.end();
197 }
198
201 {
202 return m_mat.cbegin();
203 }
204
207 {
208 return m_mat.cend();
209 }
210
212 T &at(size_t row, size_t col)
213 {
214 throwIfOutOfBounds(row, col);
215 return m_mat[(row * cols) + col];
216 }
217
219 const T &at(size_t row, size_t col) const
220 {
221 throwIfOutOfBounds(row, col);
222 return m_mat[(row * cols) + col];
223 }
224
226 T &operator()(size_t row, size_t col)
227 {
228 return m_mat[(row * cols) + col];
229 }
230
232 const T &operator()(size_t row, size_t col) const
233 {
234 return m_mat[(row * cols) + col];
235 }
236
238 T *data()
239 {
240 return m_mat.data();
241 }
242
244 const T *data() const
245 {
246 return m_mat.data();
247 }
248
253 void save(const std::string &fileName) const;
254
260 void load(const std::string &fileName);
261
267 template<typename Q = T, typename = typename std::enable_if_t<invertSupported, Q>>
269
272 std::string toString() const
273 {
274 std::stringstream ss;
275 ss << "[ ";
276 for(size_t row = 0; row < rowCount; row++)
277 {
278 ss << (row == 0 ? "[" : "\n [");
279 for(size_t col = 0; col < colCount; col++)
280 {
281 const auto value{ m_mat[(row * colCount) + col] };
282 ss << (value >= 0 ? " " : "") << std::to_string(value);
283 ss << (col == colCount - 1 ? "" : ", ");
284 }
285 ss << (row == rowCount - 1 ? "]" : "], ");
286 }
287 ss << " ]";
288 return ss.str();
289 }
290
291 private:
292 static void throwIfOutOfBounds(size_t row, size_t col)
293 {
294 if(row >= rows)
295 {
296 throw std::out_of_range{ "Trying to access row with index " + std::to_string(row)
297 + ", but allowed range is [0, " + std::to_string(rows - 1) + "]" };
298 }
299 if(col >= cols)
300 {
301 throw std::out_of_range{ "Trying to access column with index " + std::to_string(col)
302 + ", but allowed range is [0, " + std::to_string(cols - 1) + "]" };
303 }
304 }
305
306 Storage m_mat{};
307 };
308
310 template<typename T, size_t rowCount, size_t colCount>
311 std::ostream &operator<<(std::ostream &stream, const Matrix<T, rowCount, colCount> &matrix)
312 {
313 return stream << matrix.toString();
314 }
315
320
325
330
335
336#ifndef NO_DOC
338 namespace Detail
339 {
341 saveFloatMatrix(const float *data, size_t rowCount, size_t colCount, const std::string &fileName);
342
344 loadFloatMatrix(float *data, size_t rowCount, size_t colCount, const std::string &fileName);
345 } // namespace Detail
346#endif
347
348#ifndef NO_DOC
349 extern template ZIVID_UTILS_EXPORT Matrix<float, 4, 4> Matrix<float, 4, 4>::inverse<float, float>() const;
350
351 extern template ZIVID_UTILS_EXPORT Matrix<double, 4, 4> Matrix<double, 4, 4>::inverse<double, double>() const;
352
353 extern template ZIVID_UTILS_EXPORT Matrix<float, 3, 3> Matrix<float, 3, 3>::inverse<float, float>() const;
354
355 extern template ZIVID_UTILS_EXPORT Matrix<double, 3, 3> Matrix<double, 3, 3>::inverse<double, double>() const;
356
357 template<typename T, size_t rowCount, size_t colCount>
358 void Matrix<T, rowCount, colCount>::save(const std::string &fileName) const
359 {
360 static_assert(std::is_same<T, float>::value, "Saving matrices of this type is not supported");
361
362 Detail::saveFloatMatrix(data(), rowCount, colCount, fileName);
363 }
364
365 template<typename T, size_t rowCount, size_t colCount>
366 void Matrix<T, rowCount, colCount>::load(const std::string &fileName)
367 {
368 static_assert(std::is_same<T, float>::value, "Loading matrices of this type is not supported");
369
370 Detail::loadFloatMatrix(data(), rowCount, colCount, fileName);
371 }
372
373#endif
374
375} // namespace Zivid
#define ZIVID_UTILS_EXPORT
Definition UtilsExport.h:56
A fixed size matrix in row major order.
Definition Matrix.h:61
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:238
ZIVID_UTILS_EXPORT Matrix inverse() const
Get the inverse of this matrix.
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:188
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
static Matrix identity()
Get the identity matrix of given type and size.
Definition Matrix.h:165
Matrix(Iterator beginIt, Iterator endIt)
Constructor.
Definition Matrix.h:120
Matrix(std::initializer_list< T > values)
Constructor.
Definition Matrix.h:134
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:244
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:176
Matrix()=default
Constructor.
ConstIterator cbegin() const
Iterator to the beginning of the matrix.
Definition Matrix.h:200
T & at(size_t row, size_t col)
Access specified element with bounds checking.
Definition Matrix.h:212
std::string toString() const
Get string representation of the Matrix.
Definition Matrix.h:272
ConstIterator end() const
Iterator to the end of the matrix.
Definition Matrix.h:194
Matrix(std::initializer_list< std::initializer_list< T > > values)
Constructor.
Definition Matrix.h:139
const T & at(size_t row, size_t col) const
Access specified element with bounds checking.
Definition Matrix.h:219
const T & operator()(size_t row, size_t col) const
Access specified element without bounds checking.
Definition Matrix.h:232
Iterator end()
Iterator to the end of the matrix.
Definition Matrix.h:182
Matrix(const Matrix< U, rowCount, colCount > &sourceMatrix)
Constructor.
Definition Matrix.h:114
ConstIterator cend() const
Iterator to the end of the matrix.
Definition Matrix.h:206
T & operator()(size_t row, size_t col)
Access specified element without bounds checking.
Definition Matrix.h:226
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:84
std::ostream & operator<<(std::ostream &stream, const Array2D< T > &array)
Serialize array information to a stream.
Definition Array2D.h:283