SPH
Vector.h
Go to the documentation of this file.
1 #pragma once
2 
7 
8 #include "common/Globals.h"
12 #include <immintrin.h>
13 #include <iomanip>
14 #include <smmintrin.h>
15 
17 
21 enum Coordinate {
22  X = 0,
23  Y = 1,
24  Z = 2,
25  H = 3,
26 };
27 
28 
30 template <typename T>
31 struct IsVectorType {
32  static constexpr bool value = false;
33 };
34 
35 template <typename T>
37 
38 template <typename T>
40  static constexpr bool value = true;
41 };
42 
43 template <typename T>
45 
46 // test
47 static_assert(!IsVector<float>, "static test failed");
48 static_assert(IsVector<BasicVector<float>>, "Static test failed");
49 
50 
51 template <typename T>
52 class BasicVector;
53 
54 
56 template <>
57 class BasicVector<float> {
58 private:
59  __m128 data;
60 
61 public:
62  INLINE BasicVector() = default;
63 
65  INLINE BasicVector(const __m128 data)
66  : data(data) {}
67 
69  INLINE explicit BasicVector(const float f)
70  : data(_mm_set1_ps(float(f))) {}
71 
73  INLINE BasicVector(const float x, const float y, const float z, const float h = 0.f)
74  : data(_mm_set_ps(h, z, y, x)) {}
75 
78  : data(v.data) {}
79 
81  INLINE const float& operator[](const int i) const {
82  SPH_ASSERT(unsigned(i) < 4);
83  return *(reinterpret_cast<const float*>(&data) + i);
84  }
85 
87  INLINE float& operator[](const int i) {
88  SPH_ASSERT(unsigned(i) < 4);
89  return *(reinterpret_cast<float*>(&data) + i);
90  }
91 
93  template <int i>
94  INLINE const float& get() const {
95  static_assert(unsigned(i) < 4, "Invalid index");
96  return *(reinterpret_cast<const float*>(&data) + i);
97  }
98 
100  template <int i>
101  INLINE float& get() {
102  static_assert(unsigned(i) < 4, "Invalid index");
103  return *(reinterpret_cast<float*>(&data) + i);
104  }
105 
107  INLINE const __m128& sse() const {
108  return data;
109  }
110 
113  data = v.data;
114  return *this;
115  }
116 
118  data = _mm_add_ps(data, v.data);
119  return *this;
120  }
121 
123  data = _mm_sub_ps(data, v.data);
124  return *this;
125  }
126 
127  INLINE BasicVector& operator*=(const float f) {
128  data = _mm_mul_ps(data, _mm_set1_ps(f));
129  return *this;
130  }
131 
132  INLINE BasicVector& operator/=(const float f) {
133  data = _mm_div_ps(data, _mm_set1_ps(f));
134  return *this;
135  }
136 
138  data = _mm_mul_ps(data, v.data);
139  return *this;
140  }
141 
143  data = _mm_div_ps(data, v.data);
144  return *this;
145  }
146 
148  return _mm_xor_ps(v.data, _mm_set1_ps(-0.f));
149  }
150 
151  INLINE friend BasicVector operator+(const BasicVector& v1, const BasicVector& v2) {
152  return BasicVector(_mm_add_ps(v1.data, v2.data));
153  }
154 
155  INLINE friend BasicVector operator-(const BasicVector& v1, const BasicVector& v2) {
156  return BasicVector(_mm_sub_ps(v1.data, v2.data));
157  }
158 
160  INLINE friend auto operator*(const BasicVector& v, const float f) {
161  return BasicVector(_mm_mul_ps(v.data, _mm_set1_ps(f)));
162  }
163 
164  INLINE friend auto operator*(const float f, const BasicVector& v) {
165  return BasicVector(_mm_mul_ps(v.data, _mm_set1_ps(f)));
166  }
167 
168  INLINE friend auto operator*(const BasicVector& v1, const BasicVector& v2) {
169  return BasicVector(_mm_mul_ps(v1.data, v2.data));
170  }
171 
172  INLINE friend auto operator/(const BasicVector& v, const float f) {
173  SPH_ASSERT(f != 0.f);
174  return BasicVector(_mm_div_ps(v.data, _mm_set1_ps(f)));
175  }
176 
177  INLINE friend auto operator/(const BasicVector& v1, const BasicVector& v2) {
178  return BasicVector(_mm_div_ps(v1.data, v2.data));
179  }
180 
182  INLINE friend bool operator==(const BasicVector& v1, const BasicVector& v2) {
183  constexpr int d = 3;
184  const int mask = (1 << d) - 0x01;
185  return (_mm_movemask_ps(_mm_cmpeq_ps(v1.data, v2.data)) & mask) == mask;
186  }
187 
188  INLINE friend bool operator!=(const BasicVector& v1, const BasicVector& v2) {
189  return !(v1 == v2);
190  }
191 
192  friend std::ostream& operator<<(std::ostream& stream, const BasicVector& v) {
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];
197  }
198  return stream;
199  }
200 };
201 
202 
204 
205 // #define SPH_VECTOR_AVX
206 
207 #ifdef SPH_VECTOR_AVX
208 template <>
209 class BasicVector<double> {
210 private:
211  __m256d data;
212 
213 public:
214  INLINE BasicVector() = default;
215 
217  INLINE BasicVector(const __m256d data)
218  : data(data) {}
219 
221  INLINE explicit BasicVector(const double f)
222  : data(_mm256_set1_pd(f)) {}
223 
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)) {}
227 
229  INLINE BasicVector(const BasicVector& v)
230  : data(v.data) {}
231 
233  INLINE const double& operator[](const int i) const {
234  SPH_ASSERT(unsigned(i) < 4);
235  return *(reinterpret_cast<const double*>(&data) + i);
236  }
237 
239  INLINE double& operator[](const int i) {
240  SPH_ASSERT(unsigned(i) < 4);
241  return *(reinterpret_cast<double*>(&data) + i);
242  }
243 
245  template <int i>
246  INLINE const double& get() const {
247  static_assert(unsigned(i) < 4, "Invalid index");
248  return *(reinterpret_cast<const double*>(&data) + i);
249  }
250 
252  template <int i>
253  INLINE double& get() {
254  static_assert(unsigned(i) < 4, "Invalid index");
255  return *(reinterpret_cast<double*>(&data) + i);
256  }
257 
259  INLINE BasicVector& operator=(const BasicVector& v) {
260  data = v.data;
261  return *this;
262  }
263 
264  INLINE BasicVector& operator+=(const BasicVector& v) {
265  data = _mm256_add_pd(data, v.data);
266  return *this;
267  }
268 
269  INLINE BasicVector& operator-=(const BasicVector& v) {
270  data = _mm256_sub_pd(data, v.data);
271  return *this;
272  }
273 
274  INLINE BasicVector& operator*=(const double f) {
275  data = _mm256_mul_pd(data, _mm256_set1_pd(f));
276  return *this;
277  }
278 
279  INLINE BasicVector& operator/=(const double f) {
280  data = _mm256_div_pd(data, _mm256_set1_pd(f));
281  return *this;
282  }
283 
284  INLINE BasicVector& operator*=(const BasicVector& v) {
285  data = _mm256_mul_pd(data, v.data);
286  return *this;
287  }
288 
289  INLINE BasicVector& operator/=(const BasicVector& v) {
290  data = _mm256_div_pd(data, v.data);
291  return *this;
292  }
293 
294  INLINE friend BasicVector operator-(const BasicVector& v) {
295  return _mm256_xor_pd(v.data, _mm256_set1_pd(-0.));
296  }
297 
298  INLINE friend BasicVector operator+(const BasicVector& v1, const BasicVector& v2) {
299  return BasicVector(_mm256_add_pd(v1.data, v2.data));
300  }
301 
302  INLINE friend BasicVector operator-(const BasicVector& v1, const BasicVector& v2) {
303  return BasicVector(_mm256_sub_pd(v1.data, v2.data));
304  }
305 
307  INLINE friend auto operator*(const BasicVector& v, const double f) {
308  return BasicVector(_mm256_mul_pd(v.data, _mm256_set1_pd(f)));
309  }
310 
311  INLINE friend auto operator*(const double f, const BasicVector& v) {
312  return BasicVector(_mm256_mul_pd(v.data, _mm256_set1_pd(f)));
313  }
314 
315  INLINE friend auto operator*(const BasicVector& v1, const BasicVector& v2) {
316  return BasicVector(_mm256_mul_pd(v1.data, v2.data));
317  }
318 
319  INLINE friend auto operator/(const BasicVector& v, const double f) {
320  SPH_ASSERT(f != 0.);
321  return BasicVector(_mm256_div_pd(v.data, _mm256_set1_pd(f)));
322  }
323 
324  INLINE friend auto operator/(const BasicVector& v1, const BasicVector& v2) {
325  return BasicVector(_mm256_div_pd(v1.data, v2.data));
326  }
327 
329  INLINE friend bool operator==(const BasicVector& v1, const BasicVector& v2) {
331  return v1[X] == v2[X] && v1[Y] == v2[Y] && v1[Z] == v2[Z];
332  }
333 
334  INLINE friend bool operator!=(const BasicVector& v1, const BasicVector& v2) {
335  return !(v1 == v2);
336  }
337 
338  INLINE auto dot(const BasicVector& other) const {
340  return (*this)[X] * other[X] + (*this)[Y] * other[Y] + (*this)[Z] * other[Z];
341  }
342 
343  // component-wise minimum
344  INLINE BasicVector min(const BasicVector& other) const {
345  return BasicVector(_mm256_min_pd(data, other.data));
346  }
347 
348  // component-wise maximum
349  INLINE BasicVector max(const BasicVector& other) const {
350  return BasicVector(_mm256_max_pd(data, other.data));
351  }
352 
353  INLINE const __m256d& sse() const {
354  return data;
355  }
356 
357  friend std::ostream& operator<<(std::ostream& stream, const BasicVector& v) {
358  constexpr int digits = PRECISION;
359  stream << std::setprecision(digits);
360  for (int i = 0; i < 3; ++i) {
361  stream << std::setw(20) << v[i];
362  }
363  return stream;
364  }
365 };
366 
367 #else
368 
369 // also align to 32 to have the same memory layout
370 template <>
371 class alignas(32) BasicVector<double> {
372 private:
373  __m128d data[2];
374 
375 public:
376  INLINE BasicVector() = default;
377 
379  INLINE BasicVector(const __m128d data1, const __m128d data2)
380  : data{ data1, data2 } {}
381 
383  INLINE explicit BasicVector(const double f)
384  : data{ _mm_set1_pd(f), _mm_set1_pd(f) } {}
385 
387  INLINE BasicVector(const double x, const double y, const double z, const double h = 0.)
388  : data{ _mm_set_pd(y, x), _mm_set_pd(h, z) } {}
389 
392  : data{ v.data[0], v.data[1] } {}
393 
395  INLINE const double& operator[](const int i) const {
396  SPH_ASSERT(unsigned(i) < 4);
397  return *(reinterpret_cast<const double*>(&data) + i);
398  }
399 
401  INLINE double& operator[](const int i) {
402  SPH_ASSERT(unsigned(i) < 4);
403  return *(reinterpret_cast<double*>(&data) + i);
404  }
405 
407  template <int i>
408  INLINE const double& get() const {
409  static_assert(unsigned(i) < 4, "Invalid index");
410  return *(reinterpret_cast<const double*>(&data) + i);
411  }
412 
414  template <int i>
415  INLINE double& get() {
416  static_assert(unsigned(i) < 4, "Invalid index");
417  return *(reinterpret_cast<double*>(&data) + i);
418  }
419 
420  template <int i>
421  INLINE const __m128d& sse() const {
422  static_assert(unsigned(i) < 2, "Invalid index");
423  return data[i];
424  }
425 
428  data[0] = v.data[0];
429  data[1] = v.data[1];
430  return *this;
431  }
432 
434  data[0] = _mm_add_pd(data[0], v.data[0]);
435  data[1] = _mm_add_pd(data[1], v.data[1]);
436  return *this;
437  }
438 
440  data[0] = _mm_sub_pd(data[0], v.data[0]);
441  data[1] = _mm_sub_pd(data[1], v.data[1]);
442  return *this;
443  }
444 
445  INLINE BasicVector& operator*=(const double f) {
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);
449  return *this;
450  }
451 
452  INLINE BasicVector& operator/=(const double f) {
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);
456  return *this;
457  }
458 
460  data[0] = _mm_mul_pd(data[0], v.data[0]);
461  data[1] = _mm_mul_pd(data[1], v.data[1]);
462  return *this;
463  }
464 
466  data[0] = _mm_div_pd(data[0], v.data[0]);
467  data[1] = _mm_div_pd(data[1], v.data[1]);
468  return *this;
469  }
470 
472  const __m128d value = _mm_set1_pd(-0.);
473  return { _mm_xor_pd(v.data[0], value), _mm_xor_pd(v.data[1], value) };
474  }
475 
476  INLINE friend BasicVector operator+(const BasicVector& v1, const BasicVector& v2) {
477  return BasicVector(_mm_add_pd(v1.data[0], v2.data[0]), _mm_add_pd(v1.data[1], v2.data[1]));
478  }
479 
480  INLINE friend BasicVector operator-(const BasicVector& v1, const BasicVector& v2) {
481  return BasicVector(_mm_sub_pd(v1.data[0], v2.data[0]), _mm_sub_pd(v1.data[1], v2.data[1]));
482  }
483 
485  INLINE friend auto operator*(const BasicVector& v, const double f) {
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));
488  }
489 
490  INLINE friend auto operator*(const double f, const BasicVector& v) {
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));
493  }
494 
495  INLINE friend auto operator*(const BasicVector& v1, const BasicVector& v2) {
496  return BasicVector(_mm_mul_pd(v1.data[0], v2.data[0]), _mm_mul_pd(v1.data[1], v2.data[1]));
497  }
498 
499  INLINE friend auto operator/(const BasicVector& v, const double f) {
500  SPH_ASSERT(f != 0.);
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));
503  }
504 
505  INLINE friend auto operator/(const BasicVector& v1, const BasicVector& v2) {
506  return BasicVector(_mm_div_pd(v1.data[0], v2.data[0]), _mm_div_pd(v1.data[1], v2.data[1]));
507  }
508 
510  INLINE friend bool operator==(const BasicVector& v1, const BasicVector& v2) {
511  constexpr int d = 3;
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;
517  }
518 
519  INLINE friend bool operator!=(const BasicVector& v1, const BasicVector& v2) {
520  return !(v1 == v2);
521  }
522 
524  friend std::ostream& operator<<(std::ostream& stream, const BasicVector& v) {
525  constexpr int digits = PRECISION;
526  stream << std::setprecision(digits);
527  for (int i = 0; i < 3; ++i) {
528  stream << std::setw(20) << v[i];
529  }
530  return stream;
531  }
532 };
533 
534 #endif
535 
536 static_assert(alignof(BasicVector<double>) == 32, "Incorrect alignment of Vector");
537 
538 
540 
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");
544 
546 
548 INLINE float dot(const BasicVector<float>& v1, const BasicVector<float>& v2) {
549  constexpr int d = 3;
550  return _mm_cvtss_f32(_mm_dp_ps(v1.sse(), v2.sse(), (1 << (d + 4)) - 0x0F));
551 }
552 
553 INLINE double dot(const BasicVector<double>& v1, const BasicVector<double>& v2) {
555  return v1[X] * v2[X] + v1[Y] * v2[Y] + v1[Z] * v2[Z];
556 }
557 
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))));
564 }
565 
568  return BasicVector<double>(
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]);
570 }
571 
575  return dot(v, v);
576 }
577 
580  return sqrt(dot(v, v));
581 }
582 
585  return sqrtApprox(dot(v, v));
586 }
587 
591  const Float length = getLength(v);
592  SPH_ASSERT(length != 0._f);
593  return v / length;
594 }
595 
598  const Float length = getLength(v);
599  SPH_ASSERT(length != 0._f);
600  return { v / length, length };
601 }
602 
603 
605 template <>
607  return _mm_min_ps(v1.sse(), v2.sse());
608 }
609 
611 template <>
613  return _mm_max_ps(v1.sse(), v2.sse());
614 }
615 
616 #ifdef SPH_VECTOR_AVX
617 template <>
619  return v1.min(v2);
620 }
621 
623  return v1.max(v2);
624 }
625 #else
626 template <>
628  return { _mm_min_pd(v1.sse<0>(), v2.sse<0>()), _mm_min_pd(v1.sse<1>(), v2.sse<1>()) };
629 }
630 
631 template <>
633  return { _mm_max_pd(v1.sse<0>(), v2.sse<0>()), _mm_max_pd(v1.sse<1>(), v2.sse<1>()) };
634 }
635 #endif
636 
637 
639 template <>
640 INLINE Vector clamp(const Vector& v, const Vector& v1, const Vector& v2) {
641  return max(v1, min(v, v2));
642 }
643 
645 template <>
646 INLINE Vector clamp(const Vector& v, const Interval& range) {
647  return Vector(range.clamp(v[0]), range.clamp(v[1]), range.clamp(v[2]), range.clamp(v[3]));
648 }
649 
651 INLINE bool almostEqual(const Vector& v1, const Vector& v2, const Float eps = EPS) {
652  return getSqrLength(v1 - v2) <= sqr(eps) * (1._f + max(getSqrLength(v1), getSqrLength(v2)));
653 }
654 
656 template <>
657 INLINE Float norm(const Vector& v) {
658  const Float result = getLengthApprox(v);
659  SPH_ASSERT(isReal(result));
660  return result;
661 }
662 
664 template <>
666  const Float result = getSqrLength(v);
667  SPH_ASSERT(isReal(result));
668  return result;
669 }
670 
672 template <>
675  return min(v[0], v[1], v[2]);
676 }
677 
679 template <>
681  return max(v[0], v[1], v[2]);
682 }
683 
686  Size minIdx = 0;
687  if (v[1] < v[minIdx]) {
688  minIdx = 1;
689  }
690  if (v[2] < v[minIdx]) {
691  minIdx = 2;
692  }
693  return minIdx;
694 }
695 
698  Size maxIdx = 0;
699  if (v[1] > v[maxIdx]) {
700  maxIdx = 1;
701  }
702  if (v[2] > v[maxIdx]) {
703  maxIdx = 2;
704  }
705  return maxIdx;
706 }
707 
709 template <>
710 INLINE auto abs(const BasicVector<float>& v) {
711  return BasicVector<float>(_mm_andnot_ps(_mm_set1_ps(-0.f), v.sse()));
712 }
713 
714 #ifdef SPH_VECTOR_AVX
715 template <>
716 INLINE auto abs(const BasicVector<double>& v) {
718  return BasicVector<double>(abs(v[X]), abs(v[Y]), abs(v[Z]), abs(v[H]));
719 }
720 #else
721 template <>
723  return BasicVector<double>(
724  _mm_andnot_pd(_mm_set1_pd(-0.), v.sse<0>()), _mm_andnot_pd(_mm_set1_pd(-0.), v.sse<1>()));
725 }
726 #endif
727 
730  const Vector absV = abs(v);
731  return absV[X] + absV[Y] + absV[Z];
732 }
733 
734 
736 /*template <>
737 INLINE Vector sqrtInv(const Vector& v) {
738  return _mm_rsqrt_ss(v.sse());
739 }*/
740 
741 template <>
744  return isReal(v[0]) && isReal(v[1]) && isReal(v[2]);
745 }
746 
747 template <>
750  return isReal(v[0]) && isReal(v[1]) && isReal(v[2]);
751 }
752 
753 template <>
754 INLINE auto less(const Vector& v1, const Vector& v2) {
756  return Vector(Float(v1[X] < v2[X]), Float(v1[Y] < v2[Y]), Float(v1[Z] < v2[Z]), Float(v1[H] < v2[H]));
757 }
758 
759 template <>
761  return { v[X], v[Y], v[Z] };
762 }
763 
764 
767 template <typename T1, typename T2>
769  return BasicVector<T1>(T1(v[X]), T1(v[Y]), T1(v[Z]), T1(v[H]));
770 }
771 template <>
773  return v;
774 }
775 
777 INLINE Vector cos(const Vector& v) {
779  return Vector(cos(v[X]), cos(v[Y]), cos(v[Z]));
780 }
781 
788 INLINE Vector sphericalToCartesian(const Float r, const Float theta, const Float phi) {
789  const Float s = sin(theta);
790  const Float c = cos(theta);
791  return r * Vector(s * cos(phi), s * sin(phi), c);
792 }
793 
795 INLINE Vector cylindricalToCartesian(const Float r, const Float phi, const Float z) {
796  return Vector(r * cos(phi), r * sin(phi), z);
797 }
798 
803 };
804 
807  const Float r = getLength(v);
808  const Float phi = atan2(v[Y], v[X]);
809  const Float theta = acos(v[Z] / r); // atan2(sqrt(sqr(v[X]) + sqr(v[Y])), v[Z]);
810  return { r, theta, phi };
811 }
812 
813 
820 INLINE Vector sphericalInversion(const Vector& v, const Vector& center, const Float radius) {
821  const Vector diff = v - center;
822  const Float lSqr = getSqrLength(diff);
823  return center + diff * radius * radius / lSqr;
824 }
825 
827 INLINE Float distance(const Vector& r, const Vector& axis) {
828  SPH_ASSERT(almostEqual(getSqrLength(axis), 1._f));
829  return getLength(r - dot(r, axis) * axis);
830 }
831 
833 INLINE bool lexicographicalLess(const Vector& v1, const Vector& v2) {
834  if (v1[Z] < v2[Z]) {
835  return true;
836  } else if (v1[Z] > v2[Z]) {
837  return false;
838  } else if (v1[Y] < v2[Y]) {
839  return true;
840  } else if (v1[Y] > v2[Y]) {
841  return false;
842  } else if (v1[X] < v2[X]) {
843  return true;
844  } else {
845  return false;
846  }
847 }
848 
#define SPH_ASSERT(x,...)
Definition: Assert.h:94
bool operator==(const AutoPtr< T > &ptr, std::nullptr_t)
Definition: AutoPtr.h:104
bool operator!=(const AutoPtr< T > &ptr, std::nullptr_t)
Definition: AutoPtr.h:114
NAMESPACE_SPH_BEGIN
Definition: BarnesHut.cpp:13
const float radius
Definition: CurveDialog.cpp:18
Function for generic manipulation with geometric types.
Global parameters of the code.
uint32_t Size
Integral type used to index arrays (by default).
Definition: Globals.h:16
double Float
Precision used withing the code. Use Float instead of float or double where precision is important.
Definition: Globals.h:13
constexpr int PRECISION
Number of valid digits of numbers on output.
Definition: Globals.h:25
Object representing interval of real values.
Lut< TValue, TScalar > operator/(const Lut< TValue, TScalar > &lut1, const Lut< TValue, TScalar > &lut2)
Definition: Lut.h:189
INLINE T sqrtApprox(const T f)
Returns an approximative value of square root.
Definition: MathUtils.h:57
constexpr Float EPS
Definition: MathUtils.h:30
constexpr INLINE T sqr(const T &f) noexcept
Return a squared value.
Definition: MathUtils.h:67
INLINE T sin(const T f)
Definition: MathUtils.h:296
INLINE T sqrt(const T f)
Return a squared root of a value.
Definition: MathUtils.h:78
INLINE T acos(const T f)
Definition: MathUtils.h:306
INLINE T atan2(const T y, const T x)
Definition: MathUtils.h:321
#define INLINE
Macros for conditional compilation based on selected compiler.
Definition: Object.h:31
#define NAMESPACE_SPH_END
Definition: Object.h:12
std::ostream & operator<<(std::ostream &stream, const Path &path)
Definition: Path.cpp:204
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.
Definition: Vector.h:795
INLINE Size argMax(const Vector &v)
Returns the index of the maximum element.
Definition: Vector.h:697
INLINE SphericalCoords cartensianToSpherical(const Vector &v)
Converts vector in cartesian coordinates to spherical coordinates.
Definition: Vector.h:806
INLINE Vector clamp(const Vector &v, const Vector &v1, const Vector &v2)
Component-wise clamping.
Definition: Vector.h:640
INLINE Float norm(const Vector &v)
Returns norm of a vector, i.e. its (approximative) length.
Definition: Vector.h:657
INLINE Float minElement(const Vector &v)
Returns minimum element of a vector. Considers only the first 3 component, 4th one is ignored.
Definition: Vector.h:673
INLINE auto abs(const BasicVector< float > &v)
Computes vector of absolute values.
Definition: Vector.h:710
INLINE bool isReal(const BasicVector< float > &v)
Computes vector of inverse squared roots.
Definition: Vector.h:742
INLINE auto less(const Vector &v1, const Vector &v2)
Definition: Vector.h:754
INLINE Float getLength(const Vector &v)
Returns the length of the vector. Enabled only for vectors of floating-point precision.
Definition: Vector.h:579
INLINE Float distance(const Vector &r, const Vector &axis)
Returns the distance of vector from given axis. The axis is assumed to be normalized.
Definition: Vector.h:827
INLINE bool almostEqual(const Vector &v1, const Vector &v2, const Float eps=EPS)
Checks if two vectors are equal to some given accuracy.
Definition: Vector.h:651
INLINE Float getLengthApprox(const Vector &v)
Returns approximate value of the length. Enabled only for vectors of floating-point precision.
Definition: Vector.h:584
INLINE Tuple< Vector, Float > getNormalizedWithLength(const Vector &v)
Returns normalized vector and length of the input vector as tuple.
Definition: Vector.h:597
INLINE Float normSqr(const Vector &v)
Returns squared length of a vector.
Definition: Vector.h:665
INLINE BasicVector< float > min(const BasicVector< float > &v1, const BasicVector< float > &v2)
Component-wise minimum.
Definition: Vector.h:606
INLINE BasicVector< T1 > vectorCast(const BasicVector< T2 > &v)
Definition: Vector.h:768
INLINE Vector cos(const Vector &v)
Cosine applied to all components of the vector.
Definition: Vector.h:777
INLINE bool lexicographicalLess(const Vector &v1, const Vector &v2)
Compares components of two vectors lexicographically, primary component is z.
Definition: Vector.h:833
INLINE Float getSqrLength(const Vector &v)
Definition: Vector.h:574
INLINE BasicVector< float > cross(const BasicVector< float > &v1, const BasicVector< float > &v2)
Cross product between two vectors.
Definition: Vector.h:559
BasicVector< Float > Vector
Definition: Vector.h:539
INLINE Float maxElement(const Vector &v)
Returns maximum element of a vector. Considers only the first 3 component, 4th one is ignored.
Definition: Vector.h:680
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...
Definition: Vector.h:548
INLINE BasicVector< float > max(const BasicVector< float > &v1, const BasicVector< float > &v2)
Component-wise maximum.
Definition: Vector.h:612
INLINE Vector sphericalToCartesian(const Float r, const Float theta, const Float phi)
Constructs a vector from spherical coordinates.
Definition: Vector.h:788
INLINE Vector getNormalized(const Vector &v)
Definition: Vector.h:590
constexpr bool IsVector
Definition: Vector.h:44
INLINE Size argMin(const Vector &v)
Returns the index of the minimum element.
Definition: Vector.h:685
INLINE StaticArray< Float, 6 > getComponents< Vector >(const Vector &v)
Definition: Vector.h:760
INLINE Float l1Norm(const Vector &v)
Returns the L1 norm (sum of absolute values) of the vector.
Definition: Vector.h:729
Coordinate
Components of the 4D vector.
Definition: Vector.h:21
@ H
Definition: Vector.h:25
@ Y
Definition: Vector.h:23
@ X
Definition: Vector.h:22
@ Z
Definition: Vector.h:24
INLINE Vector sphericalInversion(const Vector &v, const Vector &center, const Float radius)
Definition: Vector.h:820
specialization for doubles or units of double precision
Definition: Vector.h:371
INLINE BasicVector & operator+=(const BasicVector &v)
Definition: Vector.h:433
INLINE BasicVector(const BasicVector &v)
Copy constructor.
Definition: Vector.h:391
INLINE BasicVector & operator=(const BasicVector &v)
Copy operator.
Definition: Vector.h:427
INLINE BasicVector & operator*=(const double f)
Definition: Vector.h:445
INLINE const __m128d & sse() const
Definition: Vector.h:421
INLINE friend BasicVector operator-(const BasicVector &v)
Definition: Vector.h:471
INLINE friend bool operator!=(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:519
INLINE BasicVector & operator*=(const BasicVector &v)
Definition: Vector.h:459
INLINE BasicVector(const double f)
Constructs by copying a value to all vector components.
Definition: Vector.h:383
INLINE BasicVector()=default
INLINE friend BasicVector operator+(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:476
INLINE friend auto operator/(const BasicVector &v, const double f)
Definition: Vector.h:499
INLINE BasicVector(const double x, const double y, const double z, const double h=0.)
Constructs the vector from given components.
Definition: Vector.h:387
INLINE double & get()
Get component by given compile-time constant index.
Definition: Vector.h:415
INLINE friend BasicVector operator-(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:480
INLINE BasicVector(const __m128d data1, const __m128d data2)
Constructs from two SSE vectors.
Definition: Vector.h:379
INLINE const double & operator[](const int i) const
Get component by given index.
Definition: Vector.h:395
INLINE friend auto operator*(const BasicVector &v, const double f)
Multiplication of vector by a value or unit.
Definition: Vector.h:485
INLINE friend bool operator==(const BasicVector &v1, const BasicVector &v2)
Comparison operator, only compares first three components of vectors.
Definition: Vector.h:510
INLINE BasicVector & operator/=(const BasicVector &v)
Definition: Vector.h:465
INLINE friend auto operator/(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:505
INLINE const double & get() const
Get component by given compile-time constant index.
Definition: Vector.h:408
INLINE BasicVector & operator/=(const double f)
Definition: Vector.h:452
INLINE BasicVector & operator-=(const BasicVector &v)
Definition: Vector.h:439
INLINE friend auto operator*(const double f, const BasicVector &v)
Definition: Vector.h:490
friend std::ostream & operator<<(std::ostream &stream, const BasicVector &v)
Output to stream.
Definition: Vector.h:524
INLINE double & operator[](const int i)
Get component by given index.
Definition: Vector.h:401
INLINE friend auto operator*(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:495
3-dimensional vector, float precision
Definition: Vector.h:57
INLINE BasicVector & operator*=(const float f)
Definition: Vector.h:127
INLINE friend auto operator*(const BasicVector &v, const float f)
Multiplication of vector by a value or unit.
Definition: Vector.h:160
INLINE const float & operator[](const int i) const
Get component by given index.
Definition: Vector.h:81
INLINE BasicVector & operator*=(const BasicVector &v)
Definition: Vector.h:137
INLINE friend BasicVector operator-(const BasicVector &v)
Definition: Vector.h:147
INLINE friend bool operator!=(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:188
INLINE friend auto operator*(const float f, const BasicVector &v)
Definition: Vector.h:164
INLINE BasicVector & operator/=(const float f)
Definition: Vector.h:132
INLINE friend BasicVector operator+(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:151
INLINE BasicVector & operator+=(const BasicVector &v)
Definition: Vector.h:117
INLINE BasicVector(const float x, const float y, const float z, const float h=0.f)
Constructs the vector from given components.
Definition: Vector.h:73
INLINE BasicVector & operator-=(const BasicVector &v)
Definition: Vector.h:122
INLINE BasicVector & operator=(const BasicVector &v)
Copy operator.
Definition: Vector.h:112
INLINE float & operator[](const int i)
Get component by given index.
Definition: Vector.h:87
INLINE friend BasicVector operator-(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:155
INLINE friend auto operator/(const BasicVector &v, const float f)
Definition: Vector.h:172
INLINE BasicVector(const float f)
Constructs by copying a value to all vector components.
Definition: Vector.h:69
INLINE const __m128 & sse() const
Returns the data as SSE vector.
Definition: Vector.h:107
INLINE BasicVector & operator/=(const BasicVector &v)
Definition: Vector.h:142
INLINE friend bool operator==(const BasicVector &v1, const BasicVector &v2)
Comparison operator, only compares first three components of vectors.
Definition: Vector.h:182
INLINE const float & get() const
Get component by given compile-time constant index.
Definition: Vector.h:94
INLINE friend auto operator/(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:177
INLINE BasicVector(const BasicVector &v)
Copy constructor.
Definition: Vector.h:77
INLINE BasicVector()=default
INLINE float & get()
Get component by given compile-time constant index.
Definition: Vector.h:101
friend std::ostream & operator<<(std::ostream &stream, const BasicVector &v)
Definition: Vector.h:192
INLINE BasicVector(const __m128 data)
Constructs from SSE vector.
Definition: Vector.h:65
INLINE friend auto operator*(const BasicVector &v1, const BasicVector &v2)
Definition: Vector.h:168
Object representing a 1D interval of real numbers.
Definition: Interval.h:17
INLINE Float clamp(const Float &value) const
Clamps the given value by the interval.
Definition: Interval.h:68
Array with fixed number of allocated elements.
Definition: StaticArray.h:19
Heterogeneous container capable of storing a fixed number of values.
Definition: Tuple.h:146
Difference< TValue1, TValue2 > operator-(const TValue1 &v1, const TValue2 &v2)
Definition: Multipole.h:949
MultiplyByScalar< TValue > operator*(const TValue &v, const Float f)
Definition: Multipole.h:912
Sum< TValue1, TValue2 > operator+(const TValue1 &v1, const TValue2 &v2)
Definition: Multipole.h:933
Helper type trait to determine if the type is a vector of some kind.
Definition: Vector.h:31
static constexpr bool value
Definition: Vector.h:32
Float r
radius
Definition: Vector.h:800
Float phi
longitude
Definition: Vector.h:802
Float theta
latitude
Definition: Vector.h:801