libcamera  v0.3.2+116-83c5ad0f
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 namespace ipa {
23 
24 #ifndef __DOXYGEN__
25 template<typename T, unsigned int Rows, unsigned int Cols,
26  std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
27 #else
28 template<typename T, unsigned int Rows, unsigned int Cols>
29 #endif /* __DOXYGEN__ */
30 class Matrix
31 {
32 public:
34  {
35  data_.fill(static_cast<T>(0));
36  }
37 
38  Matrix(const std::vector<T> &data)
39  {
40  std::copy(data.begin(), data.end(), data_.begin());
41  }
42 
43  static Matrix identity()
44  {
45  Matrix ret;
46  for (size_t i = 0; i < std::min(Rows, Cols); i++)
47  ret[i][i] = static_cast<T>(1);
48  return ret;
49  }
50 
51  ~Matrix() = default;
52 
53  const std::string toString() const
54  {
55  std::stringstream out;
56 
57  out << "Matrix { ";
58  for (unsigned int i = 0; i < Rows; i++) {
59  out << "[ ";
60  for (unsigned int j = 0; j < Cols; j++) {
61  out << (*this)[i][j];
62  out << ((j + 1 < Cols) ? ", " : " ");
63  }
64  out << ((i + 1 < Rows) ? "], " : "]");
65  }
66  out << " }";
67 
68  return out.str();
69  }
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 } /* namespace ipa */
170 
171 #ifndef __DOXYGEN__
172 template<typename T, unsigned int Rows, unsigned int Cols>
173 std::ostream &operator<<(std::ostream &out, const ipa::Matrix<T, Rows, Cols> &m)
174 {
175  out << m.toString();
176  return out;
177 }
178 
179 template<typename T, unsigned int Rows, unsigned int Cols>
180 struct YamlObject::Getter<ipa::Matrix<T, Rows, Cols>> {
181  std::optional<ipa::Matrix<T, Rows, Cols>> get(const YamlObject &obj) const
182  {
183  if (!ipa::matrixValidateYaml(obj, Rows * Cols))
184  return std::nullopt;
185 
187  T *data = &matrix[0][0];
188 
189  unsigned int i = 0;
190  for (const YamlObject &entry : obj.asList()) {
191  const auto value = entry.get<T>();
192  if (!value)
193  return std::nullopt;
194 
195  data[i++] = *value;
196  }
197 
198  return matrix;
199  }
200 };
201 #endif /* __DOXYGEN__ */
202 
203 } /* namespace libcamera */
Matrix< T, Rows, Cols > operator+(const Matrix< T, Rows, Cols > &m1, const Matrix< T, Rows, Cols > &m2)
Matrix addition.
Definition: matrix.h:153
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition: matrix.h:103
Matrix< T, Rows, Cols > & operator*=(U d)
Multiply the matrix by a scalar in-place.
Definition: matrix.h:86
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:206
Span< const T, Cols > operator[](size_t i) const
Index to a row in the matrix.
Definition: matrix.h:71
Span< T, Cols > operator[](size_t i)
Index to a row in the matrix.
Definition: matrix.h:76
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
static Matrix identity()
Construct an identity matrix.
Definition: matrix.h:43
A class representing the tree structure of the YAML content.
Definition: yaml_parser.h:27
const std::string toString() const
Assemble and return a string describing the matrix.
Definition: matrix.h:53
Matrix(const std::vector< T > &data)
Construct a matrix from supplied data.
Definition: matrix.h:38
Matrix class.
Definition: matrix.h:30
Logging infrastructure.
A YAML parser helper.
Matrix()
Construct a zero matrix.
Definition: matrix.h:33