fdaccc22db
Change the VTKM_CONT_EXPORT to VTKM_CONT. (Likewise for EXEC and EXEC_CONT.) Remove the inline from these macros so that they can be applied to everything, including implementations in a library. Because inline is not declared in these modifies, you have to add the keyword to functions and methods where the implementation is not inlined in the class.
957 lines
24 KiB
C
957 lines
24 KiB
C
//=============================================================================
|
|
//
|
|
// 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 Math.h.in
|
|
|
|
#ifndef vtk_m_Math_h
|
|
#define vtk_m_Math_h
|
|
|
|
#include <vtkm/Types.h>
|
|
#include <vtkm/TypeTraits.h>
|
|
#include <vtkm/VecTraits.h>
|
|
|
|
#ifndef VTKM_CUDA
|
|
#include <limits.h>
|
|
#include <math.h>
|
|
#include <stdlib.h>
|
|
#include <cmath>
|
|
#endif // !VTKM_CUDA
|
|
|
|
#if !defined(__CUDA_ARCH__)
|
|
#define VTKM_USE_STL
|
|
#include <algorithm>
|
|
#endif
|
|
|
|
#if defined(VTKM_MSVC) && !defined(VTKM_CUDA)
|
|
#include <math.h>
|
|
#endif
|
|
|
|
#define VTKM_CUDA_MATH_FUNCTION_32(func) func ## f
|
|
#define VTKM_CUDA_MATH_FUNCTION_64(func) func
|
|
|
|
$py(
|
|
def unary_function(name, type, returntype, cuda_expression, std_expression):
|
|
return '''static inline VTKM_EXEC_CONT
|
|
{2} {0}({1} x) {{
|
|
#ifdef VTKM_CUDA
|
|
return {3};
|
|
#else
|
|
return {4};
|
|
#endif
|
|
}}
|
|
'''.format(name, type, returntype, cuda_expression, std_expression)
|
|
|
|
def unary_Vec_function(vtkmname):
|
|
return '''template<typename T, vtkm::IdComponent N>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Vec<T,N> {0}(const vtkm::Vec<T,N> &x) {{
|
|
vtkm::Vec<T,N> result;
|
|
for (vtkm::IdComponent index = 0; index < N; index++)
|
|
{{
|
|
result[index] = vtkm::{0}(x[index]);
|
|
}}
|
|
return result;
|
|
}}
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Vec<T,4> {0}(const vtkm::Vec<T,4> &x) {{
|
|
return vtkm::Vec<T,4>(vtkm::{0}(x[0]),
|
|
vtkm::{0}(x[1]),
|
|
vtkm::{0}(x[2]),
|
|
vtkm::{0}(x[3]));
|
|
}}
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Vec<T,3> {0}(const vtkm::Vec<T,3> &x) {{
|
|
return vtkm::Vec<T,3>(vtkm::{0}(x[0]),
|
|
vtkm::{0}(x[1]),
|
|
vtkm::{0}(x[2]));
|
|
}}
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Vec<T,2> {0}(const vtkm::Vec<T,2> &x) {{
|
|
return vtkm::Vec<T,2>(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_CUDA_MATH_FUNCTION_32(' + sysname + ')(x)',
|
|
'std::' + sysname + '(x)') + \
|
|
unary_function(vtkmname,
|
|
'vtkm::Float64',
|
|
'vtkm::Float64' if returntype == None else returntype,
|
|
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x)',
|
|
'std::' + 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 '''static inline VTKM_EXEC_CONT
|
|
{2} {0}(vtkm::Float32 x) {{
|
|
{3} return {1};
|
|
}}
|
|
'''.format(vtkmname,
|
|
expression,
|
|
'vtkm::Float32' if returntype == None else returntype,
|
|
preexpression) + \
|
|
'''static inline VTKM_EXEC_CONT
|
|
{2} {0}(vtkm::Float64 x) {{
|
|
{3} return {1};
|
|
}}
|
|
'''.format(vtkmname,
|
|
expression,
|
|
'vtkm::Float64' if returntype == None else returntype,
|
|
preexpression)
|
|
|
|
def binary_function(name, type, cuda_expression, std_expression):
|
|
return '''static inline VTKM_EXEC_CONT
|
|
{1} {0}({1} x, {1} y) {{
|
|
#ifdef VTKM_CUDA
|
|
return {2};
|
|
#else
|
|
return {3};
|
|
#endif
|
|
}}
|
|
'''.format(name, type, cuda_expression, std_expression)
|
|
|
|
def binary_math_function(vtkmname, sysname):
|
|
return binary_function(vtkmname,
|
|
'vtkm::Float32',
|
|
'VTKM_CUDA_MATH_FUNCTION_32(' + sysname + ')(x,y)',
|
|
'std::' + sysname + '(x,y)') + \
|
|
binary_function(vtkmname,
|
|
'vtkm::Float64',
|
|
'VTKM_CUDA_MATH_FUNCTION_64(' + sysname + ')(x,y)',
|
|
'std::' + sysname + '(x,y)')
|
|
|
|
def binary_template_function(vtkmname, expression):
|
|
return '''static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 {0}(vtkm::Float32 x, vtkm::Float32 y) {{
|
|
return {1};
|
|
}}
|
|
static inline VTKM_EXEC_CONT
|
|
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.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 TwoPi()
|
|
{
|
|
return 6.28318530717958647692528676655900576;
|
|
}
|
|
|
|
/// Returns the constant Pi.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 Pi()
|
|
{
|
|
return 3.14159265358979323846264338327950288;
|
|
}
|
|
|
|
/// Returns the constant Pi halves.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 Pi_2()
|
|
{
|
|
return 1.57079632679489661923132169163975144;
|
|
}
|
|
/// Returns the constant Pi thirds.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 Pi_3()
|
|
{
|
|
return 1.04719755119659774615421446109316762;
|
|
}
|
|
|
|
/// Returns the constant Pi fourths.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
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.
|
|
///
|
|
$unary_math_function_no_vec('ASinH', 'asinh')\
|
|
$#
|
|
$unary_Vec_function('ASinH')\
|
|
|
|
/// Compute the hyperbolic arc cosine of \p x.
|
|
///
|
|
$unary_math_function_no_vec('ACosH', 'acosh')\
|
|
$#
|
|
$unary_Vec_function('ACosH')\
|
|
|
|
/// Compute the hyperbolic arc tangent of \p x.
|
|
///
|
|
$unary_math_function_no_vec('ATanH', 'atanh')\
|
|
$#
|
|
$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 <tt>1/Sqrt(x)</tt>. 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
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 RSqrt(vtkm::Float32 x) {
|
|
return rsqrtf(x);
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 RSqrt(vtkm::Float64 x) {
|
|
return rsqrt(x);
|
|
}
|
|
#else // !VTKM_CUDA
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 RSqrt(vtkm::Float32 x) {
|
|
return 1/vtkm::Sqrt(x);
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 RSqrt(vtkm::Float64 x) {
|
|
return 1/vtkm::Sqrt(x);
|
|
}
|
|
#endif // !VTKM_CUDA
|
|
|
|
$unary_Vec_function('RSqrt')\
|
|
|
|
/// Compute the cube root of \p x.
|
|
///
|
|
$unary_math_function_no_vec('Cbrt', 'cbrt')\
|
|
$#
|
|
$unary_Vec_function('Cbrt')\
|
|
|
|
/// Compute the reciprocal cube root of \p x. The result of this function is
|
|
/// equivalent to <tt>1/Cbrt(x)</tt>. 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
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 RCbrt(vtkm::Float32 x) {
|
|
return rcbrtf(x);
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 RCbrt(vtkm::Float64 x) {
|
|
return rcbrt(x);
|
|
}
|
|
#else // !VTKM_CUDA
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 RCbrt(vtkm::Float32 x) {
|
|
return 1/vtkm::Cbrt(x);
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 RCbrt(vtkm::Float64 x) {
|
|
return 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.
|
|
///
|
|
$unary_math_function_no_vec('Exp2', 'exp2')\
|
|
$#
|
|
$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.
|
|
///
|
|
$unary_math_function_no_vec('ExpM1', 'expm1')\
|
|
$#
|
|
$unary_Vec_function('ExpM1')\
|
|
|
|
/// Computes 10**\p x, the base-10 exponential of \p x.
|
|
///
|
|
#ifdef VTKM_CUDA
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 Exp10(vtkm::Float32 x) {
|
|
return exp10f(x);
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 Exp10(vtkm::Float64 x) {
|
|
return exp10(x);
|
|
}
|
|
#else // !VTKM_CUDA
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 Exp10(vtkm::Float32 x) {
|
|
return vtkm::Pow(10, x);;
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 Exp10(vtkm::Float64 x) {
|
|
return 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.
|
|
///
|
|
$unary_math_function_no_vec('Log2', 'log2')\
|
|
$#
|
|
$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.
|
|
///
|
|
$unary_math_function_no_vec('Log1P', 'log1p')\
|
|
$#
|
|
$unary_Vec_function('Log1P')\
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/// Returns \p x or \p y, whichever is larger.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Max(const T &x, const T &y);
|
|
#ifdef VTKM_USE_STL
|
|
$binary_template_function('Max', '(std::max)(x, y)')\
|
|
$#
|
|
#else // !VTKM_USE_STL
|
|
$binary_math_function('Max', 'fmax')\
|
|
$#
|
|
#endif // !VTKM_USE_STL
|
|
|
|
/// Returns \p x or \p y, whichever is smaller.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Min(const T &x, const T &y);
|
|
#ifdef VTKM_USE_STL
|
|
$binary_template_function('Min', '(std::min)(x, y)')\
|
|
$#
|
|
#else // !VTKM_USE_STL
|
|
$binary_math_function('Min', 'fmin')\
|
|
$#
|
|
#endif // !VTKM_USE_STL
|
|
|
|
namespace detail {
|
|
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Max(T x, T y, vtkm::TypeTraitsScalarTag)
|
|
{
|
|
return (x < y) ? y : x;
|
|
}
|
|
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Max(const T &x, const T &y, vtkm::TypeTraitsVectorTag)
|
|
{
|
|
typedef vtkm::VecTraits<T> 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<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Min(T x, T y, vtkm::TypeTraitsScalarTag)
|
|
{
|
|
return (x < y) ? x : y;
|
|
}
|
|
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Min(const T &x, const T &y, vtkm::TypeTraitsVectorTag)
|
|
{
|
|
typedef vtkm::VecTraits<T> 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<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Max(const T &x, const T &y) {
|
|
return detail::Max(x, y, typename vtkm::TypeTraits<T>::DimensionalityTag());
|
|
}
|
|
|
|
/// Returns \p x or \p y, whichever is smaller.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Min(const T &x, const T &y) {
|
|
return detail::Min(x, y, typename vtkm::TypeTraits<T>::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<typename T> struct FloatLimits;
|
|
|
|
template<>
|
|
struct FloatLimits<vtkm::Float32>
|
|
{
|
|
typedef vtkm::detail::IEEE754Bits32 BitsType;
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float32 Nan() {
|
|
BitsType nan = {VTKM_NAN_BITS_32};
|
|
return nan.scalar;
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float32 Infinity() {
|
|
BitsType inf = {VTKM_INF_BITS_32};
|
|
return inf.scalar;
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float32 NegativeInfinity() {
|
|
BitsType neginf = {VTKM_NEG_INF_BITS_32};
|
|
return neginf.scalar;
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float32 Epsilon() {
|
|
return VTKM_EPSILON_32;
|
|
}
|
|
};
|
|
|
|
template<int N>
|
|
struct FloatLimits< vtkm::Vec<vtkm::Float32,N> >
|
|
{
|
|
typedef vtkm::detail::IEEE754Bits32 BitsType;
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float32,N> Nan() {
|
|
BitsType nan = {VTKM_NAN_BITS_32};
|
|
return vtkm::Vec<vtkm::Float32,N>(nan.scalar);
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float32,N> Infinity() {
|
|
BitsType inf = {VTKM_INF_BITS_32};
|
|
return vtkm::Vec<vtkm::Float32,N>(inf.scalar);
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float32,N> NegativeInfinity() {
|
|
BitsType neginf = {VTKM_NEG_INF_BITS_32};
|
|
return vtkm::Vec<vtkm::Float32,N>(neginf.scalar);
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float32,N> Epsilon() {
|
|
return vtkm::Vec<vtkm::Float32,N>(VTKM_EPSILON_32);
|
|
}
|
|
};
|
|
|
|
template<>
|
|
struct FloatLimits<vtkm::Float64>
|
|
{
|
|
typedef vtkm::detail::IEEE754Bits64 BitsType;
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float64 Nan() {
|
|
BitsType nan = {VTKM_NAN_BITS_64};
|
|
return nan.scalar;
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float64 Infinity() {
|
|
BitsType inf = {VTKM_INF_BITS_64};
|
|
return inf.scalar;
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float64 NegativeInfinity() {
|
|
BitsType neginf = {VTKM_NEG_INF_BITS_64};
|
|
return neginf.scalar;
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Float64 Epsilon() {
|
|
return VTKM_EPSILON_64;
|
|
}
|
|
};
|
|
|
|
template<int N>
|
|
struct FloatLimits< vtkm::Vec<vtkm::Float64,N> >
|
|
{
|
|
typedef vtkm::detail::IEEE754Bits64 BitsType;
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float64,N> Nan() {
|
|
BitsType nan = {VTKM_NAN_BITS_64};
|
|
return vtkm::Vec<vtkm::Float64,N>(nan.scalar);
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float64,N> Infinity() {
|
|
BitsType inf = {VTKM_INF_BITS_64};
|
|
return vtkm::Vec<vtkm::Float64,N>(inf.scalar);
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float64,N> NegativeInfinity() {
|
|
BitsType neginf = {VTKM_NEG_INF_BITS_64};
|
|
return vtkm::Vec<vtkm::Float64,N>(neginf.scalar);
|
|
}
|
|
|
|
VTKM_EXEC_CONT
|
|
static vtkm::Vec<vtkm::Float64,N> Epsilon() {
|
|
return vtkm::Vec<vtkm::Float64,N>(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<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Nan()
|
|
{
|
|
return detail::FloatLimits<T>::Nan();
|
|
}
|
|
|
|
/// Returns the representation for infinity.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Infinity()
|
|
{
|
|
return detail::FloatLimits<T>::Infinity();
|
|
}
|
|
|
|
/// Returns the representation for negative infinity.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T NegativeInfinity()
|
|
{
|
|
return detail::FloatLimits<T>::NegativeInfinity();
|
|
}
|
|
|
|
/// Returns the difference between 1 and the least value greater than 1
|
|
/// that is representable.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Epsilon()
|
|
{
|
|
return detail::FloatLimits<T>::Epsilon();
|
|
}
|
|
|
|
#else // !VTKM_USE_IEEE_NONFINITE
|
|
|
|
/// Returns the representation for not-a-number (NaN).
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Nan()
|
|
{
|
|
return std::numeric_limits<T>::quiet_NaN();
|
|
}
|
|
|
|
/// Returns the representation for infinity.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Infinity()
|
|
{
|
|
return std::numeric_limits<T>::infinity();
|
|
}
|
|
|
|
/// Returns the representation for negative infinity.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T NegativeInfinity()
|
|
{
|
|
return -std::numeric_limits<T>::infinity();
|
|
}
|
|
|
|
/// Returns the difference between 1 and the least value greater than 1
|
|
/// that is representable.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
T Epsilon()
|
|
{
|
|
return std::numeric_limits<T>::epsilon();
|
|
}
|
|
#endif // !VTKM_USE_IEEE_NONFINITE
|
|
|
|
/// Returns the representation for not-a-number (NaN).
|
|
///
|
|
static inline VTKM_EXEC_CONT vtkm::Float32 Nan32() {
|
|
return vtkm::Nan<vtkm::Float32>();
|
|
}
|
|
static inline VTKM_EXEC_CONT vtkm::Float64 Nan64() {
|
|
return vtkm::Nan<vtkm::Float64>();
|
|
}
|
|
|
|
/// Returns the representation for infinity.
|
|
///
|
|
static inline VTKM_EXEC_CONT vtkm::Float32 Infinity32() {
|
|
return vtkm::Infinity<vtkm::Float32>();
|
|
}
|
|
static inline VTKM_EXEC_CONT vtkm::Float64 Infinity64() {
|
|
return vtkm::Infinity<vtkm::Float64>();
|
|
}
|
|
|
|
/// Returns the representation for negative infinity.
|
|
///
|
|
static inline VTKM_EXEC_CONT vtkm::Float32 NegativeInfinity32() {
|
|
return vtkm::NegativeInfinity<vtkm::Float32>();
|
|
}
|
|
static inline VTKM_EXEC_CONT vtkm::Float64 NegativeInfinity64() {
|
|
return vtkm::NegativeInfinity<vtkm::Float64>();
|
|
}
|
|
|
|
/// Returns the difference between 1 and the least value greater than 1
|
|
/// that is representable.
|
|
///
|
|
static inline VTKM_EXEC_CONT vtkm::Float32 Epsilon32()
|
|
{
|
|
return vtkm::Epsilon<vtkm::Float32>();
|
|
}
|
|
static inline VTKM_EXEC_CONT vtkm::Float64 Epsilon64()
|
|
{
|
|
return vtkm::Epsilon<vtkm::Float64>();
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
/// Returns true if \p x is not a number.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
bool IsNan(T x)
|
|
{
|
|
using std::isnan;
|
|
return (isnan(x) != 0);
|
|
}
|
|
|
|
/// Returns true if \p x is positive or negative infinity.
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
bool IsInf(T x)
|
|
{
|
|
using std::isinf;
|
|
return (isinf(x) != 0);
|
|
}
|
|
|
|
/// Returns true if \p x is a normal number (not NaN or infinite).
|
|
///
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
bool IsFinite(T x)
|
|
{
|
|
using std::isfinite;
|
|
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.
|
|
///
|
|
$unary_math_function_no_vec('Round', 'round')\
|
|
$#
|
|
$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, <tt>FMod(6.5, 2.3)</tt> 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, <tt>FMod(6.5, 2.3)</tt>
|
|
/// returns -0.4, which is 6.5 - 3*2.3.
|
|
///
|
|
#ifdef VTKM_MSVC
|
|
template<typename T>
|
|
static inline VTKM_EXEC_CONT
|
|
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<typename QType>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 RemainderQuotient(vtkm::Float32 numerator,
|
|
vtkm::Float32 denominator,
|
|
QType "ient)
|
|
{
|
|
int iQuotient;
|
|
vtkm::Float32 result = std::remquo(numerator, denominator, &iQuotient);
|
|
quotient = iQuotient;
|
|
return result;
|
|
}
|
|
template<typename QType>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 RemainderQuotient(vtkm::Float64 numerator,
|
|
vtkm::Float64 denominator,
|
|
QType "ient)
|
|
{
|
|
int iQuotient;
|
|
vtkm::Float64 result = std::remquo(numerator, denominator, &iQuotient);
|
|
quotient = iQuotient;
|
|
return result;
|
|
}
|
|
|
|
/// 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.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float32 ModF(vtkm::Float32 x, vtkm::Float32 &integral)
|
|
{
|
|
return std::modf(x, &integral);
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Float64 ModF(vtkm::Float64 x, vtkm::Float64 &integral)
|
|
{
|
|
return std::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.
|
|
///
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Int32 Abs(vtkm::Int32 x)
|
|
{
|
|
#if VTKM_SIZE_INT == 4
|
|
return abs(x);
|
|
#else
|
|
#error Unknown size of Int32.
|
|
#endif
|
|
}
|
|
static inline VTKM_EXEC_CONT
|
|
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<vtkm::Int32>(signbit(x))',
|
|
'vtkm::Int32',
|
|
'''
|
|
using std::signbit;
|
|
''')\
|
|
|
|
/// 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).
|
|
///
|
|
$binary_math_function('CopySign', 'copysign')\
|
|
$#
|
|
|
|
template<typename T, vtkm::IdComponent N>
|
|
static inline VTKM_EXEC_CONT
|
|
vtkm::Vec<T,N> CopySign(const vtkm::Vec<T,N> &x, const vtkm::Vec<T,N> &y)
|
|
{
|
|
vtkm::Vec<T,N> 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
|