libcamera: include/libcamera/internal/matrix.h Source File

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
16#include "libcamera/internal/yaml_parser.h"
17
18namespace libcamera {
19
20 LOG_DECLARE_CATEGORY(Matrix)
21
22#ifndef __DOXYGEN__
23template<typename T, unsigned int Rows, unsigned int Cols,
24 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
25#else
26template<typename T, unsigned int Rows, unsigned int Cols>
27#endif /* __DOXYGEN__ */
28 class Matrix
29{
30public:
31 Matrix()
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
41 static Matrix identity()
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__ */
84 Matrix<T, Rows, Cols> &operator*=(U d)
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__ */
101 Matrix<U, Rows, Cols> operator*(T d, const Matrix<U, Rows, Cols> &m)
102{
103 Matrix<U, Rows, Cols> result;
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__ */
119 Matrix<U, Rows, Cols> operator*(const Matrix<U, Rows, Cols> &m, T d)
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__ */
132 Matrix<T, R1, C2> operator*(const Matrix<T, R1, C1> &m1, const Matrix<T, R2, C2> &m2)
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>
151 Matrix<T, Rows, Cols> operator+(const Matrix<T, Rows, Cols> &m1, const Matrix<T, Rows, Cols> &m2)
152{
153 Matrix<T, Rows, Cols> result;
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 */
libcamera::Matrix
Matrix class.
Definition matrix.h:29
libcamera::Matrix::operator[]
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition matrix.h:74
libcamera::Matrix::Matrix
Matrix(const std::array< T, Rows *Cols > &data)
Construct a matrix from supplied data.
Definition matrix.h:36
libcamera::Matrix::operator*=
Matrix< T, Rows, Cols > & operator*=(U d)
Multiply the matrix by a scalar in-place.
Definition matrix.h:84
libcamera::Matrix::Matrix
Matrix()
Construct a zero matrix.
Definition matrix.h:31
libcamera::Matrix::toString
const std::string toString() const
Assemble and return a string describing the matrix.
Definition matrix.h:51
libcamera::Matrix::identity
static Matrix identity()
Construct an identity matrix.
Definition matrix.h:41
libcamera::Matrix::operator[]
Span< const T, Cols > operator[](size_t i) const
Index to a row in the matrix.
Definition matrix.h:69
libcamera::YamlObject::get
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition yaml_parser.h:175
log.h
Logging infrastructure.
LOG_DECLARE_CATEGORY
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Definition log.h:46
libcamera
Top-level libcamera namespace.
Definition backtrace.h:17
libcamera::operator<<
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition geometry.cpp:91
libcamera::operator*
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:101
libcamera::operator+
Matrix< T, Rows, Cols > operator+(const Matrix< T, Rows, Cols > &m1, const Matrix< T, Rows, Cols > &m2)
Matrix addition.
Definition matrix.h:151
yaml_parser.h
A YAML parser helper.