libcamera: include/libcamera/internal/vector.h Source File

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