Add component-wise Min/Max methods for Vec classes.

This commit is contained in:
Kenneth Moreland 2015-07-22 13:27:44 -04:00
parent d9607dac6e
commit 13023792c4
3 changed files with 155 additions and 18 deletions

@ -26,6 +26,8 @@
#define vtk_m_Math_h
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/VecTraits.h>
#ifndef VTKM_CUDA
#include <limits.h>
@ -1251,9 +1253,7 @@ vtkm::Vec<T,2> Log1P(const vtkm::Vec<T,2> &x) {
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Max(const T &x, const T &y) {
return (x < y) ? y : x;
}
T Max(const T &x, const T &y);
#ifdef VTKM_USE_STL_MIN_MAX
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 Max(vtkm::Float32 x, vtkm::Float32 y) {
@ -1278,9 +1278,7 @@ vtkm::Float64 Max(vtkm::Float64 x, vtkm::Float64 y) {
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Min(const T &x, const T &y) {
return (x < y) ? x : y;
}
T Min(const T &x, const T &y);
#ifdef VTKM_USE_STL_MIN_MAX
VTKM_EXEC_CONT_EXPORT
vtkm::Float32 Min(vtkm::Float32 x, vtkm::Float32 y) {
@ -1301,6 +1299,72 @@ vtkm::Float64 Min(vtkm::Float64 x, vtkm::Float64 y) {
}
#endif // !VTKM_USE_BOOST_MATH
namespace detail {
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Max(T x, T y, vtkm::TypeTraitsScalarTag)
{
return (x < y) ? y : x;
}
template<typename T>
VTKM_EXEC_CONT_EXPORT
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>
VTKM_EXEC_CONT_EXPORT
T Min(T x, T y, vtkm::TypeTraitsScalarTag)
{
return (x < y) ? x : y;
}
template<typename T>
VTKM_EXEC_CONT_EXPORT
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>
VTKM_EXEC_CONT_EXPORT
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>
VTKM_EXEC_CONT_EXPORT
T Min(const T &x, const T &y) {
return detail::Min(x, y, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
//-----------------------------------------------------------------------------

@ -38,6 +38,8 @@ $# Ignore the following comment. It is meant for the generated file.
#define vtk_m_Math_h
#include <vtkm/Types.h>
#include <vtkm/TypeTraits.h>
#include <vtkm/VecTraits.h>
#ifndef VTKM_CUDA
#include <limits.h>
@ -401,9 +403,7 @@ $unary_Vec_function('Log1P')\
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Max(const T &x, const T &y) {
return (x < y) ? y : x;
}
T Max(const T &x, const T &y);
#ifdef VTKM_USE_STL_MIN_MAX
$binary_template_function('Max', '(std::max)(x, y)')\
$#
@ -416,9 +416,7 @@ $#
///
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Min(const T &x, const T &y) {
return (x < y) ? x : y;
}
T Min(const T &x, const T &y);
#ifdef VTKM_USE_STL_MIN_MAX
$binary_template_function('Min', '(std::min)(x, y)')\
$#
@ -427,6 +425,72 @@ $binary_math_function('Min', 'fmin')\
$#
#endif // !VTKM_USE_BOOST_MATH
namespace detail {
template<typename T>
VTKM_EXEC_CONT_EXPORT
T Max(T x, T y, vtkm::TypeTraitsScalarTag)
{
return (x < y) ? y : x;
}
template<typename T>
VTKM_EXEC_CONT_EXPORT
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>
VTKM_EXEC_CONT_EXPORT
T Min(T x, T y, vtkm::TypeTraitsScalarTag)
{
return (x < y) ? x : y;
}
template<typename T>
VTKM_EXEC_CONT_EXPORT
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>
VTKM_EXEC_CONT_EXPORT
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>
VTKM_EXEC_CONT_EXPORT
T Min(const T &x, const T &y) {
return detail::Min(x, y, typename vtkm::TypeTraits<T>::DimensionalityTag());
}
//-----------------------------------------------------------------------------

@ -675,7 +675,7 @@ struct TryScalarVectorFieldTests
//-----------------------------------------------------------------------------
template<typename T>
struct AllScalarTests : public vtkm::exec::FunctorBase
struct AllTypesTests : public vtkm::exec::FunctorBase
{
VTKM_EXEC_EXPORT
void TestMinMax() const
@ -687,6 +687,16 @@ struct AllScalarTests : public vtkm::exec::FunctorBase
VTKM_MATH_ASSERT(test_equal(vtkm::Min(high, low), low), "Wrong min.");
VTKM_MATH_ASSERT(test_equal(vtkm::Max(low, high), high), "Wrong max.");
VTKM_MATH_ASSERT(test_equal(vtkm::Max(high, low), high), "Wrong max.");
typedef vtkm::VecTraits<T> Traits;
T mixed1 = low;
T mixed2 = high;
Traits::SetComponent(mixed1, 0, Traits::GetComponent(high, 0));
Traits::SetComponent(mixed2, 0, Traits::GetComponent(low, 0));
VTKM_MATH_ASSERT(test_equal(vtkm::Min(mixed1, mixed2), low), "Wrong min.");
VTKM_MATH_ASSERT(test_equal(vtkm::Min(mixed2, mixed1), low), "Wrong min.");
VTKM_MATH_ASSERT(test_equal(vtkm::Max(mixed1, mixed2), high), "Wrong max.");
VTKM_MATH_ASSERT(test_equal(vtkm::Max(mixed2, mixed1), high), "Wrong max.");
}
VTKM_EXEC_EXPORT
@ -697,13 +707,13 @@ struct AllScalarTests : public vtkm::exec::FunctorBase
};
template<typename Device>
struct TryAllScalarTests
struct TryAllTypesTests
{
template<typename T>
void operator()(const T&) const
{
vtkm::cont::DeviceAdapterAlgorithm<Device>::Schedule(
AllScalarTests<T>(), 1);
AllTypesTests<T>(), 1);
}
};
@ -752,9 +762,8 @@ void RunMathTests()
std::cout << "Test for scalar and vector types." << std::endl;
vtkm::testing::Testing::TryTypes(TryScalarVectorFieldTests<Device>(),
vtkm::TypeListTagField());
std::cout << "Test for all basic types." << std::endl;
vtkm::testing::Testing::TryTypes(TryAllScalarTests<Device>(),
vtkm::TypeListTagScalarAll());
std::cout << "Test for all types." << std::endl;
vtkm::testing::Testing::TryAllTypes(TryAllTypesTests<Device>());
std::cout << "Test all Abs types" << std::endl;
vtkm::testing::Testing::TryTypes(TryAbsTests<Device>(),
TypeListTagAbs());