Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Commit

Permalink
Support trigonometric functions acos, asin, atan, atan2, cos, cot, de…
Browse files Browse the repository at this point in the history
…grees, radians, sin, tan (#599)

* support trigonometric functions acos, asin, atan, atan2, cos, cot, degrees, radians, sin, tan

* updated doc

* added sql comparison test cases

* added integ test cases in ppl

* update
  • Loading branch information
chloe-zh authored Jul 22, 2020
1 parent 78a51a4 commit 49883b9
Show file tree
Hide file tree
Showing 11 changed files with 999 additions and 21 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,21 @@ public static LiteralExpression literal(ExprValue value) {
return new LiteralExpression(value);
}

/**
* Wrap a number to {@link LiteralExpression}.
*/
public static LiteralExpression literal(Number value) {
if (value instanceof Integer) {
return new LiteralExpression(ExprValueUtils.integerValue(value.intValue()));
} else if (value instanceof Long) {
return new LiteralExpression(ExprValueUtils.longValue(value.longValue()));
} else if (value instanceof Float) {
return new LiteralExpression(ExprValueUtils.floatValue(value.floatValue()));
} else {
return new LiteralExpression(ExprValueUtils.doubleValue(value.doubleValue()));
}
}

public static ReferenceExpression ref(String ref, ExprType type) {
return new ReferenceExpression(ref, type);
}
Expand Down Expand Up @@ -144,6 +159,46 @@ public FunctionExpression truncate(Expression... expressions) {
return function(BuiltinFunctionName.TRUNCATE, expressions);
}

public FunctionExpression acos(Expression... expressions) {
return function(BuiltinFunctionName.ACOS, expressions);
}

public FunctionExpression asin(Expression... expressions) {
return function(BuiltinFunctionName.ASIN, expressions);
}

public FunctionExpression atan(Expression... expressions) {
return function(BuiltinFunctionName.ATAN, expressions);
}

public FunctionExpression atan2(Expression... expressions) {
return function(BuiltinFunctionName.ATAN2, expressions);
}

public FunctionExpression cos(Expression... expressions) {
return function(BuiltinFunctionName.COS, expressions);
}

public FunctionExpression cot(Expression... expressions) {
return function(BuiltinFunctionName.COT, expressions);
}

public FunctionExpression degrees(Expression... expressions) {
return function(BuiltinFunctionName.DEGREES, expressions);
}

public FunctionExpression radians(Expression... expressions) {
return function(BuiltinFunctionName.RADIANS, expressions);
}

public FunctionExpression sin(Expression... expressions) {
return function(BuiltinFunctionName.SIN, expressions);
}

public FunctionExpression tan(Expression... expressions) {
return function(BuiltinFunctionName.TAN, expressions);
}

public FunctionExpression add(Expression... expressions) {
return function(BuiltinFunctionName.ADD, expressions);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,17 @@ public enum BuiltinFunctionName {
SQRT(FunctionName.of("sqrt")),
TRUNCATE(FunctionName.of("truncate")),

ACOS(FunctionName.of("acos")),
ASIN(FunctionName.of("asin")),
ATAN(FunctionName.of("atan")),
ATAN2(FunctionName.of("atan2")),
COS(FunctionName.of("cos")),
COT(FunctionName.of("cot")),
DEGREES(FunctionName.of("degrees")),
RADIANS(FunctionName.of("radians")),
SIN(FunctionName.of("sin")),
TAN(FunctionName.of("tan")),

/**
* Text Functions.
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,16 @@ public static void register(BuiltinFunctionRepository repository) {
repository.register(truncate());
repository.register(pi());
repository.register(rand());
repository.register(acos());
repository.register(asin());
repository.register(atan());
repository.register(atan2());
repository.register(cos());
repository.register(cot());
repository.register(degrees());
repository.register(radians());
repository.register(sin());
repository.register(tan());
}

/**
Expand Down Expand Up @@ -487,6 +497,154 @@ private static FunctionResolver truncate() {
.build());
}

/**
* Definition of acos(x) function.
* Calculates the arc cosine of x, that is, the value whose cosine is x.
* Returns NULL if x is not in the range -1 to 1.
* The supported signature of acos function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver acos() {
FunctionName functionName = BuiltinFunctionName.ACOS.getName();
return new FunctionResolver(
functionName,
singleArgumentFunction(functionName, v -> v < -1 || v > 1 ? null : Math.acos(v)));
}

/**
* Definition of asin(x) function.
* Calculates the arc sine of x, that is, the value whose sine is x.
* Returns NULL if x is not in the range -1 to 1.
* The supported signature of asin function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver asin() {
FunctionName functionName = BuiltinFunctionName.ASIN.getName();
return new FunctionResolver(
functionName,
singleArgumentFunction(functionName, v -> v < -1 || v > 1 ? null : Math.asin(v)));
}

/**
* Definition of atan(x) and atan(y, x) function.
* atan(x) calculates the arc tangent of x, that is, the value whose tangent is x.
* atan(y, x) calculates the arc tangent of y / x, except that the signs of both arguments
* are used to determine the quadrant of the result.
* The supported signature of atan function is
* (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE
*/
private static FunctionResolver atan() {
FunctionName functionName = BuiltinFunctionName.ATAN.getName();
return new FunctionResolver(functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(
new FunctionSignature(functionName, Arrays.asList(ExprCoreType.DOUBLE)),
unaryOperator(
functionName, Math::atan, ExprValueUtils::getDoubleValue, ExprCoreType.DOUBLE))
.put(
new FunctionSignature(
functionName, Arrays.asList(ExprCoreType.DOUBLE, ExprCoreType.DOUBLE)),
doubleArgFunc(functionName,
Math::atan2, ExprValueUtils::getDoubleValue, ExprValueUtils::getDoubleValue,
ExprCoreType.DOUBLE))
.build());
}

/**
* Definition of atan2(y, x) function.
* Calculates the arc tangent of y / x, except that the signs of both arguments
* are used to determine the quadrant of the result.
* The supported signature of atan2 function is
* (x: INTEGER/LONG/FLOAT/DOUBLE, y: INTEGER/LONG/FLOAT/DOUBLE) -> DOUBLE
*/
private static FunctionResolver atan2() {
FunctionName functionName = BuiltinFunctionName.ATAN2.getName();
return new FunctionResolver(functionName,
new ImmutableMap.Builder<FunctionSignature, FunctionBuilder>()
.put(
new FunctionSignature(
functionName, Arrays.asList(ExprCoreType.DOUBLE, ExprCoreType.DOUBLE)),
doubleArgFunc(functionName,
Math::atan2, ExprValueUtils::getDoubleValue, ExprValueUtils::getDoubleValue,
ExprCoreType.DOUBLE))
.build());
}

/**
* Definition of cos(x) function.
* Calculates the cosine of X, where X is given in radians
* The supported signature of cos function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver cos() {
FunctionName functionName = BuiltinFunctionName.COS.getName();
return new FunctionResolver(functionName, singleArgumentFunction(functionName, Math::cos));
}

/**
* Definition of cot(x) function.
* Calculates the cotangent of x
* The supported signature of cot function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver cot() {
FunctionName functionName = BuiltinFunctionName.COT.getName();
return new FunctionResolver(
functionName,
singleArgumentFunction(functionName, v -> {
if (v == 0) {
throw new ArithmeticException(String.format("Out of range value for cot(%s)", v));
}
return 1 / Math.tan(v);
}));
}

/**
* Definition of degrees(x) function.
* Converts x from radians to degrees
* The supported signature of degrees function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver degrees() {
FunctionName functionName = BuiltinFunctionName.DEGREES.getName();
return new FunctionResolver(
functionName, singleArgumentFunction(functionName, Math::toDegrees));
}

/**
* Definition of radians(x) function.
* Converts x from degrees to radians
* The supported signature of radians function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver radians() {
FunctionName functionName = BuiltinFunctionName.RADIANS.getName();
return new FunctionResolver(
functionName, singleArgumentFunction(functionName, Math::toRadians));
}

/**
* Definition of sin(x) function.
* Calculates the sine of x, where x is given in radians
* The supported signature of sin function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver sin() {
FunctionName functionName = BuiltinFunctionName.SIN.getName();
return new FunctionResolver(functionName, singleArgumentFunction(functionName, Math::sin));
}

/**
* Definition of tan(x) function.
* Calculates the tangent of x, where x is given in radians
* The supported signature of tan function is
* INTEGER/LONG/FLOAT/DOUBLE -> DOUBLE
*/
private static FunctionResolver tan() {
FunctionName functionName = BuiltinFunctionName.TAN.getName();
return new FunctionResolver(functionName, singleArgumentFunction(functionName, Math::tan));
}

/**
* Util method to generate single argument function bundles. Applicable for INTEGER -> INTEGER
* LONG -> LONG FLOAT -> FLOAT DOUBLE -> DOUBLE
Expand Down
Loading

0 comments on commit 49883b9

Please sign in to comment.