From a50942e951d396c73be26e3fa690559e3ba51118 Mon Sep 17 00:00:00 2001 From: Eduardo Ponce Date: Tue, 25 May 2021 02:22:50 -0400 Subject: [PATCH 01/23] add sign function and tests --- cpp/src/arrow/compute/api_scalar.cc | 1 + cpp/src/arrow/compute/api_scalar.h | 10 ++ .../compute/kernels/scalar_arithmetic.cc | 76 +++++++++++ .../compute/kernels/scalar_arithmetic_test.cc | 118 ++++++++++++++++-- 4 files changed, 193 insertions(+), 12 deletions(-) diff --git a/cpp/src/arrow/compute/api_scalar.cc b/cpp/src/arrow/compute/api_scalar.cc index be6498a74c6..88832252e19 100644 --- a/cpp/src/arrow/compute/api_scalar.cc +++ b/cpp/src/arrow/compute/api_scalar.cc @@ -330,6 +330,7 @@ void RegisterScalarOptions(FunctionRegistry* registry) { SCALAR_ARITHMETIC_UNARY(AbsoluteValue, "abs", "abs_checked") SCALAR_ARITHMETIC_UNARY(Negate, "negate", "negate_checked") +SCALAR_EAGER_UNARY(Sign, "sign") SCALAR_ARITHMETIC_UNARY(Sin, "sin", "sin_checked") SCALAR_ARITHMETIC_UNARY(Cos, "cos", "cos_checked") SCALAR_ARITHMETIC_UNARY(Asin, "asin", "asin_checked") diff --git a/cpp/src/arrow/compute/api_scalar.h b/cpp/src/arrow/compute/api_scalar.h index f0aebc8e032..fa6b8c08d77 100644 --- a/cpp/src/arrow/compute/api_scalar.h +++ b/cpp/src/arrow/compute/api_scalar.h @@ -513,6 +513,16 @@ Result MinElementWise( ElementWiseAggregateOptions options = ElementWiseAggregateOptions::Defaults(), ExecContext* ctx = NULLPTR); +/// \brief Get the sign of a value. Array values can be of arbitrary length. If argument +/// is null the result will be null. +/// +/// \param[in] arg the value to extract sign from +/// \param[in] ctx the function execution context, optional +/// \return the elementwise sign function +ARROW_EXPORT +Result Sign(const Datum& arg, ArithmeticOptions options = ArithmeticOptions(), + ExecContext* ctx = NULLPTR); + /// \brief Compare a numeric array with a scalar. /// /// \param[in] left datum to compare, must be an Array diff --git a/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc b/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc index db73294e1fa..edcab9353ea 100644 --- a/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc +++ b/cpp/src/arrow/compute/kernels/scalar_arithmetic.cc @@ -462,6 +462,29 @@ struct PowerChecked { } }; +struct Sign { + template ::value, bool> = true> + static constexpr int8_t Call(KernelContext*, Arg arg, Status*) { + return std::signbit(arg) ? -1 : 1; + } + + template ::value, bool> = true> + static constexpr int8_t Call(KernelContext*, Arg arg, Status*) { + return arg ? 1 : 0; + } + + template ::value && std::is_signed::value, + bool> = true> + static int8_t Call(KernelContext*, Arg arg, Status*) { + if (arg > 0) return 1; + if (arg < 0) return -1; + return 0; + } +}; + // Bitwise operations struct BitWiseNot { @@ -1033,6 +1056,37 @@ void AddDecimalBinaryKernels(const std::string& name, DCHECK_OK((*func)->AddKernel({in_type256, in_type256}, out_type, exec256)); } +// Generate a kernel given an arithmetic functor +template