libcamera  v0.4.0
Supporting cameras in Linux since 2019
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 
18 namespace libcamera {
19 
21 
22 #ifndef __DOXYGEN__
23 template<typename T, unsigned int Rows, unsigned int Cols,
24  std::enable_if_t<std::is_arithmetic_v<T>, bool> = true>
25 #else
26 template<typename T, unsigned int Rows, unsigned int Cols>
27 #endif /* __DOXYGEN__ */
28 class Matrix
29 {
30 public:
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__ */
85  {
86  for (unsigned int i = 0; i < Rows * Cols; i++)
87  data_[i] *= d;
88  return *this;
89  }
90 
91 private:
92  std::array<T, Rows * Cols> data_;
93 };
94 
95 #ifndef __DOXYGEN__
96 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
97  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
98 #else
99 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
100 #endif /* __DOXYGEN__ */
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__
114 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
115  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
116 #else
117 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
118 #endif /* __DOXYGEN__ */
120 {
121  return d * m;
122 }
123 
124 #ifndef __DOXYGEN__
125 template<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
130 template<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 
150 template<typename T, unsigned int Rows, unsigned int Cols>
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__
164 bool matrixValidateYaml(const YamlObject &obj, unsigned int size);
165 #endif /* __DOXYGEN__ */
166 
167 #ifndef __DOXYGEN__
168 template<typename T, unsigned int Rows, unsigned int Cols>
169 std::ostream &operator<<(std::ostream &out, const Matrix<T, Rows, Cols> &m)
170 {
171  out << m.toString();
172  return out;
173 }
174 
175 template<typename T, unsigned int Rows, unsigned int Cols>
176 struct 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
static Matrix identity()
Construct an identity matrix.
Definition: matrix.h:41
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
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition: matrix.h:74
const std::string toString() const
Assemble and return a string describing the matrix.
Definition: matrix.h:51
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.
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.