real.hh 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384
  1. // -*- mode: c++; coding: utf-8 -*-
  2. /// @file real.hh
  3. /// @brief Define real number type and related global definitions.
  4. // (c) Daniel Llorens - 2005, 2015
  5. // This library is free software; you can redistribute it and/or modify it under
  6. // the terms of the GNU Lesser General Public License as published by the Free
  7. // Software Foundation; either version 3 of the License, or (at your option) any
  8. // later version.
  9. #pragma once
  10. #include "ra/macros.hh"
  11. #include <limits>
  12. #include <cstdlib>
  13. #include <cmath>
  14. #include <algorithm>
  15. namespace ra {
  16. template <class T=double> constexpr T EPS = std::numeric_limits<T>::epsilon();
  17. template <class T=double> constexpr T ALINF = std::numeric_limits<T>::max();
  18. template <class T=double> constexpr T PINF = std::numeric_limits<T>::infinity();
  19. template <class T=double> constexpr T QNAN = std::numeric_limits<T>::quiet_NaN();
  20. constexpr double PI = 3.14159265358979323846264338327950288419716939937510582;
  21. constexpr double PI2 = PI/2.;
  22. constexpr double EXP1 = 2.71828182845904523536028747135266249775724709369995957;
  23. constexpr double TAU = 2*PI;
  24. constexpr double TTAU = TAU*2;
  25. constexpr double TAU6 = TAU/6;
  26. constexpr double TAU12 = TAU/12;
  27. constexpr double I4PI = 1./TTAU;
  28. constexpr double C0 = 2.99792458e8;
  29. constexpr double M0 = (4e-7)*PI;
  30. constexpr double ECHAR = 1.602176487e-19;
  31. constexpr double EMASS = 9.10938215e-31;
  32. constexpr double Z0 = 376.730313461;
  33. constexpr double LOG2E = 1.44269504088896340735992468100189213742664595415299;
  34. constexpr double LOGE2 = .693147180559945309417232121458176568075500134360255;
  35. constexpr double GOLDEN = 1.61803398874989484820458683436563811772030917980576; // (1+√5)/2.
  36. // constexpr clang
  37. static const double E0 = 1./(M0*C0*C0);
  38. static const double SQRT2 = sqrt(2.);
  39. static const double ISQRT2 = 1/sqrt(2.);
  40. static const double SQRTPI = sqrt(PI);
  41. static const double LNPI = log(PI);
  42. }
  43. // just as max() and min() are found for ra:: types w/o qualifying (through ADL) they should also be found for the POD types.
  44. // besides, gcc still leaks cmath functions into the global namespace, so by default e.g. sqrt will be C double sqrt(double) and not the overload set.
  45. using std::abs, std::max, std::min, std::fma, std::clamp, std::sqrt, std::pow, std::exp;
  46. using std::swap, std::isfinite, std::isinf;
  47. #define RA_IS_REAL(T) (std::numeric_limits<T>::is_integer || std::is_floating_point_v<T>)
  48. #define RA_REAL_OVERLOAD_CE(T) template <class T> requires (RA_IS_REAL(T)) inline constexpr T
  49. // As an array op; special definitions for rank 0.
  50. RA_REAL_OVERLOAD_CE(T) arg(T const x) { return 0; }
  51. RA_REAL_OVERLOAD_CE(T) amax(T const x) { return x; }
  52. RA_REAL_OVERLOAD_CE(T) amin(T const x) { return x; }
  53. RA_REAL_OVERLOAD_CE(T) sqr(T const x) { return x*x; }
  54. RA_REAL_OVERLOAD_CE(T) real_part(T const x) { return x; }
  55. RA_REAL_OVERLOAD_CE(T) imag_part(T const x) { return 0.; }
  56. RA_REAL_OVERLOAD_CE(T) conj(T const x) { return x; }
  57. RA_REAL_OVERLOAD_CE(T) sqrm(T const x) { return x*x; }
  58. RA_REAL_OVERLOAD_CE(T) norm2(T const x) { return std::abs(x); }
  59. #undef RA_REAL_OVERLOAD_CE
  60. #undef RA_IS_REAL
  61. #define FOR_FLOAT(T) \
  62. inline constexpr T mul_conj(T const x, T const y) { return x*y; } \
  63. inline constexpr T sqrm(T const x, T const y) { return sqrm(x-y); } \
  64. inline constexpr T dot(T const x, T const y) { return x*y; } \
  65. inline /* constexpr clang */ T fma_conj(T const a, T const b, T const c) { return fma(a, b, c); } \
  66. inline /* constexpr clang */ T norm2(T const x, T const y) { return std::abs(x-y); } \
  67. inline /* constexpr clang */ T abs(T const x, T const y) { return std::abs(x-y); } \
  68. inline /* constexpr clang */ T rel_error(T const a, T const b) { auto den = (abs(a)+abs(b)); return den==0 ? 0. : 2.*abs(a, b)/den; }
  69. FOR_EACH(FOR_FLOAT, float, double)
  70. #undef FOR_FLOAT
  71. namespace ra {
  72. inline constexpr double rad2deg(double const r) { return r*(360./ra::TAU); }
  73. inline constexpr double deg2rad(double const d) { return d*(ra::TAU/360.); }
  74. } // namespace ra