From 4c44f46bfc5a2500a6b97e6cc39cb67af56a319b Mon Sep 17 00:00:00 2001 From: Amit Dutta Date: Sun, 26 Sep 2021 22:18:30 -0700 Subject: [PATCH] Adding sin, cos, tan, cosh and tanh presto functions. --- velox/docs/functions/math.rst | 21 +++++++ velox/functions/prestosql/Arithmetic.h | 35 +++++++++++ .../prestosql/RegisterArithmetic.cpp | 5 ++ .../prestosql/tests/ArithmeticTest.cpp | 60 +++++++++++++++++++ 4 files changed, 121 insertions(+) diff --git a/velox/docs/functions/math.rst b/velox/docs/functions/math.rst index de49a3b1995d..330b5c776d8f 100644 --- a/velox/docs/functions/math.rst +++ b/velox/docs/functions/math.rst @@ -105,3 +105,24 @@ Trigonometric Functions .. function:: atan2(y, x) -> double Returns the arc tangent of ``y / x``. + +.. function:: cos(x) -> double + + Returns the cosine of ``x``. + +.. function:: cosh(x) -> double + + Returns the hyperbolic cosine of ``x``. + +.. function:: sin(x) -> double + + Returns the sine of ``x``. + +.. function:: tan(x) -> double + + Returns the tangent of ``x``. + +.. function:: tanh(x) -> double + + Returns the hyperbolic tangent of ``x``. + diff --git a/velox/functions/prestosql/Arithmetic.h b/velox/functions/prestosql/Arithmetic.h index 0f68dec09dc7..7021adc11e26 100644 --- a/velox/functions/prestosql/Arithmetic.h +++ b/velox/functions/prestosql/Arithmetic.h @@ -150,6 +150,20 @@ FOLLY_ALWAYS_INLINE bool call(double& result, double a) { } VELOX_UDF_END(); +VELOX_UDF_BEGIN(cos) +FOLLY_ALWAYS_INLINE bool call(double& result, double a) { + result = std::cos(a); + return true; +} +VELOX_UDF_END(); + +VELOX_UDF_BEGIN(cosh) +FOLLY_ALWAYS_INLINE bool call(double& result, double a) { + result = std::cosh(a); + return true; +} +VELOX_UDF_END(); + VELOX_UDF_BEGIN(acos) FOLLY_ALWAYS_INLINE bool call(double& result, double a) { result = std::acos(a); @@ -157,6 +171,13 @@ FOLLY_ALWAYS_INLINE bool call(double& result, double a) { } VELOX_UDF_END(); +VELOX_UDF_BEGIN(sin) +FOLLY_ALWAYS_INLINE bool call(double& result, double a) { + result = std::sin(a); + return true; +} +VELOX_UDF_END(); + VELOX_UDF_BEGIN(asin) FOLLY_ALWAYS_INLINE bool call(double& result, double a) { result = std::asin(a); @@ -164,6 +185,20 @@ FOLLY_ALWAYS_INLINE bool call(double& result, double a) { } VELOX_UDF_END(); +VELOX_UDF_BEGIN(tan) +FOLLY_ALWAYS_INLINE bool call(double& result, double a) { + result = std::tan(a); + return true; +} +VELOX_UDF_END(); + +VELOX_UDF_BEGIN(tanh) +FOLLY_ALWAYS_INLINE bool call(double& result, double a) { + result = std::tanh(a); + return true; +} +VELOX_UDF_END(); + VELOX_UDF_BEGIN(atan) FOLLY_ALWAYS_INLINE bool call(double& result, double a) { result = std::atan(a); diff --git a/velox/functions/prestosql/RegisterArithmetic.cpp b/velox/functions/prestosql/RegisterArithmetic.cpp index 16d1f66c24dd..3bafdf8b2f9e 100644 --- a/velox/functions/prestosql/RegisterArithmetic.cpp +++ b/velox/functions/prestosql/RegisterArithmetic.cpp @@ -72,8 +72,13 @@ void registerArithmeticFunctions() { {"clamp"}); registerFunction, float, float, float, float>({"clamp"}); registerFunction({"ln"}); + registerFunction({"cos"}); + registerFunction({"cosh"}); registerFunction({"acos"}); + registerFunction({"sin"}); registerFunction({"asin"}); + registerFunction({"tan"}); + registerFunction({"tanh"}); registerFunction({"atan"}); registerFunction({"atan2"}); registerFunction({"sqrt"}); diff --git a/velox/functions/prestosql/tests/ArithmeticTest.cpp b/velox/functions/prestosql/tests/ArithmeticTest.cpp index 23aaf2cd5d92..4e243f943c81 100644 --- a/velox/functions/prestosql/tests/ArithmeticTest.cpp +++ b/velox/functions/prestosql/tests/ArithmeticTest.cpp @@ -177,6 +177,30 @@ TEST_F(ArithmeticTest, ln) { EXPECT_EQ(std::nullopt, ln(std::nullopt)); } +TEST_F(ArithmeticTest, cos) { + const auto cosEval = [&](std::optional a) { + return evaluateOnce("cos(c0)", a); + }; + + for (double value : kDoubleValues) { + EXPECT_EQ(std::cos(value), cosEval(value)); + } + + EXPECT_EQ(std::nullopt, cosEval(std::nullopt)); +} + +TEST_F(ArithmeticTest, cosh) { + const auto coshEval = [&](std::optional a) { + return evaluateOnce("cosh(c0)", a); + }; + + for (double value : kDoubleValues) { + EXPECT_EQ(std::cosh(value), coshEval(value)); + } + + EXPECT_EQ(std::nullopt, coshEval(std::nullopt)); +} + TEST_F(ArithmeticTest, acos) { const auto acosEval = [&](std::optional a) { return evaluateOnce("acos(c0)", a); @@ -195,6 +219,18 @@ TEST_F(ArithmeticTest, acos) { EXPECT_EQ(std::nullopt, acosEval(std::nullopt)); } +TEST_F(ArithmeticTest, sin) { + const auto sinEval = [&](std::optional a) { + return evaluateOnce("sin(c0)", a); + }; + + for (double value : kDoubleValues) { + EXPECT_EQ(std::sin(value), sinEval(value)); + } + + EXPECT_EQ(std::nullopt, sinEval(std::nullopt)); +} + TEST_F(ArithmeticTest, asin) { const auto asinEval = [&](std::optional a) { return evaluateOnce("asin(c0)", a); @@ -213,6 +249,30 @@ TEST_F(ArithmeticTest, asin) { EXPECT_EQ(std::nullopt, asinEval(std::nullopt)); } +TEST_F(ArithmeticTest, tan) { + const auto tanEval = [&](std::optional a) { + return evaluateOnce("tan(c0)", a); + }; + + for (double value : kDoubleValues) { + EXPECT_EQ(std::tan(value), tanEval(value)); + } + + EXPECT_EQ(std::nullopt, tanEval(std::nullopt)); +} + +TEST_F(ArithmeticTest, tanh) { + const auto tanhEval = [&](std::optional a) { + return evaluateOnce("tanh(c0)", a); + }; + + for (double value : kDoubleValues) { + EXPECT_EQ(std::tanh(value), tanhEval(value)); + } + + EXPECT_EQ(std::nullopt, tanhEval(std::nullopt)); +} + TEST_F(ArithmeticTest, atan) { const auto atanEval = [&](std::optional a) { return evaluateOnce("atan(c0)", a);