Skip to content

Commit

Permalink
[SPARK-33563][PYTHON][R][SQL] Expose inverse hyperbolic trig function…
Browse files Browse the repository at this point in the history
…s in PySpark and SparkR

### What changes were proposed in this pull request?

This PR adds the following functions (introduced in Scala API with SPARK-33061):

- `acosh`
- `asinh`
- `atanh`

to Python and R.

### Why are the changes needed?

Feature parity.

### Does this PR introduce _any_ user-facing change?

New functions.

### How was this patch tested?

New unit tests.

Closes #30501 from zero323/SPARK-33563.

Authored-by: zero323 <mszymkiewicz@gmail.com>
Signed-off-by: HyukjinKwon <gurwls223@apache.org>
  • Loading branch information
zero323 authored and HyukjinKwon committed Nov 27, 2020
1 parent dfa3978 commit d082ad0
Show file tree
Hide file tree
Showing 7 changed files with 104 additions and 1 deletion.
3 changes: 3 additions & 0 deletions R/pkg/NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,7 @@ exportMethods("%<=>%",
"%in%",
"abs",
"acos",
"acosh",
"add_months",
"alias",
"approx_count_distinct",
Expand Down Expand Up @@ -232,8 +233,10 @@ exportMethods("%<=>%",
"asc_nulls_last",
"ascii",
"asin",
"asinh",
"assert_true",
"atan",
"atanh",
"atan2",
"avg",
"base64",
Expand Down
39 changes: 39 additions & 0 deletions R/pkg/R/functions.R
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,19 @@ setMethod("acos",
column(jc)
})

#' @details
#' \code{acosh}: Computes inverse hyperbolic cosine of the input column.
#'
#' @rdname column_math_functions
#' @aliases acosh acosh,Column-method
#' @note acosh since 3.1.0
setMethod("acosh",
signature(x = "Column"),
function(x) {
jc <- callJStatic("org.apache.spark.sql.functions", "acosh", x@jc)
column(jc)
})

#' @details
#' \code{approx_count_distinct}: Returns the approximate number of distinct items in a group.
#'
Expand Down Expand Up @@ -522,6 +535,19 @@ setMethod("asin",
column(jc)
})

#' @details
#' \code{asinh}: Computes inverse hyperbolic sine of the input column.
#'
#' @rdname column_math_functions
#' @aliases asinh asinh,Column-method
#' @note asinh since 3.1.0
setMethod("asinh",
signature(x = "Column"),
function(x) {
jc <- callJStatic("org.apache.spark.sql.functions", "asinh", x@jc)
column(jc)
})

#' @details
#' \code{atan}: Returns the inverse tangent of the given value,
#' as if computed by \code{java.lang.Math.atan()}
Expand All @@ -536,6 +562,19 @@ setMethod("atan",
column(jc)
})

#' @details
#' \code{atanh}: Computes inverse hyperbolic tangent of the input column.
#'
#' @rdname column_math_functions
#' @aliases atanh atanh,Column-method
#' @note atanh since 3.1.0
setMethod("atanh",
signature(x = "Column"),
function(x) {
jc <- callJStatic("org.apache.spark.sql.functions", "atanh", x@jc)
column(jc)
})

#' avg
#'
#' Aggregate function: returns the average of the values in a group.
Expand Down
1 change: 1 addition & 0 deletions R/pkg/tests/fulltests/test_sparkSQL.R
Original file line number Diff line number Diff line change
Expand Up @@ -1430,6 +1430,7 @@ test_that("column functions", {
nth_value(column("v"), 3) + nth_value(column("z"), 4L, FALSE)
c28 <- asc_nulls_first(c1) + asc_nulls_last(c1) +
desc_nulls_first(c1) + desc_nulls_last(c1)
c29 <- acosh(c1) + asinh(c1) + atanh(c1)

# Test if base::is.nan() is exposed
expect_equal(is.nan(c("a", "b")), c(FALSE, FALSE))
Expand Down
4 changes: 3 additions & 1 deletion python/docs/source/reference/pyspark.sql.rst
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,7 @@ Functions

abs
acos
acosh
add_months
aggregate
approxCountDistinct
Expand All @@ -331,8 +332,10 @@ Functions
asc_nulls_last
ascii
asin
asinh
assert_true
atan
atanh
atan2
avg
base64
Expand Down Expand Up @@ -583,4 +586,3 @@ Grouping
GroupedData.pivot
GroupedData.sum
PandasCogroupedOps.applyInPandas

39 changes: 39 additions & 0 deletions python/pyspark/sql/functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -220,6 +220,19 @@ def acos(col):
return _invoke_function_over_column("acos", col)


def acosh(col):
"""
Computes inverse hyperbolic cosine of the input column.
.. versionadded:: 3.1.0
Returns
-------
:class:`Column`
"""
return _invoke_function_over_column("acosh", col)


def asin(col):
"""
.. versionadded:: 1.3.0
Expand All @@ -233,6 +246,19 @@ def asin(col):
return _invoke_function_over_column("asin", col)


def asinh(col):
"""
Computes inverse hyperbolic sine of the input column.
.. versionadded:: 3.1.0
Returns
-------
:class:`Column`
"""
return _invoke_function_over_column("asinh", col)


def atan(col):
"""
.. versionadded:: 1.4.0
Expand All @@ -245,6 +271,19 @@ def atan(col):
return _invoke_function_over_column("atan", col)


def atanh(col):
"""
Computes inverse hyperbolic tangent of the input column.
.. versionadded:: 3.1.0
Returns
-------
:class:`Column`
"""
return _invoke_function_over_column("atanh", col)


@since(1.4)
def cbrt(col):
"""
Expand Down
3 changes: 3 additions & 0 deletions python/pyspark/sql/functions.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -260,12 +260,15 @@ def map_zip_with(
) -> Column: ...
def abs(col: ColumnOrName) -> Column: ...
def acos(col: ColumnOrName) -> Column: ...
def acosh(col: ColumnOrName) -> Column: ...
def asc(col: ColumnOrName) -> Column: ...
def asc_nulls_first(col: ColumnOrName) -> Column: ...
def asc_nulls_last(col: ColumnOrName) -> Column: ...
def ascii(col: ColumnOrName) -> Column: ...
def asin(col: ColumnOrName) -> Column: ...
def asinh(col: ColumnOrName) -> Column: ...
def atan(col: ColumnOrName) -> Column: ...
def atanh(col: ColumnOrName) -> Column: ...
@overload
def atan2(col1: ColumnOrName, col2: ColumnOrName) -> Column: ...
@overload
Expand Down
16 changes: 16 additions & 0 deletions python/pyspark/sql/tests/test_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ def assert_close(a, b):
c = get_values(b)
diff = [abs(v - c[k]) < 1e-6 for k, v in enumerate(a)]
return sum(diff) == len(a)

assert_close([math.cos(i) for i in range(10)],
df.select(functions.cos(df.a)).collect())
assert_close([math.cos(i) for i in range(10)],
Expand All @@ -139,6 +140,21 @@ def assert_close(a, b):
assert_close([math.hypot(i, 2) for i in range(10)],
df.select(functions.hypot(df.a, 2)).collect())

def test_inverse_trig_functions(self):
from pyspark.sql import functions

funs = [
(functions.acosh, "ACOSH"),
(functions.asinh, "ASINH"),
(functions.atanh, "ATANH"),
]

cols = ["a", functions.col("a")]

for f, alias in funs:
for c in cols:
self.assertIn(f"{alias}(a)", repr(f(c)))

def test_rand_functions(self):
df = self.df
from pyspark.sql import functions
Expand Down

0 comments on commit d082ad0

Please sign in to comment.