Zivid C++ API 2.13.1+18e79e79-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 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 {
165 return m_mat.begin();
166 }
167
170 {
171 return m_mat.end();
172 }
173
176 {
177 return m_mat.begin();
178 }
179
182 {
183 return m_mat.end();
184 }
185
188 {
189 return m_mat.cbegin();
190 }
191
194 {
195 return m_mat.cend();
196 }
197
199 T &at(size_t row, size_t col)
200 {
201 throwIfOutOfBounds(row, col);
202 return m_mat[row * cols + col];
203 }
204
206 const T &at(size_t row, size_t col) const
207 {
208 throwIfOutOfBounds(row, col);
209 return m_mat[row * cols + col];
210 }
211
213 T &operator()(size_t row, size_t col)
214 {
215 return m_mat[row * cols + col];
216 }
217
219 const T &operator()(size_t row, size_t col) const
220 {
221 return m_mat[row * cols + col];
222 }
223
225 T *data()
226 {
227 return m_mat.data();
228 }
229
231 const T *data() const
232 {
233 return m_mat.data();
234 }
235
240 void save(const std::string &fileName) const;
241
247 void load(const std::string &fileName);
248
254 template<typename Q = T, typename = typename std::enable_if<invertSupported, Q>::type>
256
259 std::string toString() const
260 {
261 std::stringstream ss;
262 ss << "[ ";
263 for(size_t row = 0; row < rowCount; row++)
264 {
265 ss << (row == 0 ? "[" : "\n [");
266 for(size_t col = 0; col < colCount; col++)
267 {
268 const auto value{ m_mat[row * colCount + col] };
269 ss << (value >= 0 ? " " : "") << std::to_string(value);
270 ss << (col == colCount - 1 ? "" : ", ");
271 }
272 ss << (row == rowCount - 1 ? "]" : "], ");
273 }
274 ss << " ]";
275 return ss.str();
276 }
277
278 private:
279 static void throwIfOutOfBounds(size_t row, size_t col)
280 {
281 if(row >= rows)
282 {
283 throw std::out_of_range{ "Trying to access row with index " + std::to_string(row)
284 + ", but allowed range is [0, " + std::to_string(rows - 1) + "]" };
285 }
286 if(col >= cols)
287 {
288 throw std::out_of_range{ "Trying to access column with index " + std::to_string(col)
289 + ", but allowed range is [0, " + std::to_string(cols - 1) + "]" };
290 }
291 }
292
293 Storage m_mat{};
294 };
295
297 template<typename T, size_t rowCount, size_t colCount>
298 std::ostream &operator<<(std::ostream &stream, const Matrix<T, rowCount, colCount> &matrix)
299 {
300 return stream << matrix.toString();
301 }
302
307
312
317
322
323#ifndef NO_DOC
325 namespace Detail
326 {
328 saveFloatMatrix(const float *data, size_t rowCount, size_t colCount, const std::string &fileName);
329
331 loadFloatMatrix(float *data, size_t rowCount, size_t colCount, const std::string &fileName);
332 } // namespace Detail
333#endif
334
335#ifndef NO_DOC
336 extern template ZIVID_CORE_EXPORT Matrix<float, 4, 4> Matrix<float, 4, 4>::inverse<float, float>() const;
337
338 extern template ZIVID_CORE_EXPORT Matrix<double, 4, 4> Matrix<double, 4, 4>::inverse<double, double>() const;
339
340 extern template ZIVID_CORE_EXPORT Matrix<float, 3, 3> Matrix<float, 3, 3>::inverse<float, float>() const;
341
342 extern template ZIVID_CORE_EXPORT Matrix<double, 3, 3> Matrix<double, 3, 3>::inverse<double, double>() const;
343
344 template<typename T, size_t rowCount, size_t colCount>
345 void Matrix<T, rowCount, colCount>::save(const std::string &fileName) const
346 {
347 static_assert(std::is_same<T, float>::value, "Saving matrices of this type is not supported");
348
349 Detail::saveFloatMatrix(data(), rowCount, colCount, fileName);
350 }
351
352 template<typename T, size_t rowCount, size_t colCount>
353 void Matrix<T, rowCount, colCount>::load(const std::string &fileName)
354 {
355 static_assert(std::is_same<T, float>::value, "Loading matrices of this type is not supported");
356
357 Detail::loadFloatMatrix(data(), rowCount, colCount, fileName);
358 }
359
360#endif
361
362} // 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:225
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:175
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: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:231
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:163
Matrix()=default
Constructor.
ConstIterator cbegin() const
Iterator to the beginning of the matrix.
Definition Matrix.h:187
T & at(size_t row, size_t col)
Access specified element with bounds checking.
Definition Matrix.h:199
std::string toString() const
Get string representation of the Matrix.
Definition Matrix.h:259
ConstIterator end() const
Iterator to the end of the matrix.
Definition Matrix.h:181
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:206
const T & operator()(size_t row, size_t col) const
Access specified element without bounds checking.
Definition Matrix.h:219
Iterator end()
Iterator to the end of the matrix.
Definition Matrix.h:169
Matrix(const Matrix< U, rowCount, colCount > &sourceMatrix)
Constructor.
Definition Matrix.h:114
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:193
T & operator()(size_t row, size_t col)
Access specified element without bounds checking.
Definition Matrix.h:213
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:56
std::ostream & operator<<(std::ostream &stream, const Array2D< T > &array)
Serialize array information to a stream.
Definition Array2D.h:285