File indexing completed on 2025-01-18 10:13:51
0001 #ifndef VECCORE_MATH_H
0002 #define VECCORE_MATH_H
0003
0004 #ifdef _MSC_VER
0005 #define _USE_MATH_DEFINES
0006 #include <math.h>
0007 #endif
0008
0009 #include <cmath>
0010
0011 #if defined(__APPLE__) && !defined(__NVCC__)
0012 VECCORE_FORCE_INLINE
0013 void sincosf(const float &x, float *s, float *c)
0014 {
0015 __sincosf(x, s, c);
0016 }
0017
0018 VECCORE_FORCE_INLINE
0019 void sincos(const double &x, double *s, double *c)
0020 {
0021 __sincos(x, s, c);
0022 }
0023 #elif defined(_MSC_VER)
0024 VECCORE_FORCE_INLINE
0025 void sincosf(const float &x, float *s, float *c)
0026 {
0027 *s = sinf(x);
0028 *c = cosf(x);
0029 }
0030
0031 VECCORE_FORCE_INLINE
0032 void sincos(const double &x, double *s, double *c)
0033 {
0034 *s = sin(x);
0035 *c = cos(x);
0036 }
0037 #endif
0038
0039 namespace vecCore {
0040 inline namespace math {
0041
0042 #define VECCORE_MATH_UNARY_FUNCTION(F, f) \
0043 template <typename T> \
0044 VECCORE_FORCE_INLINE VECCORE_ATT_HOST_DEVICE \
0045 T F(const T &x) \
0046 { \
0047 T ret(x); \
0048 for(size_t i = 0; i < VectorSize<T>(); ++i) \
0049 Set(ret, i, std::f(Get(x,i))); \
0050 return ret; \
0051 } \
0052
0053 #define VECCORE_MATH_BINARY_FUNCTION(F, f) \
0054 template <typename T> \
0055 VECCORE_FORCE_INLINE VECCORE_ATT_HOST_DEVICE \
0056 T F(const T &x, const T &y) \
0057 { \
0058 T ret(x); \
0059 for(size_t i = 0; i < VectorSize<T>(); ++i) \
0060 Set(ret, i, std::f(Get(x,i), Get(y,i))); \
0061 return ret; \
0062 } \
0063
0064
0065
0066 VECCORE_MATH_UNARY_FUNCTION(Abs, abs)
0067
0068 template <class T>
0069 VECCORE_FORCE_INLINE
0070 VECCORE_ATT_HOST_DEVICE
0071 T Min(const T &a, const T &b)
0072 {
0073 return Blend(a < b, a, b);
0074 }
0075
0076 template <class T>
0077 VECCORE_FORCE_INLINE
0078 VECCORE_ATT_HOST_DEVICE
0079 T Max(const T &a, const T &b)
0080 {
0081 return Blend(a > b, a, b);
0082 }
0083
0084 template <typename T>
0085 VECCORE_FORCE_INLINE
0086 VECCORE_ATT_HOST_DEVICE
0087 T Min(const T &a, const T &b, const T &c)
0088 {
0089 return Min(a, Min(b, c));
0090 }
0091
0092 template <typename T>
0093 VECCORE_FORCE_INLINE
0094 VECCORE_ATT_HOST_DEVICE
0095 T Max(const T &a, const T &b, const T &c)
0096 {
0097 return Max(a, Max(b, c));
0098 }
0099
0100 template <typename T, template <typename> class Wrapper>
0101 VECCORE_FORCE_INLINE
0102 VECCORE_ATT_HOST_DEVICE
0103 Wrapper<T> Min(const Wrapper<T> &a, const Wrapper<T> &b)
0104 {
0105 return Blend(a < b, a, b);
0106 }
0107
0108 template <typename T, template <typename> class Wrapper>
0109 VECCORE_FORCE_INLINE
0110 VECCORE_ATT_HOST_DEVICE
0111 Wrapper<T> Max(const Wrapper<T> &a, const Wrapper<T> &b)
0112 {
0113 return Blend(a > b, a, b);
0114 }
0115
0116 VECCORE_MATH_BINARY_FUNCTION(CopySign, copysign)
0117
0118 template <typename T>
0119 VECCORE_FORCE_INLINE
0120 VECCORE_ATT_HOST_DEVICE
0121 T Sign(const T &x)
0122 {
0123 return CopySign(T(1), x);
0124 }
0125
0126
0127
0128 VECCORE_MATH_UNARY_FUNCTION(Sin, sin)
0129 VECCORE_MATH_UNARY_FUNCTION(Cos, cos)
0130 VECCORE_MATH_UNARY_FUNCTION(Tan, tan)
0131
0132 VECCORE_MATH_UNARY_FUNCTION(ASin, asin)
0133 VECCORE_MATH_UNARY_FUNCTION(ACos, acos)
0134 VECCORE_MATH_UNARY_FUNCTION(ATan, atan)
0135 VECCORE_MATH_BINARY_FUNCTION(ATan2, atan2)
0136
0137 template <typename T>
0138 VECCORE_FORCE_INLINE
0139 VECCORE_ATT_HOST_DEVICE
0140 void SinCos(const T &x, T *s, T *c)
0141 {
0142 sincos(x, s, c);
0143 }
0144
0145 template <>
0146 VECCORE_FORCE_INLINE
0147 VECCORE_ATT_HOST_DEVICE
0148 void SinCos(const float &x, float *s, float *c)
0149 {
0150 ::sincosf(x, s, c);
0151 }
0152
0153 template <>
0154 VECCORE_FORCE_INLINE
0155 VECCORE_ATT_HOST_DEVICE
0156 void SinCos(const double &x, double *s, double *c)
0157 {
0158 ::sincos(x, s, c);
0159 }
0160
0161
0162
0163 VECCORE_MATH_UNARY_FUNCTION(Sinh, sinh)
0164 VECCORE_MATH_UNARY_FUNCTION(Cosh, cosh)
0165 VECCORE_MATH_UNARY_FUNCTION(Tanh, tanh)
0166
0167 VECCORE_MATH_UNARY_FUNCTION(ASinh, asinh)
0168 VECCORE_MATH_UNARY_FUNCTION(ACosh, acosh)
0169 VECCORE_MATH_UNARY_FUNCTION(ATanh, atanh)
0170
0171
0172
0173 VECCORE_MATH_UNARY_FUNCTION(Exp, exp)
0174 VECCORE_MATH_UNARY_FUNCTION(Exp2, exp2)
0175 VECCORE_MATH_UNARY_FUNCTION(Expm1, expm1)
0176 VECCORE_MATH_UNARY_FUNCTION(Log, log)
0177 VECCORE_MATH_UNARY_FUNCTION(Log2, log2)
0178 VECCORE_MATH_UNARY_FUNCTION(Logb, logb)
0179 VECCORE_MATH_UNARY_FUNCTION(Log10, log10)
0180 VECCORE_MATH_UNARY_FUNCTION(Log1p, log1p)
0181 VECCORE_MATH_UNARY_FUNCTION(Ilogb, ilogb)
0182
0183
0184 VECCORE_MATH_UNARY_FUNCTION(TGamma, tgamma)
0185
0186 template <typename T>
0187 VECCORE_FORCE_INLINE
0188 VECCORE_ATT_HOST_DEVICE
0189 T Frexp(const T &x, int *exp)
0190 {
0191 T ret;
0192 for(size_t i = 0; i < VectorSize<T>(); ++i)
0193 Set(ret, i, std::frexp(Get(x,i), &exp[i]));
0194 return ret;
0195 }
0196
0197 template <typename T>
0198 VECCORE_FORCE_INLINE
0199 VECCORE_ATT_HOST_DEVICE
0200 T Ldexp(const T &x, int exp)
0201 {
0202 T ret;
0203 for(size_t i = 0; i < VectorSize<T>(); ++i)
0204 Set(ret, i, std::ldexp(Get(x,i), exp));
0205 return ret;
0206 }
0207
0208 template <typename T>
0209 VECCORE_FORCE_INLINE
0210 VECCORE_ATT_HOST_DEVICE
0211 T Modf(const T &x, T *intpart)
0212 {
0213 T ret;
0214 for(size_t i = 0; i < VectorSize<T>(); ++i)
0215 Set(ret, i, std::modf(Get(x,i), &intpart[i]));
0216 return ret;
0217 }
0218
0219 template <typename T>
0220 VECCORE_FORCE_INLINE
0221 VECCORE_ATT_HOST_DEVICE
0222 T Rsqrt(const T &x)
0223 {
0224 T ret(1.0 / x);
0225 for(size_t i = 0; i < VectorSize<T>(); ++i)
0226 Set(ret, i, std::sqrt(Get(ret,i)));
0227 return ret;
0228 }
0229
0230 template <typename T>
0231 VECCORE_FORCE_INLINE
0232 VECCORE_ATT_HOST_DEVICE
0233 T Scalbn(const T &x, int n)
0234 {
0235 T ret;
0236 for(size_t i = 0; i < VectorSize<T>(); ++i)
0237 Set(ret, i, std::scalbn(Get(x,i), n));
0238 return ret;
0239 }
0240
0241 template <typename T>
0242 VECCORE_FORCE_INLINE
0243 VECCORE_ATT_HOST_DEVICE
0244 T Scalbln(const T &x, long int n)
0245 {
0246 T ret;
0247 for(size_t i = 0; i < VectorSize<T>(); ++i)
0248 Set(ret, i, std::scalbln(Get(x,i), n));
0249 return ret;
0250 }
0251
0252
0253
0254 VECCORE_MATH_UNARY_FUNCTION(Sqrt, sqrt)
0255 VECCORE_MATH_UNARY_FUNCTION(Cbrt, cbrt)
0256 VECCORE_MATH_BINARY_FUNCTION(Pow, pow)
0257 VECCORE_MATH_BINARY_FUNCTION(Hypot, hypot)
0258
0259
0260
0261 VECCORE_MATH_UNARY_FUNCTION(Ceil, ceil)
0262 VECCORE_MATH_UNARY_FUNCTION(Floor, floor)
0263 VECCORE_MATH_BINARY_FUNCTION(Fmod, fmod)
0264 VECCORE_MATH_UNARY_FUNCTION(Round, round)
0265 VECCORE_MATH_UNARY_FUNCTION(Trunc, trunc)
0266
0267
0268
0269 template <typename T>
0270 VECCORE_FORCE_INLINE
0271 VECCORE_ATT_HOST_DEVICE
0272 Mask<T> IsInf(const T &x)
0273 {
0274 #ifndef VECCORE_CUDA
0275 using std::isinf;
0276 #endif
0277 return isinf(x);
0278 }
0279
0280 template <typename T>
0281 VECCORE_FORCE_INLINE
0282 VECCORE_ATT_HOST_DEVICE
0283 Mask<T> IsNegative(const T &x)
0284 {
0285 return x < T(0);
0286 }
0287
0288 template <typename T>
0289 VECCORE_FORCE_INLINE
0290 VECCORE_ATT_HOST_DEVICE
0291 constexpr T Deg(const T &x)
0292 {
0293 return (x * T(180.0 / M_PI));
0294 }
0295
0296 template <typename T>
0297 VECCORE_FORCE_INLINE
0298 VECCORE_ATT_HOST_DEVICE
0299 constexpr T Rad(const T &x)
0300 {
0301 return (x * T(M_PI / 180.0));
0302 }
0303
0304 #undef VECCORE_MATH_UNARY_FUNCTION
0305 #undef VECCORE_MATH_BINARY_FUNCTION
0306
0307 }
0308 }
0309
0310 #endif