This is an automated email from the ASF dual-hosted git repository.
praveenbingo pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/arrow.git
The following commit(s) were added to refs/heads/master by this push:
new 5f4252b ARROW-11987: [C++][Gandiva] Implement trigonometric functions
5f4252b is described below
commit 5f4252bbc6d1f05cc2c7c9c113b8e133444bb523
Author: João Pedro <[email protected]>
AuthorDate: Sat Mar 27 16:27:48 2021 +0530
ARROW-11987: [C++][Gandiva] Implement trigonometric functions
Implement base trigonometric functions (sin; cos; asin; acos; tan; atan;
sinh; cosh; tanh; cotg; radians; degrees;)
JIRA issue: https://issues.apache.org/jira/browse/ARROW-11987
Closes #9726 from jpedroantunes/feature/add-trigonometry-functions and
squashes the following commits:
3391776c3 <João Pedro> Correct missing identation
896d91b49 <João Pedro> Add initialization for atan2 for different numeric
types
5ef2c8362 <João Pedro> Correct \ identation on macros being used
e2355e8e5 <João Pedro> Fix last missing format on extended math ops on
gandiva
7cd2659b7 <João Pedro> Fix more identation comments on C++ code
831cff06d <João Pedro> Fix suggestions on code format by C++ linter
a2c2b2826 <João Pedro> Add cast for pi float variable used on test
33987aad4 <João Pedro> Remove unused macro on function registry math on
gandiva
11e5c9cb4 <João Pedro> Add ifdef definition for m_pi constants
434995b7e <João Pedro> Add support for trigonometry functions on Gandiva
7e1e4d9c2 <João Pedro> Add projector test for new implemented trigonometry
functions
6603019c5 <João Pedro> Correct atan2 method name in unit tests
6b5dafdd6 <João Pedro> Correct macro for atan2 method implementation
c05463d72 <João Pedro> Register all missing trigonometry methods on funtion
registry and types header
63fba45f5 <João Pedro> Register on function registry all base trigonometry
functions
c94590fcf <João Pedro> Add unit tests for base trigonometry functions
870029fa2 <João Pedro> Add implementation for base trigonometry functions
d474f75a2 <João Pedro> Add registry for base trigonometry functions
Authored-by: João Pedro <[email protected]>
Signed-off-by: Praveen <[email protected]>
---
cpp/src/gandiva/function_registry_math_ops.cc | 15 +++
cpp/src/gandiva/precompiled/extended_math_ops.cc | 110 +++++++++++++++++-
.../gandiva/precompiled/extended_math_ops_test.cc | 128 +++++++++++++++++++++
cpp/src/gandiva/precompiled/types.h | 51 ++++++++
cpp/src/gandiva/tests/projector_test.cc | 91 ++++++++++++++-
5 files changed, 392 insertions(+), 3 deletions(-)
diff --git a/cpp/src/gandiva/function_registry_math_ops.cc
b/cpp/src/gandiva/function_registry_math_ops.cc
index 771e363..49afd40 100644
--- a/cpp/src/gandiva/function_registry_math_ops.cc
+++ b/cpp/src/gandiva/function_registry_math_ops.cc
@@ -36,6 +36,14 @@ namespace gandiva {
BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, float32, float64), \
BINARY_UNSAFE_NULL_IF_NULL(name, ALIASES, float64, float64)
+#define MATH_BINARY_SAFE(name, ALIASES)
\
+ BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int32, int32, float64),
\
+ BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, int64, int64, float64),
\
+ BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, uint32, uint32,
float64), \
+ BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, uint64, uint64,
float64), \
+ BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, float32, float32,
float64), \
+ BINARY_GENERIC_SAFE_NULL_IF_NULL(name, ALIASES, float64, float64,
float64)
+
#define UNARY_SAFE_NULL_NEVER_BOOL_FN(name, ALIASES) \
NUMERIC_BOOL_DATE_TYPES(UNARY_SAFE_NULL_NEVER_BOOL, name, ALIASES)
@@ -59,6 +67,13 @@ std::vector<NativeFunction> GetMathOpsFunctionRegistry() {
BINARY_SAFE_NULL_NEVER_BOOL_FN(is_distinct_from, {}),
BINARY_SAFE_NULL_NEVER_BOOL_FN(is_not_distinct_from, {}),
+ // trigonometry functions
+ MATH_UNARY_OPS(sin, {}), MATH_UNARY_OPS(cos, {}), MATH_UNARY_OPS(asin,
{}),
+ MATH_UNARY_OPS(acos, {}), MATH_UNARY_OPS(tan, {}), MATH_UNARY_OPS(atan,
{}),
+ MATH_UNARY_OPS(sinh, {}), MATH_UNARY_OPS(cosh, {}), MATH_UNARY_OPS(tanh,
{}),
+ MATH_UNARY_OPS(cot, {}), MATH_UNARY_OPS(radians, {}),
MATH_UNARY_OPS(degrees, {}),
+ MATH_BINARY_SAFE(atan2, {}),
+
// decimal functions
UNARY_SAFE_NULL_IF_NULL(abs, {}, decimal128, decimal128),
UNARY_SAFE_NULL_IF_NULL(ceil, {}, decimal128, decimal128),
diff --git a/cpp/src/gandiva/precompiled/extended_math_ops.cc
b/cpp/src/gandiva/precompiled/extended_math_ops.cc
index d7de432..b2d62da 100644
--- a/cpp/src/gandiva/precompiled/extended_math_ops.cc
+++ b/cpp/src/gandiva/precompiled/extended_math_ops.cc
@@ -15,6 +15,10 @@
// specific language governing permissions and limitations
// under the License.
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
#include "arrow/util/logging.h"
#include "gandiva/precompiled/decimal_ops.h"
@@ -103,13 +107,117 @@ LOG_WITH_BASE(uint64, uint64, float64)
LOG_WITH_BASE(float32, float32, float64)
LOG_WITH_BASE(float64, float64, float64)
+// Sin
+#define SIN(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE sin_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(sin(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(SIN, float64)
+
+// Asin
+#define ASIN(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE asin_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(asin(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(ASIN, float64)
+
+// Cos
+#define COS(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE cos_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(cos(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(COS, float64)
+
+// Acos
+#define ACOS(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE acos_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(acos(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(ACOS, float64)
+
+// Tan
+#define TAN(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE tan_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(tan(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(TAN, float64)
+
+// Atan
+#define ATAN(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE atan_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(atan(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(ATAN, float64)
+
+// Sinh
+#define SINH(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE sinh_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(sinh(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(SINH, float64)
+
+// Cosh
+#define COSH(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE cosh_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(cosh(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(COSH, float64)
+
+// Tanh
+#define TANH(IN_TYPE, OUT_TYPE) \
+ FORCE_INLINE \
+ gdv_##OUT_TYPE tanh_##IN_TYPE(gdv_##IN_TYPE in) { \
+ return static_cast<gdv_##OUT_TYPE>(tanh(static_cast<long double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(TANH, float64)
+
+// Atan2
+#define ATAN2(IN_TYPE, OUT_TYPE)
\
+ FORCE_INLINE
\
+ gdv_##OUT_TYPE atan2_##IN_TYPE##_##IN_TYPE(gdv_##IN_TYPE in1, gdv_##IN_TYPE
in2) { \
+ return static_cast<gdv_##OUT_TYPE>(
\
+ atan2(static_cast<long double>(in1), static_cast<long double>(in2)));
\
+ }
+ENUMERIC_TYPES_UNARY(ATAN2, float64)
+
+// Cot
+#define COT(IN_TYPE, OUT_TYPE)
\
+ FORCE_INLINE
\
+ gdv_##OUT_TYPE cot_##IN_TYPE(gdv_##IN_TYPE in) {
\
+ return static_cast<gdv_##OUT_TYPE>(tan(M_PI / 2 - static_cast<long
double>(in))); \
+ }
+ENUMERIC_TYPES_UNARY(COT, float64)
+
+// Radians
+#define RADIANS(IN_TYPE, OUT_TYPE)
\
+ FORCE_INLINE
\
+ gdv_##OUT_TYPE radians_##IN_TYPE(gdv_##IN_TYPE in) {
\
+ return static_cast<gdv_##OUT_TYPE>(static_cast<long double>(in) * M_PI /
180.0); \
+ }
+ENUMERIC_TYPES_UNARY(RADIANS, float64)
+
+// Degrees
+#define DEGREES(IN_TYPE, OUT_TYPE)
\
+ FORCE_INLINE
\
+ gdv_##OUT_TYPE degrees_##IN_TYPE(gdv_##IN_TYPE in) {
\
+ return static_cast<gdv_##OUT_TYPE>(static_cast<long double>(in) * 180.0 /
M_PI); \
+ }
+ENUMERIC_TYPES_UNARY(DEGREES, float64)
+
// power
#define POWER(IN_TYPE1, IN_TYPE2, OUT_TYPE)
\
FORCE_INLINE
\
gdv_##OUT_TYPE power_##IN_TYPE1##_##IN_TYPE2(gdv_##IN_TYPE1 in1,
gdv_##IN_TYPE2 in2) { \
return static_cast<gdv_float64>(powl(in1, in2));
\
}
-
POWER(float64, float64, float64)
FORCE_INLINE
diff --git a/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
b/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
index 81a3565..6e59f68 100644
--- a/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
+++ b/cpp/src/gandiva/precompiled/extended_math_ops_test.cc
@@ -15,6 +15,10 @@
// specific language governing permissions and limitations
// under the License.
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
#include <gtest/gtest.h>
#include <cmath>
#include "gandiva/execution_context.h"
@@ -145,4 +149,128 @@ TEST(TestExtendedMathOps, TestTruncate) {
EXPECT_EQ(truncate_int64_int32(8124674407369523212, -2),
8124674407369523200);
}
+TEST(TestExtendedMathOps, TestTrigonometricFunctions) {
+ auto pi_float = static_cast<float>(M_PI);
+ // Sin functions
+ VerifyFuzzyEquals(sin_float32(0), sin(0));
+ VerifyFuzzyEquals(sin_float32(0), sin(0));
+ VerifyFuzzyEquals(sin_float32(pi_float / 2), sin(M_PI / 2));
+ VerifyFuzzyEquals(sin_float32(pi_float), sin(M_PI));
+ VerifyFuzzyEquals(sin_float32(-pi_float / 2), sin(-M_PI / 2));
+ VerifyFuzzyEquals(sin_float64(0), sin(0));
+ VerifyFuzzyEquals(sin_float64(M_PI / 2), sin(M_PI / 2));
+ VerifyFuzzyEquals(sin_float64(M_PI), sin(M_PI));
+ VerifyFuzzyEquals(sin_float64(-M_PI / 2), sin(-M_PI / 2));
+ VerifyFuzzyEquals(sin_int32(0), sin(0));
+ VerifyFuzzyEquals(sin_int64(0), sin(0));
+
+ // Cos functions
+ VerifyFuzzyEquals(cos_float32(0), cos(0));
+ VerifyFuzzyEquals(cos_float32(pi_float / 2), cos(M_PI / 2));
+ VerifyFuzzyEquals(cos_float32(pi_float), cos(M_PI));
+ VerifyFuzzyEquals(cos_float32(-pi_float / 2), cos(-M_PI / 2));
+ VerifyFuzzyEquals(cos_float64(0), cos(0));
+ VerifyFuzzyEquals(cos_float64(M_PI / 2), cos(M_PI / 2));
+ VerifyFuzzyEquals(cos_float64(M_PI), cos(M_PI));
+ VerifyFuzzyEquals(cos_float64(-M_PI / 2), cos(-M_PI / 2));
+ VerifyFuzzyEquals(cos_int32(0), cos(0));
+ VerifyFuzzyEquals(cos_int64(0), cos(0));
+
+ // Asin functions
+ VerifyFuzzyEquals(asin_float32(-1.0), asin(-1.0));
+ VerifyFuzzyEquals(asin_float32(1.0), asin(1.0));
+ VerifyFuzzyEquals(asin_float64(-1.0), asin(-1.0));
+ VerifyFuzzyEquals(asin_float64(1.0), asin(1.0));
+ VerifyFuzzyEquals(asin_int32(0), asin(0));
+ VerifyFuzzyEquals(asin_int64(0), asin(0));
+
+ // Acos functions
+ VerifyFuzzyEquals(acos_float32(-1.0), acos(-1.0));
+ VerifyFuzzyEquals(acos_float32(1.0), acos(1.0));
+ VerifyFuzzyEquals(acos_float64(-1.0), acos(-1.0));
+ VerifyFuzzyEquals(acos_float64(1.0), acos(1.0));
+ VerifyFuzzyEquals(acos_int32(0), acos(0));
+ VerifyFuzzyEquals(acos_int64(0), acos(0));
+
+ // Tan
+ VerifyFuzzyEquals(tan_float32(pi_float), tan(M_PI));
+ VerifyFuzzyEquals(tan_float32(-pi_float), tan(-M_PI));
+ VerifyFuzzyEquals(tan_float64(M_PI), tan(M_PI));
+ VerifyFuzzyEquals(tan_float64(-M_PI), tan(-M_PI));
+ VerifyFuzzyEquals(tan_int32(0), tan(0));
+ VerifyFuzzyEquals(tan_int64(0), tan(0));
+
+ // Atan
+ VerifyFuzzyEquals(atan_float32(pi_float), atan(M_PI));
+ VerifyFuzzyEquals(atan_float32(-pi_float), atan(-M_PI));
+ VerifyFuzzyEquals(atan_float64(M_PI), atan(M_PI));
+ VerifyFuzzyEquals(atan_float64(-M_PI), atan(-M_PI));
+ VerifyFuzzyEquals(atan_int32(0), atan(0));
+ VerifyFuzzyEquals(atan_int64(0), atan(0));
+
+ // Sinh functions
+ VerifyFuzzyEquals(sinh_float32(0), sinh(0));
+ VerifyFuzzyEquals(sinh_float32(pi_float / 2), sinh(M_PI / 2));
+ VerifyFuzzyEquals(sinh_float32(pi_float), sinh(M_PI));
+ VerifyFuzzyEquals(sinh_float32(-pi_float / 2), sinh(-M_PI / 2));
+ VerifyFuzzyEquals(sinh_float64(0), sinh(0));
+ VerifyFuzzyEquals(sinh_float64(M_PI / 2), sinh(M_PI / 2));
+ VerifyFuzzyEquals(sinh_float64(M_PI), sinh(M_PI));
+ VerifyFuzzyEquals(sinh_float64(-M_PI / 2), sinh(-M_PI / 2));
+ VerifyFuzzyEquals(sinh_int32(0), sinh(0));
+ VerifyFuzzyEquals(sinh_int64(0), sinh(0));
+
+ // Cosh functions
+ VerifyFuzzyEquals(cosh_float32(0), cosh(0));
+ VerifyFuzzyEquals(cosh_float32(pi_float / 2), cosh(M_PI / 2));
+ VerifyFuzzyEquals(cosh_float32(pi_float), cosh(M_PI));
+ VerifyFuzzyEquals(cosh_float32(-pi_float / 2), cosh(-M_PI / 2));
+ VerifyFuzzyEquals(cosh_float64(0), cosh(0));
+ VerifyFuzzyEquals(cosh_float64(M_PI / 2), cosh(M_PI / 2));
+ VerifyFuzzyEquals(cosh_float64(M_PI), cosh(M_PI));
+ VerifyFuzzyEquals(cosh_float64(-M_PI / 2), cosh(-M_PI / 2));
+ VerifyFuzzyEquals(cosh_int32(0), cosh(0));
+ VerifyFuzzyEquals(cosh_int64(0), cosh(0));
+
+ // Tanh
+ VerifyFuzzyEquals(tanh_float32(pi_float), tanh(M_PI));
+ VerifyFuzzyEquals(tanh_float32(-pi_float), tanh(-M_PI));
+ VerifyFuzzyEquals(tanh_float64(M_PI), tanh(M_PI));
+ VerifyFuzzyEquals(tanh_float64(-M_PI), tanh(-M_PI));
+ VerifyFuzzyEquals(tanh_int32(0), tanh(0));
+ VerifyFuzzyEquals(tanh_int64(0), tanh(0));
+
+ // Atan2
+ VerifyFuzzyEquals(atan2_float32_float32(1, 0), atan2(1, 0));
+ VerifyFuzzyEquals(atan2_float32_float32(-1.0, 0), atan2(-1, 0));
+ VerifyFuzzyEquals(atan2_float64_float64(1.0, 0.0), atan2(1, 0));
+ VerifyFuzzyEquals(atan2_float64_float64(-1, 0), atan2(-1, 0));
+ VerifyFuzzyEquals(atan2_int32_int32(1, 0), atan2(1, 0));
+ VerifyFuzzyEquals(atan2_int64_int64(-1, 0), atan2(-1, 0));
+
+ // Radians
+ VerifyFuzzyEquals(radians_float32(0), 0);
+ VerifyFuzzyEquals(radians_float32(180.0), M_PI);
+ VerifyFuzzyEquals(radians_float32(90.0), M_PI / 2);
+ VerifyFuzzyEquals(radians_float64(0), 0);
+ VerifyFuzzyEquals(radians_float64(180.0), M_PI);
+ VerifyFuzzyEquals(radians_float64(90.0), M_PI / 2);
+ VerifyFuzzyEquals(radians_int32(180), M_PI);
+ VerifyFuzzyEquals(radians_int64(90), M_PI / 2);
+
+ // Degrees
+ VerifyFuzzyEquals(degrees_float32(0), 0.0);
+ VerifyFuzzyEquals(degrees_float32(pi_float), 180.0);
+ VerifyFuzzyEquals(degrees_float32(pi_float / 2), 90.0);
+ VerifyFuzzyEquals(degrees_float64(0), 0.0);
+ VerifyFuzzyEquals(degrees_float64(M_PI), 180.0);
+ VerifyFuzzyEquals(degrees_float64(M_PI / 2), 90.0);
+ VerifyFuzzyEquals(degrees_int32(1), 57.2958);
+ VerifyFuzzyEquals(degrees_int64(1), 57.2958);
+
+ // Cot
+ VerifyFuzzyEquals(cot_float32(pi_float / 2), tan(M_PI / 2 - M_PI / 2));
+ VerifyFuzzyEquals(cot_float64(M_PI / 2), tan(M_PI / 2 - M_PI / 2));
+}
+
} // namespace gandiva
diff --git a/cpp/src/gandiva/precompiled/types.h
b/cpp/src/gandiva/precompiled/types.h
index 78ac9ec..81bd3a2 100644
--- a/cpp/src/gandiva/precompiled/types.h
+++ b/cpp/src/gandiva/precompiled/types.h
@@ -163,6 +163,57 @@ gdv_float64 log10_int64(gdv_int64);
gdv_float64 log10_float32(gdv_float32);
gdv_float64 log10_float64(gdv_float64);
+gdv_float64 sin_int32(gdv_int32);
+gdv_float64 sin_int64(gdv_int64);
+gdv_float64 sin_float32(gdv_float32);
+gdv_float64 sin_float64(gdv_float64);
+gdv_float64 cos_int32(gdv_int32);
+gdv_float64 cos_int64(gdv_int64);
+gdv_float64 cos_float32(gdv_float32);
+gdv_float64 cos_float64(gdv_float64);
+gdv_float64 asin_int32(gdv_int32);
+gdv_float64 asin_int64(gdv_int64);
+gdv_float64 asin_float32(gdv_float32);
+gdv_float64 asin_float64(gdv_float64);
+gdv_float64 acos_int32(gdv_int32);
+gdv_float64 acos_int64(gdv_int64);
+gdv_float64 acos_float32(gdv_float32);
+gdv_float64 acos_float64(gdv_float64);
+gdv_float64 tan_int32(gdv_int32);
+gdv_float64 tan_int64(gdv_int64);
+gdv_float64 tan_float32(gdv_float32);
+gdv_float64 tan_float64(gdv_float64);
+gdv_float64 atan_int32(gdv_int32);
+gdv_float64 atan_int64(gdv_int64);
+gdv_float64 atan_float32(gdv_float32);
+gdv_float64 atan_float64(gdv_float64);
+gdv_float64 sinh_int32(gdv_int32);
+gdv_float64 sinh_int64(gdv_int64);
+gdv_float64 sinh_float32(gdv_float32);
+gdv_float64 sinh_float64(gdv_float64);
+gdv_float64 cosh_int32(gdv_int32);
+gdv_float64 cosh_int64(gdv_int64);
+gdv_float64 cosh_float32(gdv_float32);
+gdv_float64 cosh_float64(gdv_float64);
+gdv_float64 tanh_int32(gdv_int32);
+gdv_float64 tanh_int64(gdv_int64);
+gdv_float64 tanh_float32(gdv_float32);
+gdv_float64 tanh_float64(gdv_float64);
+gdv_float64 atan2_int32_int32(gdv_int32 in1, gdv_int32 in2);
+gdv_float64 atan2_int64_int64(gdv_int64 in1, gdv_int64 in2);
+gdv_float64 atan2_float32_float32(gdv_float32 in1, gdv_float32 in2);
+gdv_float64 atan2_float64_float64(gdv_float64 in1, gdv_float64 in2);
+gdv_float64 cot_float32(gdv_float32);
+gdv_float64 cot_float64(gdv_float64);
+gdv_float64 radians_int32(gdv_int32);
+gdv_float64 radians_int64(gdv_int64);
+gdv_float64 radians_float32(gdv_float32);
+gdv_float64 radians_float64(gdv_float64);
+gdv_float64 degrees_int32(gdv_int32);
+gdv_float64 degrees_int64(gdv_int64);
+gdv_float64 degrees_float32(gdv_float32);
+gdv_float64 degrees_float64(gdv_float64);
+
gdv_int32 bitwise_and_int32_int32(gdv_int32 in1, gdv_int32 in2);
gdv_int64 bitwise_and_int64_int64(gdv_int64 in1, gdv_int64 in2);
gdv_int32 bitwise_or_int32_int32(gdv_int32 in1, gdv_int32 in2);
diff --git a/cpp/src/gandiva/tests/projector_test.cc
b/cpp/src/gandiva/tests/projector_test.cc
index 02988b0..b63af40 100644
--- a/cpp/src/gandiva/tests/projector_test.cc
+++ b/cpp/src/gandiva/tests/projector_test.cc
@@ -15,6 +15,10 @@
// specific language governing permissions and limitations
// under the License.
+#ifndef M_PI
+#define M_PI 3.14159265358979323846
+#endif
+
#include "gandiva/projector.h"
#include <gtest/gtest.h>
@@ -356,6 +360,19 @@ TEST_F(TestProjector, TestExtendedMath) {
auto field_log10 = arrow::field("log10", arrow::float64());
auto field_logb = arrow::field("logb", arrow::float64());
auto field_power = arrow::field("power", arrow::float64());
+ auto field_sin = arrow::field("sin", arrow::float64());
+ auto field_cos = arrow::field("cos", arrow::float64());
+ auto field_asin = arrow::field("asin", arrow::float64());
+ auto field_acos = arrow::field("acos", arrow::float64());
+ auto field_tan = arrow::field("tan", arrow::float64());
+ auto field_atan = arrow::field("atan", arrow::float64());
+ auto field_sinh = arrow::field("sinh", arrow::float64());
+ auto field_cosh = arrow::field("cosh", arrow::float64());
+ auto field_tanh = arrow::field("tanh", arrow::float64());
+ auto field_atan2 = arrow::field("atan2", arrow::float64());
+ auto field_cot = arrow::field("cot", arrow::float64());
+ auto field_radians = arrow::field("radians", arrow::float64());
+ auto field_degrees = arrow::field("degrees", arrow::float64());
// Build expression
auto cbrt_expr = TreeExprBuilder::MakeExpression("cbrt", {field0},
field_cbrt);
@@ -365,10 +382,27 @@ TEST_F(TestProjector, TestExtendedMath) {
auto logb_expr = TreeExprBuilder::MakeExpression("log", {field0, field1},
field_logb);
auto power_expr =
TreeExprBuilder::MakeExpression("power", {field0, field1}, field_power);
+ auto sin_expr = TreeExprBuilder::MakeExpression("sin", {field0}, field_sin);
+ auto cos_expr = TreeExprBuilder::MakeExpression("cos", {field0}, field_cos);
+ auto asin_expr = TreeExprBuilder::MakeExpression("asin", {field0},
field_asin);
+ auto acos_expr = TreeExprBuilder::MakeExpression("acos", {field0},
field_acos);
+ auto tan_expr = TreeExprBuilder::MakeExpression("tan", {field0}, field_tan);
+ auto atan_expr = TreeExprBuilder::MakeExpression("atan", {field0},
field_atan);
+ auto sinh_expr = TreeExprBuilder::MakeExpression("sinh", {field0},
field_sinh);
+ auto cosh_expr = TreeExprBuilder::MakeExpression("cosh", {field0},
field_cosh);
+ auto tanh_expr = TreeExprBuilder::MakeExpression("tanh", {field0},
field_tanh);
+ auto atan2_expr =
+ TreeExprBuilder::MakeExpression("atan2", {field0, field1}, field_atan2);
+ auto cot_expr = TreeExprBuilder::MakeExpression("cot", {field0}, field_cot);
+ auto radians_expr = TreeExprBuilder::MakeExpression("radians", {field0},
field_radians);
+ auto degrees_expr = TreeExprBuilder::MakeExpression("degrees", {field0},
field_degrees);
std::shared_ptr<Projector> projector;
auto status = Projector::Make(
- schema, {cbrt_expr, exp_expr, log_expr, log10_expr, logb_expr,
power_expr},
+ schema,
+ {cbrt_expr, exp_expr, log_expr, log10_expr, logb_expr, power_expr,
sin_expr,
+ cos_expr, asin_expr, acos_expr, tan_expr, atan_expr, sinh_expr,
cosh_expr,
+ tanh_expr, atan2_expr, cot_expr, radians_expr, degrees_expr},
TestConfiguration(), &projector);
EXPECT_TRUE(status.ok());
@@ -388,6 +422,19 @@ TEST_F(TestProjector, TestExtendedMath) {
std::vector<double> log10_vals;
std::vector<double> logb_vals;
std::vector<double> power_vals;
+ std::vector<double> sin_vals;
+ std::vector<double> cos_vals;
+ std::vector<double> asin_vals;
+ std::vector<double> acos_vals;
+ std::vector<double> tan_vals;
+ std::vector<double> atan_vals;
+ std::vector<double> sinh_vals;
+ std::vector<double> cosh_vals;
+ std::vector<double> tanh_vals;
+ std::vector<double> atan2_vals;
+ std::vector<double> cot_vals;
+ std::vector<double> radians_vals;
+ std::vector<double> degrees_vals;
for (int i = 0; i < num_records; i++) {
cbrt_vals.push_back(static_cast<double>(cbrtl(input0[i])));
exp_vals.push_back(static_cast<double>(expl(input0[i])));
@@ -395,6 +442,19 @@ TEST_F(TestProjector, TestExtendedMath) {
log10_vals.push_back(static_cast<double>(log10l(input0[i])));
logb_vals.push_back(static_cast<double>(logl(input1[i]) /
logl(input0[i])));
power_vals.push_back(static_cast<double>(powl(input0[i], input1[i])));
+ sin_vals.push_back(static_cast<double>(sin(input0[i])));
+ cos_vals.push_back(static_cast<double>(cos(input0[i])));
+ asin_vals.push_back(static_cast<double>(asin(input0[i])));
+ acos_vals.push_back(static_cast<double>(acos(input0[i])));
+ tan_vals.push_back(static_cast<double>(tan(input0[i])));
+ atan_vals.push_back(static_cast<double>(atan(input0[i])));
+ sinh_vals.push_back(static_cast<double>(sinh(input0[i])));
+ cosh_vals.push_back(static_cast<double>(cosh(input0[i])));
+ tanh_vals.push_back(static_cast<double>(tanh(input0[i])));
+ atan2_vals.push_back(static_cast<double>(atan2(input0[i], input1[i])));
+ cot_vals.push_back(static_cast<double>(tan(M_PI / 2 - input0[i])));
+ radians_vals.push_back(static_cast<double>(input0[i] * M_PI / 180.0));
+ degrees_vals.push_back(static_cast<double>(input0[i] * 180.0 / M_PI));
}
auto expected_cbrt = MakeArrowArray<arrow::DoubleType, double>(cbrt_vals,
validity);
auto expected_exp = MakeArrowArray<arrow::DoubleType, double>(exp_vals,
validity);
@@ -402,7 +462,21 @@ TEST_F(TestProjector, TestExtendedMath) {
auto expected_log10 = MakeArrowArray<arrow::DoubleType, double>(log10_vals,
validity);
auto expected_logb = MakeArrowArray<arrow::DoubleType, double>(logb_vals,
validity);
auto expected_power = MakeArrowArray<arrow::DoubleType, double>(power_vals,
validity);
-
+ auto expected_sin = MakeArrowArray<arrow::DoubleType, double>(sin_vals,
validity);
+ auto expected_cos = MakeArrowArray<arrow::DoubleType, double>(cos_vals,
validity);
+ auto expected_asin = MakeArrowArray<arrow::DoubleType, double>(asin_vals,
validity);
+ auto expected_acos = MakeArrowArray<arrow::DoubleType, double>(acos_vals,
validity);
+ auto expected_tan = MakeArrowArray<arrow::DoubleType, double>(tan_vals,
validity);
+ auto expected_atan = MakeArrowArray<arrow::DoubleType, double>(atan_vals,
validity);
+ auto expected_sinh = MakeArrowArray<arrow::DoubleType, double>(sinh_vals,
validity);
+ auto expected_cosh = MakeArrowArray<arrow::DoubleType, double>(cosh_vals,
validity);
+ auto expected_tanh = MakeArrowArray<arrow::DoubleType, double>(tanh_vals,
validity);
+ auto expected_atan2 = MakeArrowArray<arrow::DoubleType, double>(atan2_vals,
validity);
+ auto expected_cot = MakeArrowArray<arrow::DoubleType, double>(cot_vals,
validity);
+ auto expected_radians =
+ MakeArrowArray<arrow::DoubleType, double>(radians_vals, validity);
+ auto expected_degrees =
+ MakeArrowArray<arrow::DoubleType, double>(degrees_vals, validity);
// prepare input record batch
auto in_batch = arrow::RecordBatch::Make(schema, num_records, {array0,
array1});
@@ -419,6 +493,19 @@ TEST_F(TestProjector, TestExtendedMath) {
EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_log10, outputs.at(3), epsilon);
EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_logb, outputs.at(4), epsilon);
EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_power, outputs.at(5), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_sin, outputs.at(6), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_cos, outputs.at(7), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_asin, outputs.at(8), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_acos, outputs.at(9), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_tan, outputs.at(10), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_atan, outputs.at(11), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_sinh, outputs.at(12), 1E-08);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_cosh, outputs.at(13), 1E-08);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_tanh, outputs.at(14), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_atan2, outputs.at(15), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_cot, outputs.at(16), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_radians, outputs.at(17), epsilon);
+ EXPECT_ARROW_ARRAY_APPROX_EQUALS(expected_degrees, outputs.at(18), epsilon);
}
TEST_F(TestProjector, TestFloatLessThan) {