Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

GH-44952: [C++][Python] Add Hyperbolic Trig functions #44630

Merged
merged 18 commits into from
Dec 9, 2024
Prev Previous commit
Next Next commit
fixes
khwilson committed Dec 8, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
commit 0b06bfc4aa1d9b04ffd358dfa13df5b3a1bf3e69
8 changes: 4 additions & 4 deletions cpp/src/arrow/compute/api_scalar.cc
Original file line number Diff line number Diff line change
@@ -734,20 +734,20 @@ SCALAR_ARITHMETIC_UNARY(AbsoluteValue, "abs", "abs_checked")
SCALAR_ARITHMETIC_UNARY(Acos, "acos", "acos_checked")
SCALAR_ARITHMETIC_UNARY(Acosh, "acosh", "acosh_checked")
SCALAR_ARITHMETIC_UNARY(Asin, "asin", "asin_checked")
SCALAR_ARITHMETIC_UNARY(Asinh, "asinh", "asinh_checked")
SCALAR_ARITHMETIC_UNARY(Atanh, "atanh", "atanh_checked")
SCALAR_ARITHMETIC_UNARY(Cos, "cos", "cos_checked")
SCALAR_ARITHMETIC_UNARY(Cosh, "cosh", "cosh_checked")
SCALAR_ARITHMETIC_UNARY(Ln, "ln", "ln_checked")
SCALAR_ARITHMETIC_UNARY(Log10, "log10", "log10_checked")
SCALAR_ARITHMETIC_UNARY(Log1p, "log1p", "log1p_checked")
SCALAR_ARITHMETIC_UNARY(Log2, "log2", "log2_checked")
SCALAR_ARITHMETIC_UNARY(Sqrt, "sqrt", "sqrt_checked")
SCALAR_ARITHMETIC_UNARY(Negate, "negate", "negate_checked")
SCALAR_ARITHMETIC_UNARY(Sin, "sin", "sin_checked")
SCALAR_ARITHMETIC_UNARY(Sinh, "sinh", "sinh_checked")
SCALAR_ARITHMETIC_UNARY(Tan, "tan", "tan_checked")
SCALAR_ARITHMETIC_UNARY(Tanh, "tanh", "tanh_checked")
SCALAR_EAGER_UNARY(Asinh, "asinh")
SCALAR_EAGER_UNARY(Cosh, "cosh")
SCALAR_EAGER_UNARY(Sinh, "sinh")
SCALAR_EAGER_UNARY(Tanh, "tanh")
SCALAR_EAGER_UNARY(Atan, "atan")
SCALAR_EAGER_UNARY(Exp, "exp")
SCALAR_EAGER_UNARY(Expm1, "expm1")
46 changes: 46 additions & 0 deletions cpp/src/arrow/compute/api_scalar.h
Original file line number Diff line number Diff line change
@@ -784,6 +784,52 @@ Result<Datum> Atan(const Datum& arg, ExecContext* ctx = NULLPTR);
ARROW_EXPORT
Result<Datum> Atan2(const Datum& y, const Datum& x, ExecContext* ctx = NULLPTR);

/// \brief Compute the hyperbolic sine of the array values.
/// \param[in] arg The values to compute the hyperbolic sine for.
/// \param[in] ctx the function execution context, optional
/// \return the elementwise hyperbolic sine of the values
ARROW_EXPORT
Result<Datum> Sinh(const Datum& arg, ExecContext* ctx = NULLPTR);

/// \brief Compute the hyperbolic cosine of the array values.
/// \param[in] arg The values to compute the hyperbolic cosine for.
/// \param[in] ctx the function execution context, optional
/// \return the elementwise hyperbolic cosine of the values
ARROW_EXPORT
Result<Datum> Cosh(const Datum& arg, ExecContext* ctx = NULLPTR);

/// \brief Compute the hyperbolic tangent of the array values.
/// \param[in] arg The values to compute the hyperbolic tangent for.
/// \param[in] ctx the function execution context, optional
/// \return the elementwise hyperbolic tangent of the values
ARROW_EXPORT
Result<Datum> Tanh(const Datum& arg, ExecContext* ctx = NULLPTR);

/// \brief Compute the inverse hyperbolic sine of the array values.
/// \param[in] arg The values to compute the inverse hyperbolic sine for.
/// \param[in] ctx the function execution context, optional
/// \return the elementwise inverse hyperbolic sine of the values
ARROW_EXPORT
Result<Datum> Asinh(const Datum& arg, ExecContext* ctx = NULLPTR);

/// \brief Compute the inverse hyperbolic cosine of the array values.
/// \param[in] arg The values to compute the inverse hyperbolic cosine for.
/// \param[in] options arithmetic options (enable/disable overflow checking), optional
/// \param[in] ctx the function execution context, optional
/// \return the elementwise inverse hyperbolic cosine of the values
ARROW_EXPORT
Result<Datum> Acosh(const Datum& arg, ArithmeticOptions options = ArithmeticOptions(),
ExecContext* ctx = NULLPTR);

/// \brief Compute the inverse hyperbolic tangent of the array values.
/// \param[in] arg The values to compute the inverse hyperbolic tangent for.
/// \param[in] options arithmetic options (enable/disable overflow checking), optional
/// \param[in] ctx the function execution context, optional
/// \return the elementwise inverse hyperbolic tangent of the values
ARROW_EXPORT
Result<Datum> Atanh(const Datum& arg, ArithmeticOptions options = ArithmeticOptions(),
ExecContext* ctx = NULLPTR);

/// \brief Get the natural log of a value.
///
/// If argument is null the result will be null.
84 changes: 5 additions & 79 deletions cpp/src/arrow/compute/kernels/scalar_arithmetic.cc
Original file line number Diff line number Diff line change
@@ -186,18 +186,6 @@ struct Sinh {
}
};

struct SinhChecked {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status* st) {
static_assert(std::is_same<T, Arg0>::value, "");
if (ARROW_PREDICT_FALSE(std::isinf(val))) {
*st = Status::Invalid("domain error");
return val;
}
return std::sinh(val);
}
};

struct Cos {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status*) {
@@ -226,18 +214,6 @@ struct Cosh {
}
};

struct CoshChecked {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status* st) {
static_assert(std::is_same<T, Arg0>::value, "");
if (ARROW_PREDICT_FALSE(std::isinf(val))) {
*st = Status::Invalid("domain error");
return val;
}
return std::cosh(val);
}
};

struct Tan {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status*) {
@@ -267,18 +243,6 @@ struct Tanh {
}
};

struct TanhChecked {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status* st) {
static_assert(std::is_same<T, Arg0>::value, "");
if (ARROW_PREDICT_FALSE(std::isinf(val))) {
*st = Status::Invalid("domain error");
return val;
}
return std::tanh(val);
}
};

struct Asin {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status*) {
@@ -380,7 +344,7 @@ struct Atanh {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status*) {
static_assert(std::is_same<T, Arg0>::value, "");
if (ARROW_PREDICT_FALSE((val <= -1.0 || val >= 1.0))) {
if (ARROW_PREDICT_FALSE((val < -1.0 || val > 1.0))) {
khwilson marked this conversation as resolved.
Show resolved Hide resolved
return std::numeric_limits<T>::quiet_NaN();
}
return std::atanh(val);
@@ -391,7 +355,7 @@ struct AtanhChecked {
template <typename T, typename Arg0>
static enable_if_floating_value<Arg0, T> Call(KernelContext*, Arg0 val, Status* st) {
static_assert(std::is_same<T, Arg0>::value, "");
if (ARROW_PREDICT_FALSE((val <= -1.0 || val >= 1.0))) {
if (ARROW_PREDICT_FALSE((val < -1.0 || val > 1.0))) {
khwilson marked this conversation as resolved.
Show resolved Hide resolved
*st = Status::Invalid("domain error");
return val;
}
@@ -1306,14 +1270,9 @@ const FunctionDoc sin_checked_doc{"Compute the sine",
{"x"}};

const FunctionDoc sinh_doc{"Compute the hyperblic sine",
("NaN is returned for invalid input values;\n"
"to raise an error instead, see \"sinh_checked\"."),
(""),
{"x"}};

const FunctionDoc sinh_checked_doc{"Compute the hyperbolic sine",
("Invalid input values raise an error;\n"
"to return NaN instead, see \"sinh\"."),
{"x"}};

const FunctionDoc cos_doc{"Compute the cosine",
("NaN is returned for invalid input values;\n"
@@ -1326,15 +1285,9 @@ const FunctionDoc cos_checked_doc{"Compute the cosine",
{"x"}};

const FunctionDoc cosh_doc{"Compute the hyperbolic cosine",
("NaN is returned for invalid input values;\n"
"to raise an error instead, see \"cosh_checked\"."),
(""),
{"x"}};

const FunctionDoc cosh_checked_doc{"Compute the hyperbolic cosine",
("Infinite values raise an error;\n"
"to return NaN instead, see \"cosh\"."),
{"x"}};

const FunctionDoc tan_doc{"Compute the tangent",
("NaN is returned for invalid input values;\n"
"to raise an error instead, see \"tanh_checked\"."),
@@ -1346,15 +1299,9 @@ const FunctionDoc tan_checked_doc{"Compute the tangent",
{"x"}};

const FunctionDoc tanh_doc{"Compute the hyperbolic tangent",
("NaN is returned for invalid input values;\n"
"to raise an error instead, see \"tanh_checked\"."),
(""),
{"x"}};

const FunctionDoc tanh_checked_doc{"Compute the hyperbolic tangent",
("Infinite values raise an error;\n"
"to return NaN instead, see \"tanh\"."),
{"x"}};

const FunctionDoc asin_doc{"Compute the inverse sine",
("NaN is returned for invalid input values;\n"
"to raise an error instead, see \"asin_checked\"."),
@@ -1371,11 +1318,6 @@ const FunctionDoc asinh_doc{"Compute the inverse hyperbolic sine",
"to raise an error instead, see \"asinh_checked\"."),
{"x"}};

const FunctionDoc asinh_checked_doc{"Compute the inverse hyperbolic sine",
("Invalid input values raise an error;\n"
"to return NaN instead, see \"asinh\"."),
{"x"}};

const FunctionDoc acos_doc{"Compute the inverse cosine",
("NaN is returned for invalid input values;\n"
"to raise an error instead, see \"acos_checked\"."),
@@ -1882,10 +1824,6 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
auto sinh = MakeUnaryArithmeticFunctionFloatingPoint<Sinh>("sinh", sinh_doc);
DCHECK_OK(registry->AddFunction(std::move(sinh)));

auto sinh_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<SinhChecked>(
"sinh_checked", sinh_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(sinh_checked)));

auto cos = MakeUnaryArithmeticFunctionFloatingPoint<Cos>("cos", cos_doc);
DCHECK_OK(registry->AddFunction(std::move(cos)));

@@ -1896,10 +1834,6 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
auto cosh = MakeUnaryArithmeticFunctionFloatingPoint<Cosh>("cosh", cosh_doc);
DCHECK_OK(registry->AddFunction(std::move(cosh)));

auto cosh_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<CoshChecked>(
"cosh_checked", cosh_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(cosh_checked)));

auto tan = MakeUnaryArithmeticFunctionFloatingPoint<Tan>("tan", tan_doc);
DCHECK_OK(registry->AddFunction(std::move(tan)));

@@ -1910,10 +1844,6 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
auto tanh = MakeUnaryArithmeticFunctionFloatingPoint<Tanh>("tanh", tanh_doc);
DCHECK_OK(registry->AddFunction(std::move(tanh)));

auto tanh_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<TanhChecked>(
"tanh_checked", tanh_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(tanh_checked)));

auto asin = MakeUnaryArithmeticFunctionFloatingPoint<Asin>("asin", asin_doc);
DCHECK_OK(registry->AddFunction(std::move(asin)));

@@ -1924,10 +1854,6 @@ void RegisterScalarArithmetic(FunctionRegistry* registry) {
auto asinh = MakeUnaryArithmeticFunctionFloatingPoint<Asinh>("asinh", asinh_doc);
DCHECK_OK(registry->AddFunction(std::move(asinh)));

auto asinh_checked = MakeUnaryArithmeticFunctionFloatingPointNotNull<AsinhChecked>(
"asinh_checked", asinh_checked_doc);
DCHECK_OK(registry->AddFunction(std::move(asinh_checked)));

auto acos = MakeUnaryArithmeticFunctionFloatingPoint<Acos>("acos", acos_doc);
DCHECK_OK(registry->AddFunction(std::move(acos)));

Loading