29#include <boost/qvm/deduce_vec.hpp>
30#include <boost/qvm/vec_traits.hpp>
40#include <initializer_list>
49template <
typename T, std::
size_t N>
class Vector :
public Array<T, N> {
55 using Array<T, N>::operator[];
75 constexpr void copy_init(T
const *first, T
const *last)
noexcept {
77 while (first != last) {
83 template <
class Range>
84 explicit constexpr Vector(Range
const &rng)
86 explicit constexpr Vector(T
const (&v)[N]) noexcept :
Base() {
87 copy_init(std::begin(v), std::end(v));
92 throw std::length_error(
93 "Construction of Vector from Container of wrong length.");
96 copy_init(v.begin(), v.end());
99 template <
typename InputIterator>
101 if (std::distance(first, last) == N) {
102 std::copy_n(first, N,
begin());
104 throw std::length_error(
105 "Construction of Vector from Container of wrong length.");
113 for (std::size_t i = 0u; i != N; ++i) {
124 return std::span<T, N>(
const_cast<T *
>(
begin()),
size());
127 constexpr operator std::span<T, N>()
const {
return as_span(); }
133 [](
auto const &e) { return static_cast<U>(e); });
138 T
norm2()
const {
return (*
this) * (*this); }
149 auto const l =
norm();
151 for (std::size_t i = 0u; i < N; ++i)
152 this->
operator[](i) /= l;
177template <std::
size_t N,
typename T,
typename U,
typename Op>
181 using R =
decltype(op(declval<T>(), declval<U>()));
184 std::transform(std::begin(a), std::end(a), std::begin(b), std::begin(ret),
190template <std::
size_t N,
typename T,
typename Op>
192 std::transform(std::begin(a), std::end(a), std::begin(b), std::begin(a), op);
196template <std::
size_t N,
typename T,
typename Op>
198 for (
unsigned int i = 0; i < N; i++) {
200 if (!
static_cast<bool>(op(a[i], b[i]))) {
209template <std::
size_t N,
typename T>
211 return detail::all_of(a, b, std::less<T>());
214template <std::
size_t N,
typename T>
216 return detail::all_of(a, b, std::greater<T>());
219template <std::
size_t N,
typename T>
221 return detail::all_of(a, b, std::less_equal<T>());
224template <std::
size_t N,
typename T>
226 return detail::all_of(a, b, std::greater_equal<T>());
229template <std::
size_t N,
typename T>
231 return detail::all_of(a, b, std::equal_to<T>());
234template <std::
size_t N,
typename T>
239template <std::
size_t N,
typename T,
typename U>
241 return detail::binary_op(a, b, std::plus<>());
244template <std::
size_t N,
typename T>
246 return detail::binary_op_assign(a, b, std::plus<T>());
249template <std::
size_t N,
typename T,
typename U>
251 return detail::binary_op(a, b, std::minus<>());
254template <std::
size_t N,
typename T>
258 std::transform(std::begin(a), std::end(a), std::begin(ret), std::negate<T>());
263template <std::
size_t N,
typename T>
265 return detail::binary_op_assign(a, b, std::minus<T>());
269template <std::size_t N,
typename T,
class U,
270 std::enable_if_t<std::is_arithmetic_v<U>,
bool> =
true>
272 using R =
decltype(a * std::declval<T>());
275 std::transform(std::begin(b), std::end(b), std::begin(ret),
276 [a](T
const &val) {
return a * val; });
281template <std::size_t N,
typename T,
class U,
282 std::enable_if_t<std::is_arithmetic_v<U>,
bool> =
true>
284 using R =
decltype(std::declval<T>() * a);
287 std::transform(std::begin(b), std::end(b), std::begin(ret),
288 [a](T
const &val) {
return a * val; });
293template <std::
size_t N,
typename T>
295 std::transform(std::begin(b), std::end(b), std::begin(b),
296 [a](T
const &val) {
return a * val; });
301template <std::
size_t N,
typename T>
305 std::transform(std::begin(a), std::end(a), ret.
begin(),
306 [b](T
const &val) { return val / b; });
310template <std::
size_t N,
typename T>
314 std::transform(std::begin(b), std::end(b), ret.
begin(),
315 [a](T
const &val) { return a / val; });
319template <std::
size_t N,
typename T>
321 std::transform(std::begin(a), std::end(a), std::begin(a),
322 [b](T
const &val) {
return val / b; });
327template <
class T>
struct is_vector : std::false_type {};
328template <
class T, std::
size_t N>
329struct is_vector<Vector<T, N>> : std::true_type {};
333template <std::size_t N,
typename T,
class U,
334 class = std::enable_if_t<not(detail::is_vector<T>::value or
335 detail::is_vector<U>::value)>>
338 using R =
decltype(declval<T>() * declval<U>());
340 return std::inner_product(std::begin(a), std::end(a), std::begin(b), R{});
344 std::size_t N,
typename T,
class U,
345 class = std::enable_if_t<std::is_integral_v<T> and std::is_integral_v<U>>>
348 using R =
decltype(declval<T>() % declval<U>());
351 std::transform(std::begin(a), std::end(a), std::begin(b), std::begin(ret),
352 [](T
const &ai, U
const &bi) {
return ai % bi; });
362 std::transform(std::begin(a), std::end(a), ret.
begin(),
363 [](T
const &v) { return sqrt(v); });
370 return {a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2],
371 a[0] * b[1] - a[1] * b[0]};
376 return std::accumulate(v.
cbegin(), v.
cend(), T{1}, std::multiplies<T>());
379template <
class T,
class U, std::
size_t N>
382 using R =
decltype(declval<T>() * declval<U>());
386 [](
auto const &ai,
auto const &bi) { return ai * bi; });
393template <
class T,
class U, std::size_t N,
394 class = std::enable_if_t<not(detail::is_vector<T>::value)>>
397 using R =
decltype(declval<T>() * declval<U>());
404template <
class T,
class U, std::size_t N,
405 class = std::enable_if_t<not(detail::is_vector<U>::value)>>
408 using R =
decltype(declval<T>() * declval<U>());
415template <
typename T,
typename U,
416 class = std::enable_if_t<not(detail::is_vector<T>::value or
417 detail::is_vector<U>::value)>>
422template <
class T,
class U, std::
size_t N>
425 using R =
decltype(declval<T>() * declval<U>());
429 [](
auto const &ai,
auto const &bi) { return ai / bi; });
436template <
class T,
class U, std::size_t N,
437 class = std::enable_if_t<not(detail::is_vector<U>::value)>>
440 using R =
decltype(declval<T>() * declval<U>());
447template <
class T,
class U, std::size_t N,
448 class = std::enable_if_t<not(detail::is_vector<T>::value)>>
451 using R =
decltype(declval<T>() * declval<U>());
454 std::transform(std::begin(b), std::end(b), ret.
begin(),
455 [a](T
const &bi) { return a / bi; });
459template <
typename T,
typename U,
460 class = std::enable_if_t<not(detail::is_vector<T>::value or
461 detail::is_vector<U>::value)>>
468 return {T{1}, T{0}, T{0}};
470 return {T{0}, T{1}, T{0}};
472 return {T{0}, T{0}, T{1}};
473 throw std::domain_error(
"coordinate out of range");
488template <std::
size_t I,
class T, std::
size_t N>
489typename std::tuple_element<I, Vector<T, N>>::type &
494template <std::
size_t I,
class T, std::
size_t N>
495const typename std::tuple_element<I, Vector<T, N>>::type &
502template <std::
size_t I,
class T, std::
size_t N>
503struct std::tuple_element<I,
Utils::Vector<T, N>> {
504 static_assert(I < N,
"Utils::Vector index must be in range");
505 using type =
typename std::enable_if_t<(I < N), T>;
508template <
class T, std::
size_t N>
509struct std::tuple_size<
Utils::Vector<T, N>>
510 : std::integral_constant<std::size_t, N> {};
517 static constexpr std::size_t dim = N;
520 template <std::
size_t I>
525 template <std::
size_t I>
526 static constexpr inline scalar_type
541template <
typename T>
struct deduce_vec<
Utils::Vector<T, 3>, 3> {
Array implementation with CUDA support.
#define UTILS_ARRAY_BOOST_MPI_T(Container, N)
Mark array types as MPI data types.
#define UTILS_ARRAY_BOOST_BIT_S(Container, N)
Mark array types as MPI bitwise serializable.
#define UTILS_ARRAY_BOOST_CLASS(Container, N, ImplementationLevel)
Redefinition of BOOST_CLASS_IMPLEMENTATION for array types.
#define UTILS_ARRAY_BOOST_TRACK(Container, N, TrackingLevel)
Redefinition of BOOST_CLASS_TRACKING for array types.
Vector() noexcept=default
constexpr Vector(T const (&v)[N]) noexcept
constexpr Vector(Range const &rng)
Vector normalized() const
std::vector< T > as_vector() const
Vector(InputIterator first, InputIterator last)
constexpr Vector(std::initializer_list< T > v)
constexpr std::span< T, N > as_span() const
static DEVICE_QUALIFIER constexpr Vector< T, N > broadcast(typename Base::value_type const &value) noexcept
Create a vector that has all entries set to the same value.
auto operator+(Vector< T, N > const &a, Vector< U, N > const &b)
Vector< T, 3 > unit_vector(unsigned int i)
T product(Vector< T, N > const &v)
Vector< T, N > & operator-=(Vector< T, N > &a, Vector< T, N > const &b)
Vector< T, N > & operator/=(Vector< T, N > &a, T const &b)
Vector< T, N > & operator+=(Vector< T, N > &a, Vector< T, N > const &b)
constexpr bool operator<(Vector< T, N > const &a, Vector< T, N > const &b)
constexpr bool operator>=(Vector< T, N > const &a, Vector< T, N > const &b)
constexpr bool operator>(Vector< T, N > const &a, Vector< T, N > const &b)
Vector< T, 3 > vector_product(Vector< T, 3 > const &a, Vector< T, 3 > const &b)
Vector< T, N > operator/(Vector< T, N > const &a, T const &b)
Quaternion< T > operator*(const U &b, const Quaternion< T > &a)
Product quaternion and arithmetic type.
constexpr bool operator==(Vector< T, N > const &a, Vector< T, N > const &b)
constexpr bool operator!=(Vector< T, N > const &a, Vector< T, N > const &b)
Vector< T, N > sqrt(Vector< T, N > const &a)
std::tuple_element< I, Array< T, N > >::type & get(Array< T, N > &a) noexcept
constexpr bool operator<=(Vector< T, N > const &a, Vector< T, N > const &b)
auto operator%(Vector< T, N > const &a, Vector< U, N > const &b)
auto hadamard_division(Vector< T, N > const &a, Vector< U, N > const &b)
auto hadamard_product(Vector< T, N > const &a, Vector< U, N > const &b)
Vector< T, N > & operator*=(Vector< T, N > &b, T const &a)
auto operator-(Vector< T, N > const &a, Vector< U, N > const &b)
DEVICE_QUALIFIER constexpr reference at(size_type i)
DEVICE_QUALIFIER constexpr bool empty() const noexcept
DEVICE_QUALIFIER constexpr reference back()
DEVICE_QUALIFIER constexpr pointer data() noexcept
DEVICE_QUALIFIER constexpr size_type max_size() const noexcept
DEVICE_QUALIFIER constexpr iterator begin() noexcept
DEVICE_QUALIFIER constexpr const_iterator cbegin() const noexcept
DEVICE_QUALIFIER constexpr const_iterator cend() const noexcept
DEVICE_QUALIFIER constexpr size_type size() const noexcept
DEVICE_QUALIFIER constexpr reference front()
DEVICE_QUALIFIER constexpr iterator end() noexcept
DEVICE_QUALIFIER void fill(const value_type &value)
Meta function to turns a Vector<1, T> into T.
typename Utils::Vector< T, 3 > type
static constexpr scalar_type read_element(::Utils::Vector< T, N > const &v)
static scalar_type & write_element_idx(std::size_t i, ::Utils::Vector< T, N > &v)
static constexpr scalar_type & write_element(::Utils::Vector< T, N > &v)
static scalar_type read_element_idx(std::size_t i, ::Utils::Vector< T, N > const &v)
typename std::enable_if_t<(I< N), T > type