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

libcamera v0.7.1 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
21#include "libcamera/internal/matrix.h"
22#include "libcamera/internal/value_node.h"
23
24namespace libcamera {
25
26 LOG_DECLARE_CATEGORY(Vector)
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__ */
34 class 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 {
68 Vector<T, Rows> ret;
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 Vector &operator+=(const Vector &other)
115 {
116 return apply(other, [](T a, T b) { return a + b; });
117 }
118
119 Vector &operator+=(T scalar)
120 {
121 return apply(scalar, [](T a, T b) { return a + b; });
122 }
123
124 Vector &operator-=(const Vector &other)
125 {
126 return apply(other, [](T a, T b) { return a - b; });
127 }
128
129 Vector &operator-=(T scalar)
130 {
131 return apply(scalar, [](T a, T b) { return a - b; });
132 }
133
134 Vector &operator*=(const Vector &other)
135 {
136 return apply(other, [](T a, T b) { return a * b; });
137 }
138
139 Vector &operator*=(T scalar)
140 {
141 return apply(scalar, [](T a, T b) { return a * b; });
142 }
143
144 Vector &operator/=(const Vector &other)
145 {
146 return apply(other, [](T a, T b) { return a / b; });
147 }
148
149 Vector &operator/=(T scalar)
150 {
151 return apply(scalar, [](T a, T b) { return a / b; });
152 }
153
154 constexpr Vector min(const Vector &other) const
155 {
156 return apply(*this, other, [](T a, T b) { return std::min(a, b); });
157 }
158
159 constexpr Vector min(T scalar) const
160 {
161 return apply(*this, scalar, [](T a, T b) { return std::min(a, b); });
162 }
163
164 constexpr Vector max(const Vector &other) const
165 {
166 return apply(*this, other, [](T a, T b) { return std::max(a, b); });
167 }
168
169 constexpr Vector max(T scalar) const
170 {
171 return apply(*this, scalar, [](T a, T b) -> T { return std::max(a, b); });
172 }
173
174 constexpr T dot(const Vector<T, Rows> &other) const
175 {
176 T ret = 0;
177 for (unsigned int i = 0; i < Rows; i++)
178 ret += data_[i] * other[i];
179 return ret;
180 }
181
182#ifndef __DOXYGEN__
183 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
184#endif /* __DOXYGEN__ */
185 constexpr const T &x() const { return data_[0]; }
186#ifndef __DOXYGEN__
187 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
188#endif /* __DOXYGEN__ */
189 constexpr const T &y() const { return data_[1]; }
190#ifndef __DOXYGEN__
191 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
192#endif /* __DOXYGEN__ */
193 constexpr const T &z() const { return data_[2]; }
194#ifndef __DOXYGEN__
195 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
196#endif /* __DOXYGEN__ */
197 constexpr T &x() { return data_[0]; }
198#ifndef __DOXYGEN__
199 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
200#endif /* __DOXYGEN__ */
201 constexpr T &y() { return data_[1]; }
202#ifndef __DOXYGEN__
203 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
204#endif /* __DOXYGEN__ */
205 constexpr T &z() { return data_[2]; }
206
207#ifndef __DOXYGEN__
208 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
209#endif /* __DOXYGEN__ */
210 constexpr const T &r() const { return data_[0]; }
211#ifndef __DOXYGEN__
212 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
213#endif /* __DOXYGEN__ */
214 constexpr const T &g() const { return data_[1]; }
215#ifndef __DOXYGEN__
216 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
217#endif /* __DOXYGEN__ */
218 constexpr const T &b() const { return data_[2]; }
219#ifndef __DOXYGEN__
220 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 1>>
221#endif /* __DOXYGEN__ */
222 constexpr T &r() { return data_[0]; }
223#ifndef __DOXYGEN__
224 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 2>>
225#endif /* __DOXYGEN__ */
226 constexpr T &g() { return data_[1]; }
227#ifndef __DOXYGEN__
228 template<bool Dependent = false, typename = std::enable_if_t<Dependent || Rows >= 3>>
229#endif /* __DOXYGEN__ */
230 constexpr T &b() { return data_[2]; }
231
232 constexpr double length2() const
233 {
234 double ret = 0;
235 for (unsigned int i = 0; i < Rows; i++)
236 ret += data_[i] * data_[i];
237 return ret;
238 }
239
240 constexpr double length() const
241 {
242 return std::sqrt(length2());
243 }
244
245 template<typename R = T>
246 constexpr R sum() const
247 {
248 return std::accumulate(data_.begin(), data_.end(), R{});
249 }
250
251private:
252 template<class BinaryOp>
253 static constexpr Vector apply(const Vector &lhs, const Vector &rhs, BinaryOp op)
254 {
255 Vector result;
256 std::transform(lhs.data_.begin(), lhs.data_.end(),
257 rhs.data_.begin(), result.data_.begin(),
258 op);
259
260 return result;
261 }
262
263 template<class BinaryOp>
264 static constexpr Vector apply(const Vector &lhs, T rhs, BinaryOp op)
265 {
266 Vector result;
267 std::transform(lhs.data_.begin(), lhs.data_.end(),
268 result.data_.begin(),
269 [&op, rhs](T v) { return op(v, rhs); });
270
271 return result;
272 }
273
274 template<class BinaryOp>
275 Vector &apply(const Vector &other, BinaryOp op)
276 {
277 auto itOther = other.data_.begin();
278 std::for_each(data_.begin(), data_.end(),
279 [&op, &itOther](T &v) { v = op(v, *itOther++); });
280
281 return *this;
282 }
283
284 template<class BinaryOp>
285 Vector &apply(T scalar, BinaryOp op)
286 {
287 std::for_each(data_.begin(), data_.end(),
288 [&op, scalar](T &v) { v = op(v, scalar); });
289
290 return *this;
291 }
292
293 std::array<T, Rows> data_;
294};
295
296template<typename T>
297 using RGB = Vector<T, 3>;
298
299template<typename T, typename U, unsigned int Rows, unsigned int Cols>
300 Vector<std::common_type_t<T, U>, Rows> operator*(const Matrix<T, Rows, Cols> &m, const Vector<U, Cols> &v)
301{
302 Vector<std::common_type_t<T, U>, Rows> result;
303
304 for (unsigned int i = 0; i < Rows; i++) {
305 std::common_type_t<T, U> sum = 0;
306 for (unsigned int j = 0; j < Cols; j++)
307 sum += m[i][j] * v[j];
308 result[i] = sum;
309 }
310
311 return result;
312}
313
314template<typename T, unsigned int Rows>
315 bool operator==(const Vector<T, Rows> &lhs, const Vector<T, Rows> &rhs)
316{
317 for (unsigned int i = 0; i < Rows; i++) {
318 if (lhs[i] != rhs[i])
319 return false;
320 }
321
322 return true;
323}
324
325template<typename T, unsigned int Rows>
326 bool operator!=(const Vector<T, Rows> &lhs, const Vector<T, Rows> &rhs)
327{
328 return !(lhs == rhs);
329}
330
331#ifndef __DOXYGEN__
332bool vectorValidateYaml(const ValueNode &obj, unsigned int size);
333#endif /* __DOXYGEN__ */
334
335#ifndef __DOXYGEN__
336template<typename T, unsigned int Rows>
337std::ostream &operator<<(std::ostream &out, const Vector<T, Rows> &v)
338{
339 out << "Vector { ";
340 for (unsigned int i = 0; i < Rows; i++) {
341 out << v[i];
342 out << ((i + 1 < Rows) ? ", " : " ");
343 }
344 out << " }";
345
346 return out;
347}
348
349template<typename T, unsigned int Rows>
350struct ValueNode::Accessor<Vector<T, Rows>> {
351 std::optional<Vector<T, Rows>> get(const ValueNode &obj) const
352 {
353 if (!vectorValidateYaml(obj, Rows))
354 return std::nullopt;
355
356 Vector<T, Rows> vector;
357
358 unsigned int i = 0;
359 for (const ValueNode &entry : obj.asList()) {
360 const auto value = entry.get<T>();
361 if (!value)
362 return std::nullopt;
363 vector[i++] = *value;
364 }
365
366 return vector;
367 }
368};
369#endif /* __DOXYGEN__ */
370
371} /* namespace libcamera */
libcamera::Matrix
Matrix class.
Definition matrix.h:31
libcamera::ValueNode::get
std::optional< T > get() const
Parse the ValueNode as a T value.
Definition value_node.h:211
libcamera::Vector
Vector class.
Definition vector.h:35
libcamera::Vector::length2
constexpr double length2() const
Get the squared length of the vector.
Definition vector.h:232
libcamera::Vector::operator/
constexpr Vector operator/(const Vector &other) const
Calculate the quotient of this vector and other element-wise.
Definition vector.h:104
libcamera::Vector< T, 3 >::b
constexpr const T & b() const
Definition vector.h:218
libcamera::Vector::operator+
constexpr Vector operator+(const Vector &other) const
Calculate the sum of this vector and other element-wise.
Definition vector.h:74
libcamera::Vector::g
constexpr T & g()
Convenience function to access the second element of the vector.
Definition vector.h:226
libcamera::Vector::length
constexpr double length() const
Get the length of the vector.
Definition vector.h:240
libcamera::Vector::r
constexpr T & r()
Convenience function to access the first element of the vector.
Definition vector.h:222
libcamera::Vector::b
constexpr T & b()
Convenience function to access the third element of the vector.
Definition vector.h:230
libcamera::Vector::Vector
constexpr Vector(const std::array< T, Rows > &data)
Construct vector from supplied data.
Definition vector.h:44
libcamera::Vector::min
constexpr Vector min(const Vector &other) const
Calculate the minimum of this vector and other element-wise.
Definition vector.h:154
libcamera::Vector::y
constexpr const T & y() const
Convenience function to access the second element of the vector.
Definition vector.h:189
libcamera::Vector::z
constexpr T & z()
Convenience function to access the third element of the vector.
Definition vector.h:205
libcamera::Vector::operator+=
Vector & operator+=(const Vector &other)
Add other element-wise to this vector.
Definition vector.h:114
libcamera::Vector::operator-
constexpr Vector< T, Rows > operator-() const
Negate a Vector by negating both all of its coordinates.
Definition vector.h:66
libcamera::Vector::operator[]
const T & operator[](size_t i) const
Index to an element in the vector.
Definition vector.h:54
libcamera::Vector::z
constexpr const T & z() const
Convenience function to access the third element of the vector.
Definition vector.h:193
libcamera::Vector::Vector
constexpr Vector(T scalar)
Construct a vector filled with a scalar value.
Definition vector.h:39
libcamera::Vector::min
constexpr Vector min(T scalar) const
Calculate the minimum of this vector and scalar element-wise.
Definition vector.h:159
libcamera::Vector::max
constexpr Vector max(const Vector &other) const
Calculate the maximum of this vector and other element-wise.
Definition vector.h:164
libcamera::Vector::operator-=
Vector & operator-=(T scalar)
Subtract scalar element-wise from this vector.
Definition vector.h:129
libcamera::Vector::operator/=
Vector & operator/=(T scalar)
Divide this vector by scalar element-wise.
Definition vector.h:149
libcamera::Vector::operator/=
Vector & operator/=(const Vector &other)
Divide this vector by other element-wise.
Definition vector.h:144
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:197
libcamera::Vector::operator*
constexpr Vector operator*(const Vector &other) const
Calculate the product of this vector and other element-wise.
Definition vector.h:94
libcamera::Vector::y
constexpr T & y()
Convenience function to access the second element of the vector.
Definition vector.h:201
libcamera::Vector::sum
constexpr R sum() const
Calculate the sum of all the vector elements.
Definition vector.h:246
libcamera::Vector::x
constexpr const T & x() const
Convenience function to access the first element of the vector.
Definition vector.h:185
libcamera::Vector::operator/
constexpr Vector operator/(T scalar) const
Calculate the quotient of this vector and scalar element-wise.
Definition vector.h:109
libcamera::Vector::operator+
constexpr Vector operator+(T scalar) const
Calculate the sum of this vector and scalar element-wise.
Definition vector.h:79
libcamera::Vector::r
constexpr const T & r() const
Convenience function to access the first element of the vector.
Definition vector.h:210
libcamera::Vector::operator*=
Vector & operator*=(T scalar)
Multiply this vector by scalar element-wise.
Definition vector.h:139
libcamera::Vector::max
constexpr Vector max(T scalar) const
Calculate the maximum of this vector and scalar element-wise.
Definition vector.h:169
libcamera::Vector::operator-
constexpr Vector operator-(T scalar) const
Calculate the difference of this vector and scalar element-wise.
Definition vector.h:89
libcamera::Vector::operator-
constexpr Vector operator-(const Vector &other) const
Calculate the difference of this vector and other element-wise.
Definition vector.h:84
libcamera::Vector::operator-=
Vector & operator-=(const Vector &other)
Subtract other element-wise from this vector.
Definition vector.h:124
libcamera::Vector::operator+=
Vector & operator+=(T scalar)
Add scalar element-wise to this vector.
Definition vector.h:119
libcamera::Vector::Vector
constexpr Vector(const Span< const T, Rows > data)
Construct vector from supplied data.
Definition vector.h:49
libcamera::Vector::operator*=
Vector & operator*=(const Vector &other)
Multiply this vector by other element-wise.
Definition vector.h:134
libcamera::Vector::operator*
constexpr Vector operator*(T scalar) const
Calculate the product of this vector and scalar element-wise.
Definition vector.h:99
libcamera::Vector::g
constexpr const T & g() const
Convenience function to access the second element of the vector.
Definition vector.h:214
libcamera::Vector::dot
constexpr T dot(const Vector< T, Rows > &other) const
Compute the dot product.
Definition vector.h:174
libcamera::Vector::operator[]
T & operator[](size_t i)
Index to an element in the vector.
Definition vector.h:60
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:133
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:93
libcamera::operator*
Matrix< U, Rows, Cols > operator*(T d, const Matrix< U, Rows, Cols > &m)
Multiply the matrix by a scalar.
Definition matrix.h:133
libcamera::RGB
Vector< T, 3 > RGB
A Vector of 3 elements representing an RGB pixel value.
Definition vector.h:297
value_node.h
Data structure to manage tree of values.