12 #include <immintrin.h>
14 #include <smmintrin.h>
32 static constexpr
bool value =
false;
40 static constexpr
bool value =
true;
47 static_assert(!IsVector<float>,
"static test failed");
70 : data(_mm_set1_ps(float(f))) {}
74 : data(_mm_set_ps(h, z, y, x)) {}
83 return *(
reinterpret_cast<const float*
>(&data) + i);
89 return *(
reinterpret_cast<float*
>(&data) + i);
95 static_assert(
unsigned(i) < 4,
"Invalid index");
96 return *(
reinterpret_cast<const float*
>(&data) + i);
102 static_assert(
unsigned(i) < 4,
"Invalid index");
103 return *(
reinterpret_cast<float*
>(&data) + i);
118 data = _mm_add_ps(data, v.data);
123 data = _mm_sub_ps(data, v.data);
128 data = _mm_mul_ps(data, _mm_set1_ps(f));
133 data = _mm_div_ps(data, _mm_set1_ps(f));
138 data = _mm_mul_ps(data, v.data);
143 data = _mm_div_ps(data, v.data);
148 return _mm_xor_ps(v.data, _mm_set1_ps(-0.f));
161 return BasicVector(_mm_mul_ps(v.data, _mm_set1_ps(f)));
165 return BasicVector(_mm_mul_ps(v.data, _mm_set1_ps(f)));
174 return BasicVector(_mm_div_ps(v.data, _mm_set1_ps(f)));
184 const int mask = (1 << d) - 0x01;
185 return (_mm_movemask_ps(_mm_cmpeq_ps(v1.data, v2.data)) & mask) == mask;
193 constexpr
int digits = 6;
194 stream << std::setprecision(digits);
195 for (
int i = 0; i < 3; ++i) {
196 stream << std::setw(20) << v[i];
207 #ifdef SPH_VECTOR_AVX
222 : data(_mm256_set1_pd(f)) {}
225 INLINE BasicVector(
const double x,
const double y,
const double z = 0.,
const double h = 0.)
226 : data(_mm256_set_pd(h, z, y, x)) {}
233 INLINE const double& operator[](
const int i)
const {
235 return *(
reinterpret_cast<const double*
>(&data) + i);
239 INLINE double& operator[](
const int i) {
241 return *(
reinterpret_cast<double*
>(&data) + i);
246 INLINE const double& get()
const {
247 static_assert(
unsigned(i) < 4,
"Invalid index");
248 return *(
reinterpret_cast<const double*
>(&data) + i);
254 static_assert(
unsigned(i) < 4,
"Invalid index");
255 return *(
reinterpret_cast<double*
>(&data) + i);
265 data = _mm256_add_pd(data, v.data);
270 data = _mm256_sub_pd(data, v.data);
275 data = _mm256_mul_pd(data, _mm256_set1_pd(f));
280 data = _mm256_div_pd(data, _mm256_set1_pd(f));
285 data = _mm256_mul_pd(data, v.data);
290 data = _mm256_div_pd(data, v.data);
295 return _mm256_xor_pd(v.data, _mm256_set1_pd(-0.));
299 return BasicVector(_mm256_add_pd(v1.data, v2.data));
303 return BasicVector(_mm256_sub_pd(v1.data, v2.data));
308 return BasicVector(_mm256_mul_pd(v.data, _mm256_set1_pd(f)));
312 return BasicVector(_mm256_mul_pd(v.data, _mm256_set1_pd(f)));
316 return BasicVector(_mm256_mul_pd(v1.data, v2.data));
321 return BasicVector(_mm256_div_pd(v.data, _mm256_set1_pd(f)));
325 return BasicVector(_mm256_div_pd(v1.data, v2.data));
331 return v1[
X] == v2[
X] && v1[
Y] == v2[
Y] && v1[
Z] == v2[
Z];
340 return (*
this)[
X] * other[
X] + (*this)[
Y] * other[
Y] + (*this)[
Z] * other[
Z];
345 return BasicVector(_mm256_min_pd(data, other.data));
350 return BasicVector(_mm256_max_pd(data, other.data));
353 INLINE const __m256d& sse()
const {
359 stream << std::setprecision(digits);
360 for (
int i = 0; i < 3; ++i) {
361 stream << std::setw(20) << v[i];
380 : data{ data1, data2 } {}
384 : data{ _mm_set1_pd(f), _mm_set1_pd(f) } {}
388 : data{ _mm_set_pd(y, x), _mm_set_pd(h, z) } {}
392 : data{ v.data[0], v.data[1] } {}
397 return *(
reinterpret_cast<const double*
>(&data) + i);
403 return *(
reinterpret_cast<double*
>(&data) + i);
409 static_assert(
unsigned(i) < 4,
"Invalid index");
410 return *(
reinterpret_cast<const double*
>(&data) + i);
416 static_assert(
unsigned(i) < 4,
"Invalid index");
417 return *(
reinterpret_cast<double*
>(&data) + i);
422 static_assert(
unsigned(i) < 2,
"Invalid index");
434 data[0] = _mm_add_pd(data[0], v.data[0]);
435 data[1] = _mm_add_pd(data[1], v.data[1]);
440 data[0] = _mm_sub_pd(data[0], v.data[0]);
441 data[1] = _mm_sub_pd(data[1], v.data[1]);
446 const __m128d value = _mm_set1_pd(f);
447 data[0] = _mm_mul_pd(data[0], value);
448 data[1] = _mm_mul_pd(data[1], value);
453 const __m128d value = _mm_set1_pd(f);
454 data[0] = _mm_div_pd(data[0], value);
455 data[1] = _mm_div_pd(data[1], value);
460 data[0] = _mm_mul_pd(data[0], v.data[0]);
461 data[1] = _mm_mul_pd(data[1], v.data[1]);
466 data[0] = _mm_div_pd(data[0], v.data[0]);
467 data[1] = _mm_div_pd(data[1], v.data[1]);
472 const __m128d value = _mm_set1_pd(-0.);
473 return { _mm_xor_pd(v.data[0], value), _mm_xor_pd(v.data[1], value) };
477 return BasicVector(_mm_add_pd(v1.data[0], v2.data[0]), _mm_add_pd(v1.data[1], v2.data[1]));
481 return BasicVector(_mm_sub_pd(v1.data[0], v2.data[0]), _mm_sub_pd(v1.data[1], v2.data[1]));
486 const __m128d value = _mm_set1_pd(f);
487 return BasicVector(_mm_mul_pd(v.data[0], value), _mm_mul_pd(v.data[1], value));
491 const __m128d value = _mm_set1_pd(f);
492 return BasicVector(_mm_mul_pd(v.data[0], value), _mm_mul_pd(v.data[1], value));
496 return BasicVector(_mm_mul_pd(v1.data[0], v2.data[0]), _mm_mul_pd(v1.data[1], v2.data[1]));
501 const __m128d value = _mm_set1_pd(f);
502 return BasicVector(_mm_div_pd(v.data[0], value), _mm_div_pd(v.data[1], value));
506 return BasicVector(_mm_div_pd(v1.data[0], v2.data[0]), _mm_div_pd(v1.data[1], v2.data[1]));
512 const int r1 = _mm_movemask_pd(_mm_cmpeq_pd(v1.data[0], v2.data[0]));
513 const int r2 = _mm_movemask_pd(_mm_cmpeq_pd(v1.data[1], v2.data[1]));
514 const int mask1 = (1 << 2) - 0x01;
515 const int mask2 = (1 << (d - 2)) - 0x01;
516 return (r1 & mask1) == mask1 && (r2 & mask2) == mask2;
526 stream << std::setprecision(digits);
527 for (
int i = 0; i < 3; ++i) {
528 stream << std::setw(20) << v[i];
542 static_assert(std::is_trivially_default_constructible<Vector>::value,
"must be trivially construtible");
543 static_assert(std::is_trivially_destructible<Vector>::value,
"must be trivially destructible");
550 return _mm_cvtss_f32(_mm_dp_ps(v1.
sse(), v2.
sse(), (1 << (d + 4)) - 0x0F));
555 return v1[
X] * v2[
X] + v1[
Y] * v2[
Y] + v1[
Z] * v2[
Z];
560 return _mm_sub_ps(_mm_mul_ps(_mm_shuffle_ps(v1.
sse(), v1.
sse(), _MM_SHUFFLE(3, 0, 2, 1)),
561 _mm_shuffle_ps(v2.
sse(), v2.
sse(), _MM_SHUFFLE(3, 1, 0, 2))),
562 _mm_mul_ps(_mm_shuffle_ps(v1.
sse(), v1.
sse(), _MM_SHUFFLE(3, 1, 0, 2)),
563 _mm_shuffle_ps(v2.
sse(), v2.
sse(), _MM_SHUFFLE(3, 0, 2, 1))));
569 v1[
Y] * v2[
Z] - v1[
Z] * v2[
Y], v1[
Z] * v2[
X] - v1[
X] * v2[
Z], v1[
X] * v2[
Y] - v1[
Y] * v2[
X]);
600 return { v / length, length };
607 return _mm_min_ps(v1.
sse(), v2.
sse());
613 return _mm_max_ps(v1.
sse(), v2.
sse());
616 #ifdef SPH_VECTOR_AVX
628 return { _mm_min_pd(v1.
sse<0>(), v2.
sse<0>()), _mm_min_pd(v1.
sse<1>(), v2.
sse<1>()) };
633 return { _mm_max_pd(v1.
sse<0>(), v2.
sse<0>()), _mm_max_pd(v1.
sse<1>(), v2.
sse<1>()) };
641 return max(v1,
min(v, v2));
675 return min(v[0], v[1], v[2]);
681 return max(v[0], v[1], v[2]);
687 if (v[1] < v[minIdx]) {
690 if (v[2] < v[minIdx]) {
699 if (v[1] > v[maxIdx]) {
702 if (v[2] > v[maxIdx]) {
714 #ifdef SPH_VECTOR_AVX
724 _mm_andnot_pd(_mm_set1_pd(-0.), v.
sse<0>()), _mm_andnot_pd(_mm_set1_pd(-0.), v.
sse<1>()));
731 return absV[
X] + absV[
Y] + absV[
Z];
761 return { v[
X], v[
Y], v[
Z] };
767 template <
typename T1,
typename T2>
810 return { r, theta, phi };
821 const Vector diff = v - center;
836 }
else if (v1[
Z] > v2[
Z]) {
838 }
else if (v1[
Y] < v2[
Y]) {
840 }
else if (v1[
Y] > v2[
Y]) {
842 }
else if (v1[
X] < v2[
X]) {
#define SPH_ASSERT(x,...)
bool operator==(const AutoPtr< T > &ptr, std::nullptr_t)
bool operator!=(const AutoPtr< T > &ptr, std::nullptr_t)
Function for generic manipulation with geometric types.
Global parameters of the code.
uint32_t Size
Integral type used to index arrays (by default).
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
constexpr int PRECISION
Number of valid digits of numbers on output.
Object representing interval of real values.
Lut< TValue, TScalar > operator/(const Lut< TValue, TScalar > &lut1, const Lut< TValue, TScalar > &lut2)
INLINE T sqrtApprox(const T f)
Returns an approximative value of square root.
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
INLINE T sqrt(const T f)
Return a squared root of a value.
INLINE T atan2(const T y, const T x)
#define INLINE
Macros for conditional compilation based on selected compiler.
#define NAMESPACE_SPH_END
std::ostream & operator<<(std::ostream &stream, const Path &path)
Re-implementation of std::tuple with some additional functionality.
INLINE Vector cylindricalToCartesian(const Float r, const Float phi, const Float z)
Constructs a vector from cylindrical coordinates.
INLINE Size argMax(const Vector &v)
Returns the index of the maximum element.
INLINE SphericalCoords cartensianToSpherical(const Vector &v)
Converts vector in cartesian coordinates to spherical coordinates.
INLINE Vector clamp(const Vector &v, const Vector &v1, const Vector &v2)
Component-wise clamping.
INLINE Float norm(const Vector &v)
Returns norm of a vector, i.e. its (approximative) length.
INLINE Float minElement(const Vector &v)
Returns minimum element of a vector. Considers only the first 3 component, 4th one is ignored.
INLINE auto abs(const BasicVector< float > &v)
Computes vector of absolute values.
INLINE bool isReal(const BasicVector< float > &v)
Computes vector of inverse squared roots.
INLINE auto less(const Vector &v1, const Vector &v2)
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
INLINE Float distance(const Vector &r, const Vector &axis)
Returns the distance of vector from given axis. The axis is assumed to be normalized.
INLINE bool almostEqual(const Vector &v1, const Vector &v2, const Float eps=EPS)
Checks if two vectors are equal to some given accuracy.
INLINE Float getLengthApprox(const Vector &v)
Returns approximate value of the length. Enabled only for vectors of floating-point precision.
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
INLINE Float normSqr(const Vector &v)
Returns squared length of a vector.
INLINE BasicVector< float > min(const BasicVector< float > &v1, const BasicVector< float > &v2)
Component-wise minimum.
INLINE BasicVector< T1 > vectorCast(const BasicVector< T2 > &v)
INLINE Vector cos(const Vector &v)
Cosine applied to all components of the vector.
INLINE bool lexicographicalLess(const Vector &v1, const Vector &v2)
Compares components of two vectors lexicographically, primary component is z.
INLINE Float getSqrLength(const Vector &v)
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
BasicVector< Float > Vector
INLINE Float maxElement(const Vector &v)
Returns maximum element of a vector. Considers only the first 3 component, 4th one is ignored.
INLINE float dot(const BasicVector< float > &v1, const BasicVector< float > &v2)
Make sure the vector is trivially constructible and destructible, needed for fast initialization of a...
INLINE BasicVector< float > max(const BasicVector< float > &v1, const BasicVector< float > &v2)
Component-wise maximum.
INLINE Vector sphericalToCartesian(const Float r, const Float theta, const Float phi)
Constructs a vector from spherical coordinates.
INLINE Vector getNormalized(const Vector &v)
INLINE Size argMin(const Vector &v)
Returns the index of the minimum element.
INLINE StaticArray< Float, 6 > getComponents< Vector >(const Vector &v)
INLINE Float l1Norm(const Vector &v)
Returns the L1 norm (sum of absolute values) of the vector.
Coordinate
Components of the 4D vector.
INLINE Vector sphericalInversion(const Vector &v, const Vector ¢er, const Float radius)
specialization for doubles or units of double precision
INLINE BasicVector & operator+=(const BasicVector &v)
INLINE BasicVector(const BasicVector &v)
Copy constructor.
INLINE BasicVector & operator=(const BasicVector &v)
Copy operator.
INLINE BasicVector & operator*=(const double f)
INLINE const __m128d & sse() const
INLINE friend BasicVector operator-(const BasicVector &v)
INLINE friend bool operator!=(const BasicVector &v1, const BasicVector &v2)
INLINE BasicVector & operator*=(const BasicVector &v)
INLINE BasicVector(const double f)
Constructs by copying a value to all vector components.
INLINE BasicVector()=default
INLINE friend BasicVector operator+(const BasicVector &v1, const BasicVector &v2)
INLINE friend auto operator/(const BasicVector &v, const double f)
INLINE BasicVector(const double x, const double y, const double z, const double h=0.)
Constructs the vector from given components.
INLINE double & get()
Get component by given compile-time constant index.
INLINE friend BasicVector operator-(const BasicVector &v1, const BasicVector &v2)
INLINE BasicVector(const __m128d data1, const __m128d data2)
Constructs from two SSE vectors.
INLINE const double & operator[](const int i) const
Get component by given index.
INLINE friend auto operator*(const BasicVector &v, const double f)
Multiplication of vector by a value or unit.
INLINE friend bool operator==(const BasicVector &v1, const BasicVector &v2)
Comparison operator, only compares first three components of vectors.
INLINE BasicVector & operator/=(const BasicVector &v)
INLINE friend auto operator/(const BasicVector &v1, const BasicVector &v2)
INLINE const double & get() const
Get component by given compile-time constant index.
INLINE BasicVector & operator/=(const double f)
INLINE BasicVector & operator-=(const BasicVector &v)
INLINE friend auto operator*(const double f, const BasicVector &v)
friend std::ostream & operator<<(std::ostream &stream, const BasicVector &v)
Output to stream.
INLINE double & operator[](const int i)
Get component by given index.
INLINE friend auto operator*(const BasicVector &v1, const BasicVector &v2)
3-dimensional vector, float precision
INLINE BasicVector & operator*=(const float f)
INLINE friend auto operator*(const BasicVector &v, const float f)
Multiplication of vector by a value or unit.
INLINE const float & operator[](const int i) const
Get component by given index.
INLINE BasicVector & operator*=(const BasicVector &v)
INLINE friend BasicVector operator-(const BasicVector &v)
INLINE friend bool operator!=(const BasicVector &v1, const BasicVector &v2)
INLINE friend auto operator*(const float f, const BasicVector &v)
INLINE BasicVector & operator/=(const float f)
INLINE friend BasicVector operator+(const BasicVector &v1, const BasicVector &v2)
INLINE BasicVector & operator+=(const BasicVector &v)
INLINE BasicVector(const float x, const float y, const float z, const float h=0.f)
Constructs the vector from given components.
INLINE BasicVector & operator-=(const BasicVector &v)
INLINE BasicVector & operator=(const BasicVector &v)
Copy operator.
INLINE float & operator[](const int i)
Get component by given index.
INLINE friend BasicVector operator-(const BasicVector &v1, const BasicVector &v2)
INLINE friend auto operator/(const BasicVector &v, const float f)
INLINE BasicVector(const float f)
Constructs by copying a value to all vector components.
INLINE const __m128 & sse() const
Returns the data as SSE vector.
INLINE BasicVector & operator/=(const BasicVector &v)
INLINE friend bool operator==(const BasicVector &v1, const BasicVector &v2)
Comparison operator, only compares first three components of vectors.
INLINE const float & get() const
Get component by given compile-time constant index.
INLINE friend auto operator/(const BasicVector &v1, const BasicVector &v2)
INLINE BasicVector(const BasicVector &v)
Copy constructor.
INLINE BasicVector()=default
INLINE float & get()
Get component by given compile-time constant index.
friend std::ostream & operator<<(std::ostream &stream, const BasicVector &v)
INLINE BasicVector(const __m128 data)
Constructs from SSE vector.
INLINE friend auto operator*(const BasicVector &v1, const BasicVector &v2)
Object representing a 1D interval of real numbers.
INLINE Float clamp(const Float &value) const
Clamps the given value by the interval.
Array with fixed number of allocated elements.
Heterogeneous container capable of storing a fixed number of values.
Difference< TValue1, TValue2 > operator-(const TValue1 &v1, const TValue2 &v2)
MultiplyByScalar< TValue > operator*(const TValue &v, const Float f)
Sum< TValue1, TValue2 > operator+(const TValue1 &v1, const TValue2 &v2)
Helper type trait to determine if the type is a vector of some kind.
static constexpr bool value