libcamera v0.4.0
Supporting cameras in Linux since 2019
 
Loading...
Searching...
No Matches
matrix.h
Go to the documentation of this file.
1/* SPDX-License-Identifier: LGPL-2.1-or-later */
2/*
3 * Copyright (C) 2024, Paul Elder <paul.elder@ideasonboard.com>
4 *
5 * Matrix and related operations
6 */
7#pragma once
8
9#include <algorithm>
10#include <sstream>
11#include <vector>
12
13#include <libcamera/base/log.h>
14#include <libcamera/base/span.h>
15
17
18namespace libcamera {
19
21
22#ifndef __DOXYGEN__
23template<typename T, unsigned int Rows, unsigned int Cols,
24 std::enable_if_t<std::is_arithmetic_v<T>, bool> = true>
25#else
26template<typename T, unsigned int Rows, unsigned int Cols>
27#endif /* __DOXYGEN__ */
28class Matrix
29{
30public:
32 {
33 data_.fill(static_cast<T>(0));
34 }
35
36 Matrix(const std::array<T, Rows * Cols> &data)
37 {
38 std::copy(data.begin(), data.end(), data_.begin());
39 }
40
42 {
43 Matrix ret;
44 for (size_t i = 0; i < std::min(Rows, Cols); i++)
45 ret[i][i] = static_cast<T>(1);
46 return ret;
47 }
48
49 ~Matrix() = default;
50
51 const std::string toString() const
52 {
53 std::stringstream out;
54
55 out << "Matrix { ";
56 for (unsigned int i = 0; i < Rows; i++) {
57 out << "[ ";
58 for (unsigned int j = 0; j < Cols; j++) {
59 out << (*this)[i][j];
60 out << ((j + 1 < Cols) ? ", " : " ");
61 }
62 out << ((i + 1 < Rows) ? "], " : "]");
63 }
64 out << " }";
65
66 return out.str();
67 }
68
69 Span<const T, Cols> operator[](size_t i) const
70 {
71 return Span<const T, Cols>{ &data_.data()[i * Cols], Cols };
72 }
73
74 Span<T, Cols> operator[](size_t i)
75 {
76 return Span<T, Cols>{ &data_.data()[i * Cols], Cols };
77 }
78
79#ifndef __DOXYGEN__
80 template<typename U, std::enable_if_t<std::is_arithmetic_v<U>>>
81#else
82 template<typename U>
83#endif /* __DOXYGEN__ */
85 {
86 for (unsigned int i = 0; i < Rows * Cols; i++)
87 data_[i] *= d;
88 return *this;
89 }
90
91private:
92 std::array<T, Rows * Cols> data_;
93};
94
95#ifndef __DOXYGEN__
96template<typename T, typename U, unsigned int Rows, unsigned int Cols,
97 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
98#else
99template<typename T, typename U, unsigned int Rows, unsigned int Cols>
100#endif /* __DOXYGEN__ */
102{
104
105 for (unsigned int i = 0; i < Rows; i++) {
106 for (unsigned int j = 0; j < Cols; j++)
107 result[i][j] = d * m[i][j];
108 }
109
110 return result;
111}
112
113#ifndef __DOXYGEN__
114template<typename T, typename U, unsigned int Rows, unsigned int Cols,
115 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
116#else
117template<typename T, typename U, unsigned int Rows, unsigned int Cols>
118#endif /* __DOXYGEN__ */
120{
121 return d * m;
122}
123
124#ifndef __DOXYGEN__
125template<typename T,
126 unsigned int R1, unsigned int C1,
127 unsigned int R2, unsigned int C2,
128 std::enable_if_t<C1 == R2> * = nullptr>
129#else
130template<typename T, unsigned int R1, unsigned int C1, unsigned int R2, unsigned in C2>
131#endif /* __DOXYGEN__ */
133{
134 Matrix<T, R1, C2> result;
135
136 for (unsigned int i = 0; i < R1; i++) {
137 for (unsigned int j = 0; j < C2; j++) {
138 T sum = 0;
139
140 for (unsigned int k = 0; k < C1; k++)
141 sum += m1[i][k] * m2[k][j];
142
143 result[i][j] = sum;
144 }
145 }
146
147 return result;
148}
149
150template<typename T, unsigned int Rows, unsigned int Cols>
152{
154
155 for (unsigned int i = 0; i < Rows; i++) {
156 for (unsigned int j = 0; j < Cols; j++)
157 result[i][j] = m1[i][j] + m2[i][j];
158 }
159
160 return result;
161}
162
163#ifndef __DOXYGEN__
164bool matrixValidateYaml(const YamlObject &obj, unsigned int size);
165#endif /* __DOXYGEN__ */
166
167#ifndef __DOXYGEN__
168template<typename T, unsigned int Rows, unsigned int Cols>
169std::ostream &operator<<(std::ostream &out, const Matrix<T, Rows, Cols> &m)
170{
171 out << m.toString();
172 return out;
173}
174
175template<typename T, unsigned int Rows, unsigned int Cols>
176struct YamlObject::Getter<Matrix<T, Rows, Cols>> {
177 std::optional<Matrix<T, Rows, Cols>> get(const YamlObject &obj) const
178 {
179 if (!matrixValidateYaml(obj, Rows * Cols))
180 return std::nullopt;
181
182 Matrix<T, Rows, Cols> matrix;
183 T *data = &matrix[0][0];
184
185 unsigned int i = 0;
186 for (const YamlObject &entry : obj.asList()) {
187 const auto value = entry.get<T>();
188 if (!value)
189 return std::nullopt;
190
191 data[i++] = *value;
192 }
193
194 return matrix;
195 }
196};
197#endif /* __DOXYGEN__ */
198
199} /* namespace libcamera */
Matrix class.
Definition matrix.h:29
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition matrix.h:74
Matrix(const std::array< T, Rows *Cols > &data)
Construct a matrix from supplied data.
Definition matrix.h:36
Matrix< T, Rows, Cols > & operator*=(U d)
Multiply the matrix by a scalar in-place.
Definition matrix.h:84
Matrix()
Construct a zero matrix.
Definition matrix.h:31
const std::string toString() const
Assemble and return a string describing the matrix.
Definition matrix.h:51
static Matrix identity()
Construct an identity matrix.
Definition matrix.h:41
Span< const T, Cols > operator[](size_t i) const
Index to a row in the matrix.
Definition matrix.h:69
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition yaml_parser.h:175
Logging infrastructure.
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Definition log.h:46
Top-level libcamera namespace.
Definition backtrace.h:17
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition geometry.cpp:91
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:101
Matrix< T, Rows, Cols > operator+(const Matrix< T, Rows, Cols > &m1, const Matrix< T, Rows, Cols > &m2)
Matrix addition.
Definition matrix.h:151
A YAML parser helper.