libcamera: src/ipa/libipa/vector.h Source File

libcamera v0.4.0 Supporting cameras in Linux since 2019 |

Loading...
Searching...
No Matches
vector.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 * Vector and related operations
6 */
7#pragma once
8
9#include <algorithm>
10#include <array>
11#include <cmath>
12#include <functional>
13#include <numeric>
14#include <optional>
15#include <ostream>
16
17#include <libcamera/base/log.h>
18#include <libcamera/base/span.h>
19
20#include "libcamera/internal/matrix.h"
21#include "libcamera/internal/yaml_parser.h"
22
23namespace libcamera {
24
25 LOG_DECLARE_CATEGORY(Vector)
26
27namespace ipa {
28
29#ifndef __DOXYGEN__
30template<typename T, unsigned int Rows,
31 std::enable_if_t<std::is_arithmetic_v<T>> * = nullptr>
32#else
33template<typename T, unsigned int Rows>
34#endif /* __DOXYGEN__ */
35 class Vector
36{
37public:
38 constexpr Vector() = default;
39
40 constexpr explicit Vector(T scalar)
41 {
42 data_.fill(scalar);
43 }
44
45 constexpr Vector(const std::array<T, Rows> &data)
46 {
47 for (unsigned int i = 0; i < Rows; i++)
48 data_[i] = data[i];
49 }
50
51 const T &operator[](size_t i) const
52 {
53 ASSERT(i < data_.size());
54 return data_[i];
55 }
56
57 T &operator[](size_t i)
58 {
59 ASSERT(i < data_.size());
60 return data_[i];
61 }
62
63 constexpr Vector<T, Rows> operator-() const
64 {
65 Vector<T, Rows> ret;
66 for (unsigned int i = 0; i < Rows; i++)
67 ret[i] = -data_[i];
68 return ret;
69 }
70
71 constexpr Vector operator+(const Vector &other) const
72 {
73 return apply(*this, other, std::plus<>{});
74 }
75
76 constexpr Vector operator+(T scalar) const
77 {
78 return apply(*this, scalar, std::plus<>{});
79 }
80
81 constexpr Vector operator-(const Vector &other) const
82 {
83 return apply(*this, other, std::minus<>{});
84 }
85
86 constexpr Vector operator-(T scalar) const
87 {
88 return apply(*this, scalar, std::minus<>{});
89 }
90
91 constexpr Vector operator*(const Vector &other) const
92 {
93 return apply(*this, other, std::multiplies<>{});
94 }
95
96 constexpr Vector operator*(T scalar) const
97 {
98 return apply(*this, scalar, std::multiplies<>{});
99 }
100
101 constexpr Vector operator/(const Vector &other) const
102 {
103 return apply(*this, other, std::divides<>{});
104 }
105
106 constexpr Vector operator/(T scalar) const
107 {
108 return apply(*this, scalar, std::divides<>{});
109 }
110
111 Vector &operator+=(const Vector &other)
112 {
113 return apply(other, [](T a, T b) { return a + b; });
114 }
115
116 Vector &operator+=(T scalar)
117 {
118 return apply(scalar, [](T a, T b) { return a + b; });
119 }
120
121 Vector &operator-=(const Vector &other)
122 {
123 return apply(other, [](T a, T b) { return a - b; });
124 }
125
126 Vector &operator-=(T scalar)
127 {
128 return apply(scalar, [](T a, T b) { return a - b; });
129 }
130
131 Vector &operator*=(const Vector &other)
132 {
133 return apply(other, [](T a, T b) { return a * b; });
134 }
135
136 Vector &operator*=(T scalar)
137 {
138 return apply(scalar, [](T a, T b) { return a * b; });
139 }
140
141 Vector &operator/=(const Vector &other)
142 {
143 return apply(other, [](T a, T b) { return a / b; });
144 }
145
146 Vector &operator/=(T scalar)
147 {
148 return apply(scalar, [](T a, T b) { return a / b; });
149 }
150
151 constexpr Vector min(const Vector &other) const
152 {
153 return apply(*this, other, [](T a, T b) { return std::min(a, b); });
154 }
155
156 constexpr Vector min(T scalar) const
157 {
158 return apply(*this, scalar, [](T a, T b) { return std::min(a, b); });
159 }
160
161 constexpr Vector max(const Vector &other) const
162 {
163 return apply(*this, other, [](T a, T b) { return std::max(a, b); });
164 }
165
166 constexpr Vector max(T scalar) const
167 {
168 return apply(*this, scalar, [](T a, T b) -> T { return std::max(a, b); });
169 }
170
171 constexpr T dot(const Vector<T, Rows> &other) const
172 {
173 T ret = 0;
174 for (unsigned int i = 0; i < Rows; i++)
175 ret += data_[i] * other[i];
176 return ret;
177 }
178
179#ifndef __DOXYGEN__
180 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
181#endif /* __DOXYGEN__ */
182 constexpr const T &x() const { return data_[0]; }
183#ifndef __DOXYGEN__
184 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
185#endif /* __DOXYGEN__ */
186 constexpr const T &y() const { return data_[1]; }
187#ifndef __DOXYGEN__
188 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
189#endif /* __DOXYGEN__ */
190 constexpr const T &z() const { return data_[2]; }
191#ifndef __DOXYGEN__
192 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
193#endif /* __DOXYGEN__ */
194 constexpr T &x() { return data_[0]; }
195#ifndef __DOXYGEN__
196 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
197#endif /* __DOXYGEN__ */
198 constexpr T &y() { return data_[1]; }
199#ifndef __DOXYGEN__
200 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
201#endif /* __DOXYGEN__ */
202 constexpr T &z() { return data_[2]; }
203
204#ifndef __DOXYGEN__
205 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
206#endif /* __DOXYGEN__ */
207 constexpr const T &r() const { return data_[0]; }
208#ifndef __DOXYGEN__
209 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
210#endif /* __DOXYGEN__ */
211 constexpr const T &g() const { return data_[1]; }
212#ifndef __DOXYGEN__
213 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
214#endif /* __DOXYGEN__ */
215 constexpr const T &b() const { return data_[2]; }
216#ifndef __DOXYGEN__
217 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
218#endif /* __DOXYGEN__ */
219 constexpr T &r() { return data_[0]; }
220#ifndef __DOXYGEN__
221 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
222#endif /* __DOXYGEN__ */
223 constexpr T &g() { return data_[1]; }
224#ifndef __DOXYGEN__
225 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
226#endif /* __DOXYGEN__ */
227 constexpr T &b() { return data_[2]; }
228
229 constexpr double length2() const
230 {
231 double ret = 0;
232 for (unsigned int i = 0; i < Rows; i++)
233 ret += data_[i] * data_[i];
234 return ret;
235 }
236
237 constexpr double length() const
238 {
239 return std::sqrt(length2());
240 }
241
242 template<typename R = T>
243 constexpr R sum() const
244 {
245 return std::accumulate(data_.begin(), data_.end(), R{});
246 }
247
248private:
249 template<class BinaryOp>
250 static constexpr Vector apply(const Vector &lhs, const Vector &rhs, BinaryOp op)
251 {
252 Vector result;
253 std::transform(lhs.data_.begin(), lhs.data_.end(),
254 rhs.data_.begin(), result.data_.begin(),
255 op);
256
257 return result;
258 }
259
260 template<class BinaryOp>
261 static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)
262 {
263 Vector result;
264 std::transform(lhs.data_.begin(), lhs.data_.end(),
265 result.data_.begin(),
266 [&op, rhs](T v) { return op(v, rhs); });
267
268 return result;
269 }
270
271 template<class BinaryOp>
272 Vector &apply(const Vector &other, BinaryOp op)
273 {
274 auto itOther = other.data_.begin();
275 std::for_each(data_.begin(), data_.end(),
276 [&op, &itOther](T &v) { v = op(v, *itOther++); });
277
278 return *this;
279 }
280
281 template<class BinaryOp>
282 Vector &apply(T scalar, BinaryOp op)
283 {
284 std::for_each(data_.begin(), data_.end(),
285 [&op, scalar](T &v) { v = op(v, scalar); });
286
287 return *this;
288 }
289
290 std::array<T, Rows> data_;
291};
292
293template<typename T>
294 using RGB = Vector<T, 3>;
295
296template<typename T, unsigned int Rows, unsigned int Cols>
297 Vector<T, Rows> operator*(const Matrix<T, Rows, Cols> &m, const Vector<T, Cols> &v)
298{
299 Vector<T, Rows> result;
300
301 for (unsigned int i = 0; i < Rows; i++) {
302 T sum = 0;
303 for (unsigned int j = 0; j < Cols; j++)
304 sum += m[i][j] * v[j];
305 result[i] = sum;
306 }
307
308 return result;
309}
310
311template<typename T, unsigned int Rows>
312 bool operator==(const Vector<T, Rows> &lhs, const Vector<T, Rows> &rhs)
313{
314 for (unsigned int i = 0; i < Rows; i++) {
315 if (lhs[i] != rhs[i])
316 return false;
317 }
318
319 return true;
320}
321
322template<typename T, unsigned int Rows>
323 bool operator!=(const Vector<T, Rows> &lhs, const Vector<T, Rows> &rhs)
324{
325 return !(lhs == rhs);
326}
327
328#ifndef __DOXYGEN__
329bool vectorValidateYaml(const YamlObject &obj, unsigned int size);
330#endif /* __DOXYGEN__ */
331
332} /* namespace ipa */
333
334#ifndef __DOXYGEN__
335template<typename T, unsigned int Rows>
336std::ostream &operator<<(std::ostream &out, const ipa::Vector<T, Rows> &v)
337{
338 out << "Vector { ";
339 for (unsigned int i = 0; i < Rows; i++) {
340 out << v[i];
341 out << ((i + 1 < Rows) ? ", " : " ");
342 }
343 out << " }";
344
345 return out;
346}
347
348template<typename T, unsigned int Rows>
349struct YamlObject::Getter<ipa::Vector<T, Rows>> {
350 std::optional<ipa::Vector<T, Rows>> get(const YamlObject &obj) const
351 {
352 if (!ipa::vectorValidateYaml(obj, Rows))
353 return std::nullopt;
354
355 ipa::Vector<T, Rows> vector;
356
357 unsigned int i = 0;
358 for (const YamlObject &entry : obj.asList()) {
359 const auto value = entry.get<T>();
360 if (!value)
361 return std::nullopt;
362 vector[i++] = *value;
363 }
364
365 return vector;
366 }
367};
368#endif /* __DOXYGEN__ */
369
370} /* namespace libcamera */
libcamera::Matrix
Matrix class.
Definition matrix.h:29
libcamera::YamlObject
A class representing the tree structure of the YAML content.
Definition yaml_parser.h:28
libcamera::YamlObject::get
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition yaml_parser.h:175
libcamera::ipa::Vector
Vector class.
Definition vector.h:36
libcamera::ipa::Vector::x
constexpr T & x()
Convenience function to access the first element of the vector.
Definition vector.h:194
libcamera::ipa::Vector::operator+=
Vector & operator+=(T scalar)
Add scalar element-wise to this vector.
Definition vector.h:116
libcamera::ipa::Vector::sum
constexpr R sum() const
Calculate the sum of all the vector elements.
Definition vector.h:243
libcamera::ipa::Vector::max
constexpr Vector max(const Vector &other) const
Calculate the maximum of this vector and other element-wise.
Definition vector.h:161
libcamera::ipa::Vector::operator*
constexpr Vector operator*(T scalar) const
Calculate the product of this vector and scalar element-wise.
Definition vector.h:96
libcamera::ipa::Vector::dot
constexpr T dot(const Vector< T, Rows > &other) const
Compute the dot product.
Definition vector.h:171
libcamera::ipa::Vector::b
constexpr T & b()
Convenience function to access the third element of the vector.
Definition vector.h:227
libcamera::ipa::Vector::g
constexpr T & g()
Convenience function to access the second element of the vector.
Definition vector.h:223
libcamera::ipa::Vector::operator-=
Vector & operator-=(T scalar)
Subtract scalar element-wise from this vector.
Definition vector.h:126
libcamera::ipa::Vector::x
constexpr const T & x() const
Convenience function to access the first element of the vector.
Definition vector.h:182
libcamera::ipa::Vector::operator/=
Vector & operator/=(const Vector &other)
Divide this vector by other element-wise.
Definition vector.h:141
libcamera::ipa::Vector::operator/
constexpr Vector operator/(T scalar) const
Calculate the quotient of this vector and scalar element-wise.
Definition vector.h:106
libcamera::ipa::Vector::operator-
constexpr Vector operator-(const Vector &other) const
Calculate the difference of this vector and other element-wise.
Definition vector.h:81
libcamera::ipa::Vector::z
constexpr const T & z() const
Convenience function to access the third element of the vector.
Definition vector.h:190
libcamera::ipa::Vector::min
constexpr Vector min(T scalar) const
Calculate the minimum of this vector and scalar element-wise.
Definition vector.h:156
libcamera::ipa::Vector::g
constexpr const T & g() const
Convenience function to access the second element of the vector.
Definition vector.h:211
libcamera::ipa::Vector::Vector
constexpr Vector()=default
Construct an uninitialized vector.
libcamera::ipa::Vector::max
constexpr Vector max(T scalar) const
Calculate the maximum of this vector and scalar element-wise.
Definition vector.h:166
libcamera::ipa::Vector::operator*=
Vector & operator*=(const Vector &other)
Multiply this vector by other element-wise.
Definition vector.h:131
libcamera::ipa::Vector::operator*=
Vector & operator*=(T scalar)
Multiply this vector by scalar element-wise.
Definition vector.h:136
libcamera::ipa::Vector::operator-
constexpr Vector operator-(T scalar) const
Calculate the difference of this vector and scalar element-wise.
Definition vector.h:86
libcamera::ipa::Vector::Vector
constexpr Vector(const std::array< T, Rows > &data)
Construct vector from supplied data.
Definition vector.h:45
libcamera::ipa::Vector::operator*
constexpr Vector operator*(const Vector &other) const
Calculate the product of this vector and other element-wise.
Definition vector.h:91
libcamera::ipa::Vector< double, 2 >::b
constexpr const double & b() const
Definition vector.h:215
libcamera::ipa::Vector::y
constexpr const T & y() const
Convenience function to access the second element of the vector.
Definition vector.h:186
libcamera::ipa::Vector::operator-
constexpr Vector< T, Rows > operator-() const
Negate a Vector by negating both all of its coordinates.
Definition vector.h:63
libcamera::ipa::Vector::length
constexpr double length() const
Get the length of the vector.
Definition vector.h:237
libcamera::ipa::Vector::operator/
constexpr Vector operator/(const Vector &other) const
Calculate the quotient of this vector and other element-wise.
Definition vector.h:101
libcamera::ipa::Vector::y
constexpr T & y()
Convenience function to access the second element of the vector.
Definition vector.h:198
libcamera::ipa::Vector::Vector
constexpr Vector(T scalar)
Construct a vector filled with a scalar value.
Definition vector.h:40
libcamera::ipa::Vector::operator[]
const T & operator[](size_t i) const
Index to an element in the vector.
Definition vector.h:51
libcamera::ipa::Vector::operator+=
Vector & operator+=(const Vector &other)
Add other element-wise to this vector.
Definition vector.h:111
libcamera::ipa::Vector::r
constexpr const T & r() const
Convenience function to access the first element of the vector.
Definition vector.h:207
libcamera::ipa::Vector::operator-=
Vector & operator-=(const Vector &other)
Subtract other element-wise from this vector.
Definition vector.h:121
libcamera::ipa::Vector::length2
constexpr double length2() const
Get the squared length of the vector.
Definition vector.h:229
libcamera::ipa::Vector::operator+
constexpr Vector operator+(const Vector &other) const
Calculate the sum of this vector and other element-wise.
Definition vector.h:71
libcamera::ipa::Vector::r
constexpr T & r()
Convenience function to access the first element of the vector.
Definition vector.h:219
libcamera::ipa::Vector::operator[]
T & operator[](size_t i)
Index to an element in the vector.
Definition vector.h:57
libcamera::ipa::Vector::operator+
constexpr Vector operator+(T scalar) const
Calculate the sum of this vector and scalar element-wise.
Definition vector.h:76
libcamera::ipa::Vector::min
constexpr Vector min(const Vector &other) const
Calculate the minimum of this vector and other element-wise.
Definition vector.h:151
libcamera::ipa::Vector::z
constexpr T & z()
Convenience function to access the third element of the vector.
Definition vector.h:202
libcamera::ipa::Vector::operator/=
Vector & operator/=(T scalar)
Divide this vector by scalar element-wise.
Definition vector.h:146
log.h
Logging infrastructure.
LOG_DECLARE_CATEGORY
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Definition log.h:46
ASSERT
#define ASSERT(condition)
Abort program execution if assertion fails.
Definition log.h:126
matrix.h
Matrix class.
libcamera::ipa
The IPA (Image Processing Algorithm) namespace.
Definition af.cpp:58
libcamera::ipa::RGB
Vector< T, 3 > RGB
A Vector of 3 elements representing an RGB pixel value.
Definition vector.h:294
libcamera::ipa::operator==
bool operator==(const Vector< T, Rows > &lhs, const Vector< T, Rows > &rhs)
Compare vectors for equality.
Definition vector.h:312
libcamera::ipa::operator*
Vector< T, Rows > operator*(const Matrix< T, Rows, Cols > &m, const Vector< T, Cols > &v)
Multiply a matrix by a vector.
Definition vector.h:297
libcamera::ipa::operator!=
bool operator!=(const Vector< T, Rows > &lhs, const Vector< T, Rows > &rhs)
Compare vectors for inequality.
Definition vector.h:323
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
yaml_parser.h
A YAML parser helper.