Skip to content

Commit

Permalink
[SPARK-33061][SQL] Expose inverse hyperbolic trig functions through s…
Browse files Browse the repository at this point in the history
…ql.functions API

This patch is a small extension to change-request SPARK-28133, which added inverse hyperbolic functions to the SQL interpreter, but did not include those methods within the Scala `sql.functions._` API. This patch makes `acosh`, `asinh` and `atanh` functions available through the Scala API.

Unit-tests have been added to `sql/core/src/test/scala/org/apache/spark/sql/MathFunctionsSuite.scala`. Manual testing has been done via `spark-shell`, using the following recipe:
```
val df = spark.range(0, 11)
              .toDF("x")
              .withColumn("x", ($"x" - 5) / 2.0)
val hyps = df.withColumn("tanh", tanh($"x"))
             .withColumn("sinh", sinh($"x"))
             .withColumn("cosh", cosh($"x"))
val invhyps = hyps.withColumn("atanh", atanh($"tanh"))
                  .withColumn("asinh", asinh($"sinh"))
                  .withColumn("acosh", acosh($"cosh"))
invhyps.show
```
which produces the following output:
```
+----+--------------------+-------------------+------------------+-------------------+-------------------+------------------+
|   x|                tanh|               sinh|              cosh|              atanh|              asinh|             acosh|
+----+--------------------+-------------------+------------------+-------------------+-------------------+------------------+
|-2.5| -0.9866142981514303|-6.0502044810397875| 6.132289479663686| -2.500000000000001|-2.4999999999999956|               2.5|
|-2.0| -0.9640275800758169| -3.626860407847019|3.7621956910836314|-2.0000000000000004|-1.9999999999999991|               2.0|
|-1.5| -0.9051482536448664|-2.1292794550948173| 2.352409615243247|-1.4999999999999998|-1.4999999999999998|               1.5|
|-1.0| -0.7615941559557649|-1.1752011936438014| 1.543080634815244|               -1.0|               -1.0|               1.0|
|-0.5|-0.46211715726000974|-0.5210953054937474|1.1276259652063807|               -0.5|-0.5000000000000002|0.4999999999999998|
| 0.0|                 0.0|                0.0|               1.0|                0.0|                0.0|               0.0|
| 0.5| 0.46211715726000974| 0.5210953054937474|1.1276259652063807|                0.5|                0.5|0.4999999999999998|
| 1.0|  0.7615941559557649| 1.1752011936438014| 1.543080634815244|                1.0|                1.0|               1.0|
| 1.5|  0.9051482536448664| 2.1292794550948173| 2.352409615243247| 1.4999999999999998|                1.5|               1.5|
| 2.0|  0.9640275800758169|  3.626860407847019|3.7621956910836314| 2.0000000000000004|                2.0|               2.0|
| 2.5|  0.9866142981514303| 6.0502044810397875| 6.132289479663686|  2.500000000000001|                2.5|               2.5|
+----+--------------------+-------------------+------------------+-------------------+-------------------+------------------+
```

Closes #29938 from rwpenney/fix/inverse-hyperbolics.

Authored-by: Richard Penney <rwp@rwpenney.uk>
Signed-off-by: Sean Owen <srowen@gmail.com>
  • Loading branch information
rwpenney authored and srowen committed Oct 14, 2020
1 parent 05a62dc commit d8c4a47
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 1 deletion.
50 changes: 49 additions & 1 deletion sql/core/src/main/scala/org/apache/spark/sql/functions.scala
Expand Up @@ -1427,6 +1427,22 @@ object functions {
*/
def acos(columnName: String): Column = acos(Column(columnName))

/**
* @return inverse hyperbolic cosine of `e`
*
* @group math_funcs
* @since 3.1.0
*/
def acosh(e: Column): Column = withExpr { Acosh(e.expr) }

/**
* @return inverse hyperbolic cosine of `columnName`
*
* @group math_funcs
* @since 3.1.0
*/
def acosh(columnName: String): Column = acosh(Column(columnName))

/**
* @return inverse sine of `e` in radians, as if computed by `java.lang.Math.asin`
*
Expand All @@ -1444,7 +1460,23 @@ object functions {
def asin(columnName: String): Column = asin(Column(columnName))

/**
* @return inverse tangent of `e`, as if computed by `java.lang.Math.atan`
* @return inverse hyperbolic sine of `e`
*
* @group math_funcs
* @since 3.1.0
*/
def asinh(e: Column): Column = withExpr { Asinh(e.expr) }

/**
* @return inverse hyperbolic sine of `columnName`
*
* @group math_funcs
* @since 3.1.0
*/
def asinh(columnName: String): Column = asinh(Column(columnName))

/**
* @return inverse tangent of `e` as if computed by `java.lang.Math.atan`
*
* @group math_funcs
* @since 1.4.0
Expand Down Expand Up @@ -1572,6 +1604,22 @@ object functions {
*/
def atan2(yValue: Double, xName: String): Column = atan2(yValue, Column(xName))

/**
* @return inverse hyperbolic tangent of `e`
*
* @group math_funcs
* @since 3.1.0
*/
def atanh(e: Column): Column = withExpr { Atanh(e.expr) }

/**
* @return inverse hyperbolic tangent of `columnName`
*
* @group math_funcs
* @since 3.1.0
*/
def atanh(columnName: String): Column = atanh(Column(columnName))

/**
* An expression that returns the string representation of the binary value of the given long
* column. For example, bin("12") returns "1100".
Expand Down
Expand Up @@ -125,6 +125,11 @@ class MathFunctionsSuite extends QueryTest with SharedSparkSession {
testOneToOneMathFunction(sinh, math.sinh)
}

test("asinh") {
testOneToOneMathFunction(asinh,
(x: Double) => math.log(x + math.sqrt(x * x + 1)) )
}

test("cos") {
testOneToOneMathFunction(cos, math.cos)
}
Expand All @@ -137,6 +142,11 @@ class MathFunctionsSuite extends QueryTest with SharedSparkSession {
testOneToOneMathFunction(cosh, math.cosh)
}

test("acosh") {
testOneToOneMathFunction(acosh,
(x: Double) => math.log(x + math.sqrt(x * x - 1)) )
}

test("tan") {
testOneToOneMathFunction(tan, math.tan)
}
Expand All @@ -149,6 +159,11 @@ class MathFunctionsSuite extends QueryTest with SharedSparkSession {
testOneToOneMathFunction(tanh, math.tanh)
}

test("atanh") {
testOneToOneMathFunction(atanh,
(x: Double) => (0.5 * (math.log1p(x) - math.log1p(-x))) )
}

test("degrees") {
testOneToOneMathFunction(degrees, math.toDegrees)
checkAnswer(
Expand Down

0 comments on commit d8c4a47

Please sign in to comment.