Skip to content

Commit

Permalink
feat(fronted): cotd implementation (#9259)
Browse files Browse the repository at this point in the history
  • Loading branch information
CAJan93 authored Apr 24, 2023
1 parent a504f0e commit ccfb492
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 12 deletions.
68 changes: 68 additions & 0 deletions e2e_test/batch/functions/trigonometric_funcs.slt.part
Original file line number Diff line number Diff line change
Expand Up @@ -429,5 +429,73 @@ SELECT abs(tand(-120) + -1.7320508075688772) < 0.000000000000001
----
t

query R
SELECT abs(cotd(45) - 1) < 0.000000000000001;
----
t

query R
SELECT abs(cotd(60) - 0.5773502691896257) < 0.000000000000001;
----
t

query R
SELECT cotd(90);
----
0

query R
SELECT abs(cotd(-45) + 1) < 0.000000000000001;
----
t

query R
SELECT abs(cotd(-60) + 0.5773502691896257) < 0.000000000000001;
----
t

query R
SELECT cotd(-90);
----
0

query R
SELECT abs(cotd(30) - 1.7320508075688772) < 0.000000000000001;
----
t

query R
SELECT abs(cotd(-30) + 1.7320508075688772) < 0.000000000000001;
----
t


query R
SELECT abs(cotd(120) + 0.5773502691896255) < 0.000000000000001;
----
t

query R
SELECT abs(cotd(-120) - 0.5773502691896255) < 0.000000000000001;
----
t

query R
SELECT cotd(('-Inf'))
----
NaN

query R
SELECT cotd(('Inf'))
----
NaN

query R
SELECT cotd('NaN')
----
NaN

query R
SELECT cotd('-NaN')
----
NaN
9 changes: 5 additions & 4 deletions proto/expr.proto
Original file line number Diff line number Diff line change
Expand Up @@ -113,10 +113,11 @@ message ExprNode {
ATAN2 = 252;
SIND = 253;
COSD = 254;
TAND = 255;
SQRT = 256;
DEGREES = 257;
RADIANS = 258;
COTD = 255;
TAND = 256;
SQRT = 257;
DEGREES = 258;
RADIANS = 259;

// Boolean comparison
IS_TRUE = 301;
Expand Down
75 changes: 68 additions & 7 deletions src/expr/src/vector_op/trigonometric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,24 +60,25 @@ pub fn atan2_f64(input_x: F64, input_y: F64) -> F64 {
static RADIANS_PER_DEGREE: f64 = 0.017_453_292_519_943_295;
// Constants we use to get more accurate results.
// See PSQL: https://github.com/postgres/postgres/blob/78ec02d612a9b69039ec2610740f738968fe144d/src/backend/utils/adt/float.c#L2024
static SIN_30: f64 = 0.499_999_999_999_999_94;
static ONE_MINUS_COS_60: f64 = 0.499_999_999_999_999_9;
static TAN_45: f64 = 1.0;
static SIND_30: f64 = 0.499_999_999_999_999_94;
static ONE_MINUS_COSD_60: f64 = 0.499_999_999_999_999_9;
static TAND_45: f64 = 1.0;
static COTD_45: f64 = 1.0;

// returns the cosine of an angle that lies between 0 and 60 degrees. This will return exactly 1
// when xi s 0, and exactly 0.5 when x is 60 degrees.
fn cosd_0_to_60(x: f64) -> f64 {
// https://github.com/postgres/postgres/blob/REL_15_2/src/backend/utils/adt/float.c
let one_minus_cos_x: f64 = 1.0 - f64::cos(x * RADIANS_PER_DEGREE);
1.0 - (one_minus_cos_x / ONE_MINUS_COS_60) / 2.0
1.0 - (one_minus_cos_x / ONE_MINUS_COSD_60) / 2.0
}

// returns the sine of an angle that lies between 0 and 30 degrees. This will return exactly 0 when
// x is 0, and exactly 0.5 when x is 30 degrees.
fn sind_0_to_30(x: f64) -> f64 {
// https://github.com/postgres/postgres/blob/REL_15_2/src/backend/utils/adt/float.c
let sin_x = f64::sin(x * RADIANS_PER_DEGREE);
(sin_x / SIN_30) / 2.0
(sin_x / SIND_30) / 2.0
}

// returns the cosine of an angle in the first quadrant (0 to 90 degrees).
Expand Down Expand Up @@ -184,6 +185,47 @@ pub fn sind_f64(input: F64) -> F64 {
}
}

#[function("cotd(float64) -> float64")]
pub fn cotd_f64(input: F64) -> F64 {
// PSQL implementation: https://github.com/postgres/postgres/blob/78ec02d612a9b69039ec2610740f738968fe144d/src/backend/utils/adt/float.c#L2378

// Returns NaN if input is NaN or infinite. Different from PSQL implementation.
if input.0.is_nan() || input.0.is_infinite() {
return f64::NAN.into();
}

let mut arg1 = input.0 % 360.0;
let mut sign = 1.0;

if arg1 < 0.0 {
// cotd(-x) = -cotd(x)
arg1 = -arg1;
sign = -sign;
}

if arg1 > 180.0 {
// cotd(360-x) = -cotd(x)
arg1 = 360.0 - arg1;
sign = -sign;
}

if arg1 > 90.0 {
// cotd(180-x) = -cotd(x)
arg1 = 180.0 - arg1;
sign = -sign;
}

let cot_arg1 = cosd_q1(arg1) / sind_q1(arg1);
let result = sign * (cot_arg1 / COTD_45);

// On some machines we get cotd(270) = minus zero, but this isn't always
// true. For portability, and because the user constituency for this
// function probably doesn't want minus zero, force it to plain zero.
let result = if result == 0.0 { 0.0 } else { result };
// Not checking for overflow because cotd(0) == Inf
result.into()
}

#[function("tand(float64) -> float64")]
pub fn tand_f64(input: F64) -> F64 {
// PSQL implementation: https://github.com/postgres/postgres/blob/REL_15_2/src/backend/utils/adt/float.c
Expand Down Expand Up @@ -219,7 +261,7 @@ pub fn tand_f64(input: F64) -> F64 {
}

let tan_arg1 = sind_q1(arg1) / cosd_q1(arg1);
let result = sign * (tan_arg1 / TAN_45);
let result = sign * (tan_arg1 / TAND_45);

// On some machines we get tand(180) = minus zero, but this isn't always
// true. For portability, and because the user constituency for this
Expand All @@ -240,9 +282,9 @@ pub fn radians_f64(input: F64) -> F64 {

#[cfg(test)]
mod tests {

use std::f64::consts::PI;

use num_traits::Float;
use risingwave_common::types::F64;

use crate::vector_op::trigonometric::*;
Expand Down Expand Up @@ -300,6 +342,25 @@ mod tests {
assert_eq!(cosd_f64(F64::from(0)).0, 1.0);
assert_eq!(cosd_f64(F64::from(90)).0, 0.0);

// cotd
assert_eq!(F64::from(-f64::INFINITY), cotd_f64(d));
assert!(cotd_f64(F64::from(-180)).is_infinite());
assert!(
(cotd_f64(F64::from(-190)) + F64::from(5.671281819617705))
.abs()
.0
<= 0.00000000000001,
);
assert_similar(cot_f64(50_f64.to_radians().into()), cotd_f64(F64::from(50)));
assert_similar(
cot_f64(100_f64.to_radians().into()),
cotd_f64(F64::from(100)),
);
assert_similar(
cot_f64(250_f64.to_radians().into()),
cotd_f64(F64::from(250)),
);

// tand
assert_similar(
tan_f64((-10_f64).to_radians().into()),
Expand Down
1 change: 1 addition & 0 deletions src/frontend/src/binder/expr/function.rs
Original file line number Diff line number Diff line change
Expand Up @@ -367,6 +367,7 @@ impl Binder {
("atan2", raw_call(ExprType::Atan2)),
("sind", raw_call(ExprType::Sind)),
("cosd", raw_call(ExprType::Cosd)),
("cotd", raw_call(ExprType::Cotd)),
("tand", raw_call(ExprType::Tand)),
("degrees", raw_call(ExprType::Degrees)),
("radians", raw_call(ExprType::Radians)),
Expand Down
3 changes: 2 additions & 1 deletion src/frontend/src/expr/pure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,8 +150,9 @@ impl ExprVisitor<bool> for ImpureAnalyzer {
| expr_node::Type::Pi
| expr_node::Type::Sind
| expr_node::Type::Cosd
| expr_node::Type::Encode
| expr_node::Type::Cotd
| expr_node::Type::Decode
| expr_node::Type::Encode
| expr_node::Type::Tand
| expr_node::Type::ArrayPositions
| expr_node::Type::StringToArray =>
Expand Down

0 comments on commit ccfb492

Please sign in to comment.