libcamera  v0.4.0+67-32cc6717
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>> * = nullptr>
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, Rows * Cols> data() const { return data_; }
70 
71  Span<const T, Cols> operator[](size_t i) const
72  {
73  return Span<const T, Cols>{ &data_.data()[i * Cols], Cols };
74  }
75 
76  Span<T, Cols> operator[](size_t i)
77  {
78  return Span<T, Cols>{ &data_.data()[i * Cols], Cols };
79  }
80 
81 #ifndef __DOXYGEN__
82  template<typename U, std::enable_if_t<std::is_arithmetic_v<U>>>
83 #else
84  template<typename U>
85 #endif /* __DOXYGEN__ */
87  {
88  for (unsigned int i = 0; i < Rows * Cols; i++)
89  data_[i] *= d;
90  return *this;
91  }
92 
93 private:
94  std::array<T, Rows * Cols> data_;
95 };
96 
97 #ifndef __DOXYGEN__
98 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
99  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
100 #else
101 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
102 #endif /* __DOXYGEN__ */
104 {
105  Matrix<U, Rows, Cols> result;
106 
107  for (unsigned int i = 0; i < Rows; i++) {
108  for (unsigned int j = 0; j < Cols; j++)
109  result[i][j] = d * m[i][j];
110  }
111 
112  return result;
113 }
114 
115 #ifndef __DOXYGEN__
116 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
117  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
118 #else
119 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
120 #endif /* __DOXYGEN__ */
122 {
123  return d * m;
124 }
125 
126 #ifndef __DOXYGEN__
127 template<typename T,
128  unsigned int R1, unsigned int C1,
129  unsigned int R2, unsigned int C2,
130  std::enable_if_t<C1 == R2> * = nullptr>
131 #else
132 template<typename T, unsigned int R1, unsigned int C1, unsigned int R2, unsigned in C2>
133 #endif /* __DOXYGEN__ */
135 {
136  Matrix<T, R1, C2> result;
137 
138  for (unsigned int i = 0; i < R1; i++) {
139  for (unsigned int j = 0; j < C2; j++) {
140  T sum = 0;
141 
142  for (unsigned int k = 0; k < C1; k++)
143  sum += m1[i][k] * m2[k][j];
144 
145  result[i][j] = sum;
146  }
147  }
148 
149  return result;
150 }
151 
152 template<typename T, unsigned int Rows, unsigned int Cols>
154 {
155  Matrix<T, Rows, Cols> result;
156 
157  for (unsigned int i = 0; i < Rows; i++) {
158  for (unsigned int j = 0; j < Cols; j++)
159  result[i][j] = m1[i][j] + m2[i][j];
160  }
161 
162  return result;
163 }
164 
165 #ifndef __DOXYGEN__
166 bool matrixValidateYaml(const YamlObject &obj, unsigned int size);
167 #endif /* __DOXYGEN__ */
168 
169 #ifndef __DOXYGEN__
170 template<typename T, unsigned int Rows, unsigned int Cols>
171 std::ostream &operator<<(std::ostream &out, const Matrix<T, Rows, Cols> &m)
172 {
173  out << m.toString();
174  return out;
175 }
176 
177 template<typename T, unsigned int Rows, unsigned int Cols>
178 struct YamlObject::Getter<Matrix<T, Rows, Cols>> {
179  std::optional<Matrix<T, Rows, Cols>> get(const YamlObject &obj) const
180  {
181  if (!matrixValidateYaml(obj, Rows * Cols))
182  return std::nullopt;
183 
184  Matrix<T, Rows, Cols> matrix;
185  T *data = &matrix[0][0];
186 
187  unsigned int i = 0;
188  for (const YamlObject &entry : obj.asList()) {
189  const auto value = entry.get<T>();
190  if (!value)
191  return std::nullopt;
192 
193  data[i++] = *value;
194  }
195 
196  return matrix;
197  }
198 };
199 #endif /* __DOXYGEN__ */
200 
201 } /* namespace libcamera */
Span< const T, Cols > operator[](size_t i) const
Index to a row in the matrix.
Definition: matrix.h:71
Top-level libcamera namespace.
Definition: backtrace.h:17
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition: matrix.h:76
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:206
Matrix< T, Rows, Cols > operator+(const Matrix< T, Rows, Cols > &m1, const Matrix< T, Rows, Cols > &m2)
Matrix addition.
Definition: matrix.h:153
Matrix< T, Rows, Cols > & operator*=(U d)
Multiply the matrix by a scalar in-place.
Definition: matrix.h:86
Matrix class.
Definition: matrix.h:28
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition: matrix.h:103
const std::string toString() const
Assemble and return a string describing the matrix.
Definition: matrix.h:51
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Matrix()
Construct a zero matrix.
Definition: matrix.h:31
A class representing the tree structure of the YAML content.
Definition: yaml_parser.h:27
Matrix(const std::array< T, Rows *Cols > &data)
Construct a matrix from supplied data.
Definition: matrix.h:36
Logging infrastructure.
Span< const T, Rows *Cols > data() const
Access the matrix data as a linear array.
Definition: matrix.h:69
A YAML parser helper.
static Matrix identity()
Construct an identity matrix.
Definition: matrix.h:41