libcamera  v0.3.1+12-19bbca3c
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 <cmath>
11 #include <sstream>
12 #include <vector>
13 
14 #include <libcamera/base/log.h>
15 #include <libcamera/base/span.h>
16 
18 
19 namespace libcamera {
20 
22 
23 namespace ipa {
24 
25 #ifndef __DOXYGEN__
26 template<typename T, unsigned int Rows, unsigned int Cols,
27  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
28 #else
29 template<typename T, unsigned int Rows, unsigned int Cols>
30 #endif /* __DOXYGEN__ */
31 class Matrix
32 {
33 public:
35  {
36  data_.fill(static_cast<T>(0));
37  }
38 
39  Matrix(const std::vector<T> &data)
40  {
41  std::copy(data.begin(), data.end(), data_.begin());
42  }
43 
44  static Matrix identity()
45  {
46  Matrix ret;
47  for (size_t i = 0; i < std::min(Rows, Cols); i++)
48  ret[i][i] = static_cast<T>(1);
49  return ret;
50  }
51 
52  ~Matrix() = default;
53 
54  const std::string toString() const
55  {
56  std::stringstream out;
57 
58  out << "Matrix { ";
59  for (unsigned int i = 0; i < Rows; i++) {
60  out << "[ ";
61  for (unsigned int j = 0; j < Cols; j++) {
62  out << (*this)[i][j];
63  out << ((j + 1 < Cols) ? ", " : " ");
64  }
65  out << ((i + 1 < Rows) ? "], " : "]");
66  }
67  out << " }";
68 
69  return out.str();
70  }
71 
72  Span<const T, Cols> operator[](size_t i) const
73  {
74  return Span<const T, Cols>{ &data_.data()[i * Cols], Cols };
75  }
76 
77  Span<T, Cols> operator[](size_t i)
78  {
79  return Span<T, Cols>{ &data_.data()[i * Cols], Cols };
80  }
81 
82 #ifndef __DOXYGEN__
83  template<typename U, std::enable_if_t<std::is_arithmetic_v<U>>>
84 #else
85  template<typename U>
86 #endif /* __DOXYGEN__ */
88  {
89  for (unsigned int i = 0; i < Rows * Cols; i++)
90  data_[i] *= d;
91  return *this;
92  }
93 
94 private:
95  std::array<T, Rows * Cols> data_;
96 };
97 
98 #ifndef __DOXYGEN__
99 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
100  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
101 #else
102 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
103 #endif /* __DOXYGEN__ */
105 {
106  Matrix<U, Rows, Cols> result;
107 
108  for (unsigned int i = 0; i < Rows; i++) {
109  for (unsigned int j = 0; j < Cols; j++)
110  result[i][j] = d * m[i][j];
111  }
112 
113  return result;
114 }
115 
116 #ifndef __DOXYGEN__
117 template<typename T, typename U, unsigned int Rows, unsigned int Cols,
118  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
119 #else
120 template<typename T, typename U, unsigned int Rows, unsigned int Cols>
121 #endif /* __DOXYGEN__ */
123 {
124  return d * m;
125 }
126 
127 #ifndef __DOXYGEN__
128 template<typename T,
129  unsigned int R1, unsigned int C1,
130  unsigned int R2, unsigned int C2,
131  std::enable_if_t<C1 == R2> * = nullptr>
132 #else
133 template<typename T, unsigned int R1, unsigned int C1, unsigned int R2, unsigned in C2>
134 #endif /* __DOXYGEN__ */
136 {
137  Matrix<T, R1, C2> result;
138 
139  for (unsigned int i = 0; i < R1; i++) {
140  for (unsigned int j = 0; j < C2; j++) {
141  T sum = 0;
142 
143  for (unsigned int k = 0; k < C1; k++)
144  sum += m1[i][k] * m2[k][j];
145 
146  result[i][j] = sum;
147  }
148  }
149 
150  return result;
151 }
152 
153 template<typename T, unsigned int Rows, unsigned int Cols>
155 {
156  Matrix<T, Rows, Cols> result;
157 
158  for (unsigned int i = 0; i < Rows; i++) {
159  for (unsigned int j = 0; j < Cols; j++)
160  result[i][j] = m1[i][j] + m2[i][j];
161  }
162 
163  return result;
164 }
165 
166 #ifndef __DOXYGEN__
167 bool matrixValidateYaml(const YamlObject &obj, unsigned int size);
168 #endif /* __DOXYGEN__ */
169 
170 } /* namespace ipa */
171 
172 #ifndef __DOXYGEN__
173 template<typename T, unsigned int Rows, unsigned int Cols>
174 std::ostream &operator<<(std::ostream &out, const ipa::Matrix<T, Rows, Cols> &m)
175 {
176  out << m.toString();
177  return out;
178 }
179 
180 template<typename T, unsigned int Rows, unsigned int Cols>
181 struct YamlObject::Getter<ipa::Matrix<T, Rows, Cols>> {
182  std::optional<ipa::Matrix<T, Rows, Cols>> get(const YamlObject &obj) const
183  {
184  if (!ipa::matrixValidateYaml(obj, Rows * Cols))
185  return std::nullopt;
186 
188  T *data = &matrix[0][0];
189 
190  unsigned int i = 0;
191  for (const YamlObject &entry : obj.asList()) {
192  const auto value = entry.get<T>();
193  if (!value)
194  return std::nullopt;
195 
196  data[i++] = *value;
197  }
198 
199  return matrix;
200  }
201 };
202 #endif /* __DOXYGEN__ */
203 
204 } /* namespace libcamera */
Matrix< T, Rows, Cols > operator+(const Matrix< T, Rows, Cols > &m1, const Matrix< T, Rows, Cols > &m2)
Matrix addition.
Definition: matrix.h:154
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition: matrix.h:104
Matrix< T, Rows, Cols > & operator*=(U d)
Multiply the matrix by a scalar in-place.
Definition: matrix.h:87
Top-level libcamera namespace.
Definition: backtrace.h:17
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition: yaml_parser.h:196
Span< const T, Cols > operator[](size_t i) const
Index to a row in the matrix.
Definition: matrix.h:72
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition: matrix.h:77
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
static Matrix identity()
Construct an identity matrix.
Definition: matrix.h:44
A class representing the tree structure of the YAML content.
Definition: yaml_parser.h:25
const std::string toString() const
Assemble and return a string describing the matrix.
Definition: matrix.h:54
Matrix(const std::vector< T > &data)
Construct a matrix from supplied data.
Definition: matrix.h:39
Matrix class.
Definition: matrix.h:31
Logging infrastructure.
A YAML parser helper.
Matrix()
Construct a zero matrix.
Definition: matrix.h:34