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