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
22
23namespace libcamera {
24
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__ */
33class 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 {
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
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
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
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
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>
293
294template<typename T, unsigned int Rows, unsigned int Cols>
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>
310bool 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>
321bool 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 */
Matrix class.
Definition matrix.h:29
Vector class.
Definition vector.h:34
constexpr double length() const
Get the length of the vector.
Definition vector.h:235
constexpr const T & b() const
Definition vector.h:213
constexpr Vector operator/(T scalar) const
Calculate the quotient of this vector and scalar element-wise.
Definition vector.h:104
constexpr Vector operator*(T scalar) const
Calculate the product of this vector and scalar element-wise.
Definition vector.h:94
constexpr T & g()
Convenience function to access the second element of the vector.
Definition vector.h:221
constexpr Vector()=default
Construct an uninitialized vector.
constexpr Vector min(T scalar) const
Calculate the minimum of this vector and scalar element-wise.
Definition vector.h:154
constexpr T & r()
Convenience function to access the first element of the vector.
Definition vector.h:217
constexpr T & b()
Convenience function to access the third element of the vector.
Definition vector.h:225
constexpr Vector< T, Rows > operator-() const
Negate a Vector by negating both all of its coordinates.
Definition vector.h:61
constexpr T dot(const Vector< T, Rows > &other) const
Compute the dot product.
Definition vector.h:169
constexpr Vector(const std::array< T, Rows > &data)
Construct vector from supplied data.
Definition vector.h:43
constexpr Vector(T scalar)
Construct a vector filled with a scalar value.
Definition vector.h:38
const T & operator[](size_t i) const
Index to an element in the vector.
Definition vector.h:49
constexpr const T & y() const
Definition vector.h:184
constexpr T & z()
Convenience function to access the third element of the vector.
Definition vector.h:200
Vector & operator-=(const Vector &other)
Subtract other element-wise from this vector.
Definition vector.h:119
constexpr double length2() const
Get the squared length of the vector.
Definition vector.h:227
constexpr const T & z() const
Definition vector.h:188
constexpr Vector operator-(T scalar) const
Calculate the difference of this vector and scalar element-wise.
Definition vector.h:84
Vector & operator-=(T scalar)
Subtract scalar element-wise from this vector.
Definition vector.h:124
constexpr Vector operator/(const Vector &other) const
Calculate the quotient of this vector and other element-wise.
Definition vector.h:99
constexpr R sum() const
Calculate the sum of all the vector elements.
Definition vector.h:241
Vector & operator/=(const Vector &other)
Divide this vector by other element-wise.
Definition vector.h:139
Vector & operator/=(T scalar)
Divide this vector by scalar element-wise.
Definition vector.h:144
constexpr T & x()
Convenience function to access the first element of the vector.
Definition vector.h:192
constexpr Vector min(const Vector &other) const
Calculate the minimum of this vector and other element-wise.
Definition vector.h:149
constexpr T & y()
Convenience function to access the second element of the vector.
Definition vector.h:196
constexpr const T & x() const
Definition vector.h:180
constexpr Vector operator+(const Vector &other) const
Calculate the sum of this vector and other element-wise.
Definition vector.h:69
Vector & operator+=(T scalar)
Add scalar element-wise to this vector.
Definition vector.h:114
constexpr Vector operator-(const Vector &other) const
Calculate the difference of this vector and other element-wise.
Definition vector.h:79
Vector & operator*=(const Vector &other)
Multiply this vector by other element-wise.
Definition vector.h:129
Vector & operator*=(T scalar)
Multiply this vector by scalar element-wise.
Definition vector.h:134
constexpr const T & r() const
Definition vector.h:205
Vector & operator+=(const Vector &other)
Add other element-wise to this vector.
Definition vector.h:109
constexpr Vector operator*(const Vector &other) const
Calculate the product of this vector and other element-wise.
Definition vector.h:89
constexpr Vector operator+(T scalar) const
Calculate the sum of this vector and scalar element-wise.
Definition vector.h:74
constexpr const T & g() const
Definition vector.h:209
constexpr Vector max(T scalar) const
Calculate the maximum of this vector and scalar element-wise.
Definition vector.h:164
T & operator[](size_t i)
Definition vector.h:55
constexpr Vector max(const Vector &other) const
Calculate the maximum of this vector and other element-wise.
Definition vector.h:159
std::optional< T > get() const
Parse the YamlObject as a T value.
Definition yaml_parser.h:175
ListAdapter asList() const
Wrap a list YamlObject in an adapter that exposes iterators.
Definition yaml_parser.h:206
Logging infrastructure.
#define LOG_DECLARE_CATEGORY(name)
Declare a category of log messages.
Definition log.h:51
#define ASSERT(condition)
Abort program execution if assertion fails.
Definition log.h:127
Matrix class.
Top-level libcamera namespace.
Definition backtrace.h:17
std::ostream & operator<<(std::ostream &out, const Point &p)
Insert a text representation of a Point into an output stream.
Definition geometry.cpp:91
bool operator==(const ColorSpace &lhs, const ColorSpace &rhs)
Compare color spaces for equality.
Definition color_space.cpp:506
bool operator!=(const Vector< T, Rows > &lhs, const Vector< T, Rows > &rhs)
Compare vectors for inequality.
Definition vector.h:321
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:103
A YAML parser helper.