//============================================================================= // // Copyright (c) Kitware, Inc. // All rights reserved. // See LICENSE.txt for details. // // This software is distributed WITHOUT ANY WARRANTY; without even // the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR // PURPOSE. See the above copyright notice for more information. // // Copyright 2015 Sandia Corporation. // Copyright 2015 UT-Battelle, LLC. // Copyright 2015 Los Alamos National Security. // // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation, // the U.S. Government retains certain rights in this software. // Under the terms of Contract DE-AC52-06NA25396 with Los Alamos National // Laboratory (LANL), the U.S. Government retains certain rights in // this software. // //============================================================================= $# This file uses the pyexpander macro processing utility to build the $# FunctionInterface facilities that use a variable number of arguments. $# Information, documentation, and downloads for pyexpander can be found at: $# $# http://pyexpander.sourceforge.net/ $# $# To build the source code, execute the following (after installing $# pyexpander, of course): $# $# expander.py Math.h.in > Math.h $# $# Ignore the following comment. It is meant for the generated file. // **** DO NOT EDIT THIS FILE!!! **** // This file is automatically generated by FunctionInterfaceDetailPre.h.in #ifndef vtk_m_Math_h #define vtk_m_Math_h #include #include #include #ifndef VTKM_CUDA #include #include #include // The nonfinite and sign test functions are usually defined as macros, and // boost seems to want to undefine those macros so that it can implement the // C99 templates and other implementations of the same name. Get around the // problem by using the boost version when compiling for a CPU. VTKM_THIRDPARTY_PRE_INCLUDE #include #include VTKM_THIRDPARTY_POST_INCLUDE #include #define VTKM_USE_BOOST_CLASSIFY #define VTKM_USE_BOOST_SIGN #endif // !VTKM_CUDA #if !defined(__CUDA_ARCH__) #define VTKM_USE_STL_MIN_MAX #include #endif #if defined(VTKM_MSVC) && !defined(VTKM_CUDA) VTKM_THIRDPARTY_PRE_INCLUDE #include #include #include #include #include #include #include VTKM_THIRDPARTY_POST_INCLUDE #define VTKM_USE_BOOST_MATH #if (_MSC_VER <= 1600) && !defined(VTKM_USE_STL_MIN_MAX) #define VTKM_USE_STL_MIN_MAX #include #endif #endif #define VTKM_SYS_MATH_FUNCTION_32(func) func ## f #define VTKM_SYS_MATH_FUNCTION_64(func) func $py( def unary_function(name, type, returntype, expression): return '''VTKM_EXEC_CONT_EXPORT {2} {0}({1} x) {{ return {3}; }} '''.format(name, type, returntype, expression) def unary_Vec_function(vtkmname): return '''template VTKM_EXEC_CONT_EXPORT vtkm::Vec {0}(const vtkm::Vec &x) {{ vtkm::Vec result; for (vtkm::IdComponent index = 0; index < N; index++) {{ result[index] = vtkm::{0}(x[index]); }} return result; }} template VTKM_EXEC_CONT_EXPORT vtkm::Vec {0}(const vtkm::Vec &x) {{ return vtkm::Vec(vtkm::{0}(x[0]), vtkm::{0}(x[1]), vtkm::{0}(x[2]), vtkm::{0}(x[3])); }} template VTKM_EXEC_CONT_EXPORT vtkm::Vec {0}(const vtkm::Vec &x) {{ return vtkm::Vec(vtkm::{0}(x[0]), vtkm::{0}(x[1]), vtkm::{0}(x[2])); }} template VTKM_EXEC_CONT_EXPORT vtkm::Vec {0}(const vtkm::Vec &x) {{ return vtkm::Vec(vtkm::{0}(x[0]), vtkm::{0}(x[1])); }} '''.format(vtkmname) def unary_math_function_no_vec(vtkmname, sysname, returntype = None): return unary_function(vtkmname, 'vtkm::Float32', 'vtkm::Float32' if returntype == None else returntype, 'VTKM_SYS_MATH_FUNCTION_32(' + sysname + ')(x)') + \ unary_function(vtkmname, 'vtkm::Float64', 'vtkm::Float64' if returntype == None else returntype, 'VTKM_SYS_MATH_FUNCTION_64(' + sysname + ')(x)') def unary_math_function(vtkmname, sysname): return unary_math_function_no_vec(vtkmname, sysname) + \ unary_Vec_function(vtkmname) def unary_template_function_no_vec(vtkmname, expression, returntype = None, preexpression = ''): return '''VTKM_EXEC_CONT_EXPORT {2} {0}(vtkm::Float32 x) {{ {3} return {1}; }} '''.format(vtkmname, expression, 'vtkm::Float32' if returntype == None else returntype, preexpression) + \ '''VTKM_EXEC_CONT_EXPORT {2} {0}(vtkm::Float64 x) {{ {3} return {1}; }} '''.format(vtkmname, expression, 'vtkm::Float64' if returntype == None else returntype, preexpression) def binary_function(name, type, expression): return '''VTKM_EXEC_CONT_EXPORT {1} {0}({1} x, {1} y) {{ return {2}; }} '''.format(name, type, expression) def binary_math_function(vtkmname, sysname): return binary_function(vtkmname, 'vtkm::Float32', 'VTKM_SYS_MATH_FUNCTION_32(' + sysname + ')(x,y)') + \ binary_function(vtkmname, 'vtkm::Float64', 'VTKM_SYS_MATH_FUNCTION_64(' + sysname + ')(x,y)') def binary_template_function(vtkmname, expression): return '''VTKM_EXEC_CONT_EXPORT vtkm::Float32 {0}(vtkm::Float32 x, vtkm::Float32 y) {{ return {1}; }} VTKM_EXEC_CONT_EXPORT vtkm::Float64 {0}(vtkm::Float64 x, vtkm::Float64 y) {{ return {1}; }} '''.format(vtkmname, expression) ) $extend(unary_math_function) $extend(unary_math_function_no_vec) $extend(unary_Vec_function) $extend(unary_template_function_no_vec) $extend(binary_math_function) $extend(binary_template_function) namespace vtkm { //----------------------------------------------------------------------------- /// Returns the constant 2 times Pi. /// VTKM_EXEC_CONT_EXPORT vtkm::Float64 TwoPi() { return 6.28318530717958647692528676655900576; } /// Returns the constant Pi. /// VTKM_EXEC_CONT_EXPORT vtkm::Float64 Pi() { return 3.14159265358979323846264338327950288; } /// Returns the constant Pi halves. /// VTKM_EXEC_CONT_EXPORT vtkm::Float64 Pi_2() { return 1.57079632679489661923132169163975144; } /// Returns the constant Pi thirds. /// VTKM_EXEC_CONT_EXPORT vtkm::Float64 Pi_3() { return 1.04719755119659774615421446109316762; } /// Returns the constant Pi fourths. /// VTKM_EXEC_CONT_EXPORT vtkm::Float64 Pi_4() { return 0.78539816339744830961566084581987572; } /// Compute the sine of \p x. /// $unary_math_function('Sin', 'sin')\ /// Compute the cosine of \p x. /// $unary_math_function('Cos', 'cos')\ /// Compute the tangent of \p x. /// $unary_math_function('Tan', 'tan')\ /// Compute the arc sine of \p x. /// $unary_math_function('ASin', 'asin')\ /// Compute the arc cosine of \p x. /// $unary_math_function('ACos', 'acos')\ /// Compute the arc tangent of \p x. /// $unary_math_function('ATan', 'atan')\ /// Compute the arc tangent of \p x / \p y using the signs of both arguments /// to determine the quadrant of the return value. /// $binary_math_function('ATan2', 'atan2')\ /// Compute the hyperbolic sine of \p x. /// $unary_math_function('SinH', 'sinh')\ /// Compute the hyperbolic cosine of \p x. /// $unary_math_function('CosH', 'cosh')\ /// Compute the hyperbolic tangent of \p x. /// $unary_math_function('TanH', 'tanh')\ /// Compute the hyperbolic arc sine of \p x. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('ASinH', 'boost::math::asinh(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('ASinH', 'asinh')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('ASinH')\ /// Compute the hyperbolic arc cosine of \p x. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('ACosH', 'boost::math::acosh(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('ACosH', 'acosh')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('ACosH')\ /// Compute the hyperbolic arc tangent of \p x. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('ATanH', 'boost::math::atanh(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('ATanH', 'atanh')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('ATanH')\ //----------------------------------------------------------------------------- /// Computes \p x raised to the power of \p y. /// $binary_math_function('Pow', 'pow')\ /// Compute the square root of \p x. /// $unary_math_function('Sqrt', 'sqrt')\ /// Compute the reciprocal square root of \p x. The result of this function is /// equivalent to 1/Sqrt(x). However, on some devices it is faster to /// compute the reciprocal square root than the regular square root. Thus, you /// should use this function whenever dividing by the square root. /// #ifdef VTKM_CUDA $unary_math_function_no_vec('RSqrt', 'rsqrt')\ $# #else // !VTKM_CUDA $unary_template_function_no_vec('RSqrt', '1/vtkm::Sqrt(x)')\ $# #endif // !VTKM_CUDA $unary_Vec_function('RSqrt')\ /// Compute the cube root of \p x. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('Cbrt', 'boost::math::cbrt(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('Cbrt', 'cbrt')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('Cbrt')\ /// Compute the reciprocal cube root of \p x. The result of this function is /// equivalent to 1/Cbrt(x). However, on some devices it is faster to /// compute the reciprocal cube root than the regular cube root. Thus, you /// should use this function whenever dividing by the cube root. /// #ifdef VTKM_CUDA $unary_math_function_no_vec('RCbrt', 'rcbrt')\ $# #else // !VTKM_CUDA $unary_template_function_no_vec('RCbrt', '1/vtkm::Cbrt(x)')\ $# #endif // !VTKM_CUDA $unary_Vec_function('RCbrt')\ /// Computes e**\p x, the base-e exponential of \p x. /// $unary_math_function('Exp', 'exp')\ /// Computes 2**\p x, the base-2 exponential of \p x. /// #ifdef VTKM_MSVC $unary_template_function_no_vec('Exp2', 'vtkm::Pow(2,x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('Exp2', 'exp2')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('Exp2')\ /// Computes (e**\p x) - 1, the of base-e exponental of \p x then minus 1. The /// accuracy of this function is good even for very small values of x. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('ExpM1', 'boost::math::expm1(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('ExpM1', 'expm1')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('ExpM1')\ /// Computes 10**\p x, the base-10 exponential of \p x. /// #ifdef VTKM_CUDA $unary_math_function_no_vec('Exp10', 'exp10')\ $# #else // !VTKM_CUDA $unary_template_function_no_vec('Exp10', 'vtkm::Pow(10, x);')\ $# #endif // !VTKM_CUDA $unary_Vec_function('Exp10')\ /// Computes the natural logarithm of \p x. /// $unary_math_function('Log', 'log')\ /// Computes the logarithm base 2 of \p x. /// #ifdef VTKM_MSVC VTKM_EXEC_CONT_EXPORT vtkm::Float32 Log2(vtkm::Float32 x) { //windows and boost don't provide log2 //0.6931471805599453 is the constant value of log(2) const vtkm::Float32 log2v = 0.6931471805599453f; return vtkm::Log(x)/log2v; } VTKM_EXEC_CONT_EXPORT vtkm::Float64 Log2(vtkm::Float64 x) { //windows and boost don't provide log2 //0.6931471805599453 is the constant value of log(2) const vtkm::Float64 log2v = 0.6931471805599453; return vtkm::Log(x)/log2v; } #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('Log2', 'log2')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('Log2')\ /// Computes the logarithm base 10 of \p x. /// $unary_math_function('Log10', 'log10')\ /// Computes the value of log(1+x) accurately for very small values of x. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('Log1P', 'boost::math::log1p(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('Log1P', 'log1p')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('Log1P')\ //----------------------------------------------------------------------------- /// Returns \p x or \p y, whichever is larger. /// template VTKM_EXEC_CONT_EXPORT T Max(const T &x, const T &y); #ifdef VTKM_USE_STL_MIN_MAX $binary_template_function('Max', '(std::max)(x, y)')\ $# #else // !VTKM_USE_STL_MIN_MAX $binary_math_function('Max', 'fmax')\ $# #endif // !VTKM_USE_STL_MIN_MAX /// Returns \p x or \p y, whichever is smaller. /// template VTKM_EXEC_CONT_EXPORT T Min(const T &x, const T &y); #ifdef VTKM_USE_STL_MIN_MAX $binary_template_function('Min', '(std::min)(x, y)')\ $# #else // !VTKM_USE_STL_MIN_MAX $binary_math_function('Min', 'fmin')\ $# #endif // !VTKM_USE_STL_MIN_MAX namespace detail { template VTKM_EXEC_CONT_EXPORT T Max(T x, T y, vtkm::TypeTraitsScalarTag) { return (x < y) ? y : x; } template VTKM_EXEC_CONT_EXPORT T Max(const T &x, const T &y, vtkm::TypeTraitsVectorTag) { typedef vtkm::VecTraits Traits; T result; for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++) { Traits::SetComponent(result, index, vtkm::Max(Traits::GetComponent(x, index), Traits::GetComponent(y, index))); } return result; } template VTKM_EXEC_CONT_EXPORT T Min(T x, T y, vtkm::TypeTraitsScalarTag) { return (x < y) ? x : y; } template VTKM_EXEC_CONT_EXPORT T Min(const T &x, const T &y, vtkm::TypeTraitsVectorTag) { typedef vtkm::VecTraits Traits; T result; for (vtkm::IdComponent index = 0; index < Traits::NUM_COMPONENTS; index++) { Traits::SetComponent(result, index, vtkm::Min(Traits::GetComponent(x, index), Traits::GetComponent(y, index))); } return result; } } // namespace detail /// Returns \p x or \p y, whichever is larger. /// template VTKM_EXEC_CONT_EXPORT T Max(const T &x, const T &y) { return detail::Max(x, y, typename vtkm::TypeTraits::DimensionalityTag()); } /// Returns \p x or \p y, whichever is smaller. /// template VTKM_EXEC_CONT_EXPORT T Min(const T &x, const T &y) { return detail::Min(x, y, typename vtkm::TypeTraits::DimensionalityTag()); } //----------------------------------------------------------------------------- //#ifdef VTKM_CUDA #define VTKM_USE_IEEE_NONFINITE //#endif #ifdef VTKM_USE_IEEE_NONFINITE namespace detail { union IEEE754Bits32 { vtkm::UInt32 bits; vtkm::Float32 scalar; }; #define VTKM_NAN_BITS_32 0x7FC00000 #define VTKM_INF_BITS_32 0x7F800000 #define VTKM_NEG_INF_BITS_32 0xFF800000 #define VTKM_EPSILON_32 1e-5f union IEEE754Bits64 { vtkm::UInt64 bits; vtkm::Float64 scalar; }; #define VTKM_NAN_BITS_64 0x7FF8000000000000LL #define VTKM_INF_BITS_64 0x7FF0000000000000LL #define VTKM_NEG_INF_BITS_64 0xFFF0000000000000LL #define VTKM_EPSILON_64 1e-9 template struct FloatLimits; template<> struct FloatLimits { typedef vtkm::detail::IEEE754Bits32 BitsType; VTKM_EXEC_CONT_EXPORT static vtkm::Float32 Nan() { BitsType nan = {VTKM_NAN_BITS_32}; return nan.scalar; } VTKM_EXEC_CONT_EXPORT static vtkm::Float32 Infinity() { BitsType inf = {VTKM_INF_BITS_32}; return inf.scalar; } VTKM_EXEC_CONT_EXPORT static vtkm::Float32 NegativeInfinity() { BitsType neginf = {VTKM_NEG_INF_BITS_32}; return neginf.scalar; } VTKM_EXEC_CONT_EXPORT static vtkm::Float32 Epsilon() { return VTKM_EPSILON_32; } }; template<> struct FloatLimits { typedef vtkm::detail::IEEE754Bits64 BitsType; VTKM_EXEC_CONT_EXPORT static vtkm::Float64 Nan() { BitsType nan = {VTKM_NAN_BITS_64}; return nan.scalar; } VTKM_EXEC_CONT_EXPORT static vtkm::Float64 Infinity() { BitsType inf = {VTKM_INF_BITS_64}; return inf.scalar; } VTKM_EXEC_CONT_EXPORT static vtkm::Float64 NegativeInfinity() { BitsType neginf = {VTKM_NEG_INF_BITS_64}; return neginf.scalar; } VTKM_EXEC_CONT_EXPORT static vtkm::Float64 Epsilon() { return VTKM_EPSILON_64; } }; #undef VTKM_NAN_BITS_32 #undef VTKM_INF_BITS_32 #undef VTKM_NEG_INF_BITS_32 #undef VTKM_EPSILON_32 #undef VTKM_NAN_BITS_64 #undef VTKM_INF_BITS_64 #undef VTKM_NEG_INF_BITS_64 #undef VTKM_EPSILON_64 } // namespace detail /// Returns the representation for not-a-number (NaN). /// template VTKM_EXEC_CONT_EXPORT T Nan() { return detail::FloatLimits::Nan(); } /// Returns the representation for infinity. /// template VTKM_EXEC_CONT_EXPORT T Infinity() { return detail::FloatLimits::Infinity(); } /// Returns the representation for negative infinity. /// template VTKM_EXEC_CONT_EXPORT T NegativeInfinity() { return detail::FloatLimits::NegativeInfinity(); } /// Returns the difference between 1 and the least value greater than 1 /// that is representable. /// template VTKM_EXEC_CONT_EXPORT T Epsilon() { return detail::FloatLimits::Epsilon(); } #else // !VTKM_USE_IEEE_NONFINITE /// Returns the representation for not-a-number (NaN). /// template VTKM_EXEC_CONT_EXPORT T Nan() { return std::numeric_limits::quiet_NaN(); } /// Returns the representation for infinity. /// template VTKM_EXEC_CONT_EXPORT T Infinity() { return std::numeric_limits::infinity(); } /// Returns the representation for negative infinity. /// template VTKM_EXEC_CONT_EXPORT T NegativeInfinity() { return -std::numeric_limits::infinity(); } /// Returns the difference between 1 and the least value greater than 1 /// that is representable. /// template VTKM_EXEC_CONT_EXPORT T Epsilon() { return std::numeric_limits::epsilon(); } #endif // !VTKM_USE_IEEE_NONFINITE /// Returns the representation for not-a-number (NaN). /// VTKM_EXEC_CONT_EXPORT vtkm::Float32 Nan32() { return vtkm::Nan(); } VTKM_EXEC_CONT_EXPORT vtkm::Float64 Nan64() { return vtkm::Nan(); } /// Returns the representation for infinity. /// VTKM_EXEC_CONT_EXPORT vtkm::Float32 Infinity32() { return vtkm::Infinity(); } VTKM_EXEC_CONT_EXPORT vtkm::Float64 Infinity64() { return vtkm::Infinity(); } /// Returns the representation for negative infinity. /// VTKM_EXEC_CONT_EXPORT vtkm::Float32 NegativeInfinity32() { return vtkm::NegativeInfinity(); } VTKM_EXEC_CONT_EXPORT vtkm::Float64 NegativeInfinity64() { return vtkm::NegativeInfinity(); } /// Returns the difference between 1 and the least value greater than 1 /// that is representable. /// VTKM_EXEC_CONT_EXPORT vtkm::Float32 Epsilon32() { return vtkm::Epsilon(); } VTKM_EXEC_CONT_EXPORT vtkm::Float64 Epsilon64() { return vtkm::Epsilon(); } //----------------------------------------------------------------------------- /// Returns true if \p x is not a number. /// template VTKM_EXEC_CONT_EXPORT bool IsNan(T x) { #ifdef VTKM_USE_BOOST_CLASSIFY using boost::math::isnan; #endif return (isnan(x) != 0); } /// Returns true if \p x is positive or negative infinity. /// template VTKM_EXEC_CONT_EXPORT bool IsInf(T x) { #ifdef VTKM_USE_BOOST_CLASSIFY using boost::math::isinf; #endif return (isinf(x) != 0); } /// Returns true if \p x is a normal number (not NaN or infinite). /// template VTKM_EXEC_CONT_EXPORT bool IsFinite(T x) { #ifdef VTKM_USE_BOOST_CLASSIFY using boost::math::isfinite; #endif return (isfinite(x) != 0); } //----------------------------------------------------------------------------- /// Round \p x to the smallest integer value not less than x. /// $unary_math_function('Ceil', 'ceil')\ /// Round \p x to the largest integer value not greater than x. /// $unary_math_function('Floor', 'floor')\ /// Round \p x to the nearest integral value. /// #ifdef VTKM_USE_BOOST_MATH $unary_template_function_no_vec('Round', 'boost::math::round(x)')\ $# #else // !VTKM_USE_BOOST_MATH $unary_math_function_no_vec('Round', 'round')\ $# #endif // !VTKM_USE_BOOST_MATH $unary_Vec_function('Round')\ //----------------------------------------------------------------------------- /// Computes the remainder on division of 2 floating point numbers. The return /// value is \p numerator - n \p denominator, where n is the quotient of \p /// numerator divided by \p denominator rounded towards zero to an integer. For /// example, FMod(6.5, 2.3) returns 1.9, which is 6.5 - 2*2.3. /// $binary_math_function('FMod', 'fmod')\ /// Computes the remainder on division of 2 floating point numbers. The return /// value is \p numerator - n \p denominator, where n is the quotient of \p /// numerator divided by \p denominator rounded towards the nearest integer /// (instead of toward zero like FMod). For example, FMod(6.5, 2.3) /// returns -0.4, which is 6.5 - 3*2.3. /// #ifdef VTKM_MSVC template VTKM_EXEC_CONT_EXPORT T Remainder(T numerator, T denominator) { T quotient = vtkm::Round(numerator/denominator); return numerator - quotient*denominator; } #else // !VTKM_MSVC $binary_math_function('Remainder', 'remainder')\ $# #endif // !VTKM_MSVC /// Returns the remainder on division of 2 floating point numbers just like /// Remainder. In addition, this function also returns the \c quotient used to /// get that remainder. /// template VTKM_EXEC_CONT_EXPORT vtkm::Float32 RemainderQuotient(vtkm::Float32 numerator, vtkm::Float32 denominator, QType "ient) { #ifdef VTKM_USE_BOOST_MATH quotient = static_cast(boost::math::round(numerator/denominator)); return vtkm::Remainder(numerator, denominator); #else int iQuotient; vtkm::Float32 result = VTKM_SYS_MATH_FUNCTION_32(remquo)(numerator, denominator, &iQuotient); quotient = iQuotient; return result; #endif } template VTKM_EXEC_CONT_EXPORT vtkm::Float64 RemainderQuotient(vtkm::Float64 numerator, vtkm::Float64 denominator, QType "ient) { #ifdef VTKM_USE_BOOST_MATH quotient = static_cast(boost::math::round(numerator/denominator)); return vtkm::Remainder(numerator, denominator); #else int iQuotient; vtkm::Float64 result = VTKM_SYS_MATH_FUNCTION_64(remquo)(numerator, denominator, &iQuotient); quotient = iQuotient; return result; #endif } /// Gets the integral and fractional parts of \c x. The return value is the /// fractional part and \c integral is set to the integral part. /// VTKM_EXEC_CONT_EXPORT vtkm::Float32 ModF(vtkm::Float32 x, vtkm::Float32 &integral) { return VTKM_SYS_MATH_FUNCTION_32(modf)(x, &integral); } VTKM_EXEC_CONT_EXPORT vtkm::Float64 ModF(vtkm::Float64 x, vtkm::Float64 &integral) { return VTKM_SYS_MATH_FUNCTION_64(modf)(x, &integral); } //----------------------------------------------------------------------------- /// Return the absolute value of \p x. That is, return \p x if it is positive or /// \p -x if it is negative. /// VTKM_EXEC_CONT_EXPORT vtkm::Int32 Abs(vtkm::Int32 x) { #if VTKM_SIZE_INT == 4 return abs(x); #else #error Unknown size of Int32. #endif } VTKM_EXEC_CONT_EXPORT vtkm::Int64 Abs(vtkm::Int64 x) { #if VTKM_SIZE_LONG == 8 return labs(x); #elif VTKM_SIZE_LONG_LONG == 8 return llabs(x); #else #error Unknown size of Int64. #endif } $unary_math_function('Abs', 'fabs')\ /// Returns a nonzero value if \p x is negative. /// $unary_template_function_no_vec('SignBit', 'static_cast(signbit(x))', 'vtkm::Int32', '''#ifdef VTKM_USE_BOOST_SIGN using boost::math::signbit; #endif ''')\ /// Returns true if \p x is less than zero, false otherwise. /// $unary_template_function_no_vec('IsNegative', '(vtkm::SignBit(x) != 0)', 'bool')\ /// Copies the sign of \p y onto \p x. If \p y is positive, returns Abs(\p x). /// If \p y is negative, returns -Abs(\p x). /// #ifdef VTKM_USE_BOOST_SIGN $binary_template_function('CopySign', 'boost::math::copysign(x,y)')\ $# #else // !VTKM_USE_BOOST_SIGN $binary_math_function('CopySign', 'copysign')\ $# #endif // !VTKM_USE_BOOST_SIGN template VTKM_EXEC_CONT_EXPORT vtkm::Vec CopySign(const vtkm::Vec &x, const vtkm::Vec &y) { vtkm::Vec result; for (vtkm::IdComponent index = 0; index < N; index++) { result[index] = vtkm::CopySign(x[index], y[index]); } return result; } } // namespace vtkm #endif //vtk_m_Math_h