Select Git revision
TinyVector.hpp
-
Stéphane Del Pino authoredStéphane Del Pino authored
TinyVector.hpp 4.92 KiB
#ifndef TINY_VECTOR_HPP
#define TINY_VECTOR_HPP
#include <iostream>
#include <PastisAssert.hpp>
#include <Kokkos_Core.hpp>
#include <Types.hpp>
template <size_t N, typename T=double>
class TinyVector
{
private:
T m_values[N];
static_assert((N>0),"TinyVector size must be strictly positive");
void _unpackVariadicInput(const T& t)
{
m_values[N-1] = t;
}
template <typename... Args>
void _unpackVariadicInput(const T& t, Args&&... args)
{
m_values[N-1-sizeof...(args)] = t;
this->_unpackVariadicInput(args...);
}
public:
KOKKOS_INLINE_FUNCTION
TinyVector operator-() const
{
TinyVector opposed;
for (size_t i=0; i<N; ++i) {
opposed.m_values[i] =-m_values[i];
}
return std::move(opposed);
}
KOKKOS_INLINE_FUNCTION
constexpr size_t dimension() const
{
return N;
}
KOKKOS_INLINE_FUNCTION
bool operator==(const TinyVector& v) const
{
for (size_t i=0; i<N; ++i) {
if (m_values[i] != v.m_values[i]) return false;
}
return true;
}
KOKKOS_INLINE_FUNCTION
bool operator!=(const TinyVector& v) const
{
return not this->operator==(v);
}
KOKKOS_INLINE_FUNCTION
T operator,(const TinyVector& v) const
{
T t = m_values[0]*v.m_values[0];
for (size_t i=1; i<N; ++i) {
t += m_values[i]*v.m_values[i];
}
return std::move(t);
}
KOKKOS_INLINE_FUNCTION
TinyVector& operator*=(const T& t)
{
for (size_t i=0; i<N; ++i) {
m_values[i] *= t;
}
return *this;
}
KOKKOS_INLINE_FUNCTION
friend TinyVector operator*(const T& t, const TinyVector& v)
{
TinyVector tv;
for (size_t i=0; i<N; ++i) {
tv.m_values[i] = t * v.m_values[i];
}
return std::move(tv);
}
KOKKOS_INLINE_FUNCTION
friend TinyVector operator*(const T& t, TinyVector&& v)
{
v *= t;
return std::move(v);
}
KOKKOS_INLINE_FUNCTION
friend std::ostream& operator<<(std::ostream& os, const TinyVector& v)
{
os << '(' << v.m_values[0];
for (size_t i=1; i<N; ++i) {
os << ',' << v.m_values[i];
}
os << ')';
return os;
}
KOKKOS_INLINE_FUNCTION
TinyVector operator+(const TinyVector& v) const
{
TinyVector sum;
for (size_t i=0; i<N; ++i) {
sum.m_values[i] = m_values[i]+v.m_values[i];
}
return std::move(sum);
}
KOKKOS_INLINE_FUNCTION
TinyVector operator+(TinyVector&& v) const
{
for (size_t i=0; i<N; ++i) {
v.m_values[i] += m_values[i];
}
return std::move(v);
}
KOKKOS_INLINE_FUNCTION
TinyVector operator-(const TinyVector& v) const
{
TinyVector difference;
for (size_t i=0; i<N; ++i) {
difference.m_values[i] = m_values[i]-v.m_values[i];
}
return std::move(difference);
}
KOKKOS_INLINE_FUNCTION
TinyVector operator-(TinyVector&& v) const
{
for (size_t i=0; i<N; ++i) {
v.m_values[i] = m_values[i]-v.m_values[i];
}
return std::move(v);
}
KOKKOS_INLINE_FUNCTION
TinyVector& operator+=(const TinyVector& v)
{
for (size_t i=0; i<N; ++i) {
m_values[i] += v.m_values[i];
}
return *this;
}
KOKKOS_INLINE_FUNCTION
TinyVector& operator-=(const TinyVector& v)
{
for (size_t i=0; i<N; ++i) {
m_values[i] -= v.m_values[i];
}
return *this;
}
KOKKOS_INLINE_FUNCTION
T& operator[](const size_t& i)
{
Assert(i<N);
return m_values[i];
}
KOKKOS_INLINE_FUNCTION
const T& operator[](const size_t& i) const
{
Assert(i<N);
return m_values[i];
}
KOKKOS_INLINE_FUNCTION
TinyVector& operator=(const ZeroType& z)
{
static_assert(std::is_arithmetic<T>(),"Cannot assign 'zero' value for non-arithmetic types");
for (size_t i=0; i<N; ++i) {
m_values[i] = 0;
}
return *this;
}
KOKKOS_INLINE_FUNCTION
const TinyVector& operator=(const TinyVector& v)
{
for (size_t i=0; i<N; ++i) {
m_values[i] = v.m_values[i];
}
return *this;
}
KOKKOS_INLINE_FUNCTION
TinyVector& operator=(TinyVector&& v) = default;
template <typename... Args>
KOKKOS_INLINE_FUNCTION
TinyVector(const T& t, Args&&... args)
{
static_assert(sizeof...(args)==N-1, "wrong number of parameters");
this->_unpackVariadicInput(t, args...);
}
KOKKOS_INLINE_FUNCTION
TinyVector()
{
;
}
KOKKOS_INLINE_FUNCTION
TinyVector(const ZeroType& z)
{
static_assert(std::is_arithmetic<T>(),"Cannot construct from 'zero' value for non-arithmetic types");
for (size_t i=0; i<N; ++i) {
m_values[i] = 0;
}
}
KOKKOS_INLINE_FUNCTION
TinyVector(const TinyVector& v)
{
for (size_t i=0; i<N; ++i) {
m_values[i] = v.m_values[i];
}
}
KOKKOS_INLINE_FUNCTION
TinyVector(TinyVector&& v) = default;
KOKKOS_INLINE_FUNCTION
~TinyVector()
{
;
}
};
template <size_t N, typename T>
KOKKOS_INLINE_FUNCTION
T l2Norm(const TinyVector<N,T>& x)
{
static_assert(std::is_arithmetic<T>(),"Cannot compute L2 norm for non-arithmetic types");
return std::sqrt((x,x));
}
#endif // TINYVECTOR_HPP