datafusion_functions/math/
bounds.rs

1// Licensed to the Apache Software Foundation (ASF) under one
2// or more contributor license agreements.  See the NOTICE file
3// distributed with this work for additional information
4// regarding copyright ownership.  The ASF licenses this file
5// to you under the Apache License, Version 2.0 (the
6// "License"); you may not use this file except in compliance
7// with the License.  You may obtain a copy of the License at
8//
9//   http://www.apache.org/licenses/LICENSE-2.0
10//
11// Unless required by applicable law or agreed to in writing,
12// software distributed under the License is distributed on an
13// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
14// KIND, either express or implied.  See the License for the
15// specific language governing permissions and limitations
16// under the License.
17
18use datafusion_common::ScalarValue;
19use datafusion_expr::interval_arithmetic::Interval;
20
21pub(super) fn unbounded_bounds(input: &[&Interval]) -> crate::Result<Interval> {
22    let data_type = input[0].data_type();
23
24    Interval::make_unbounded(&data_type)
25}
26
27pub(super) fn sin_bounds(input: &[&Interval]) -> crate::Result<Interval> {
28    // sin(x) is bounded by [-1, 1]
29    let data_type = input[0].data_type();
30
31    Interval::make_symmetric_unit_interval(&data_type)
32}
33
34pub(super) fn asin_bounds(input: &[&Interval]) -> crate::Result<Interval> {
35    // asin(x) is bounded by [-π/2, π/2]
36    let data_type = input[0].data_type();
37
38    Interval::make_symmetric_half_pi_interval(&data_type)
39}
40
41pub(super) fn atan_bounds(input: &[&Interval]) -> crate::Result<Interval> {
42    // atan(x) is bounded by [-π/2, π/2]
43    let data_type = input[0].data_type();
44
45    Interval::make_symmetric_half_pi_interval(&data_type)
46}
47
48pub(super) fn acos_bounds(input: &[&Interval]) -> crate::Result<Interval> {
49    // acos(x) is bounded by [0, π]
50    let data_type = input[0].data_type();
51
52    Interval::try_new(
53        ScalarValue::new_zero(&data_type)?,
54        ScalarValue::new_pi_upper(&data_type)?,
55    )
56}
57
58pub(super) fn acosh_bounds(input: &[&Interval]) -> crate::Result<Interval> {
59    // acosh(x) is bounded by [0, ∞)
60    let data_type = input[0].data_type();
61
62    Interval::make_non_negative_infinity_interval(&data_type)
63}
64
65pub(super) fn cos_bounds(input: &[&Interval]) -> crate::Result<Interval> {
66    // cos(x) is bounded by [-1, 1]
67    let data_type = input[0].data_type();
68
69    Interval::make_symmetric_unit_interval(&data_type)
70}
71
72pub(super) fn cosh_bounds(input: &[&Interval]) -> crate::Result<Interval> {
73    // cosh(x) is bounded by [1, ∞)
74    let data_type = input[0].data_type();
75
76    Interval::try_new(
77        ScalarValue::new_one(&data_type)?,
78        ScalarValue::try_from(&data_type)?,
79    )
80}
81
82pub(super) fn exp_bounds(input: &[&Interval]) -> crate::Result<Interval> {
83    // exp(x) is bounded by [0, ∞)
84    let data_type = input[0].data_type();
85
86    Interval::make_non_negative_infinity_interval(&data_type)
87}
88
89pub(super) fn radians_bounds(input: &[&Interval]) -> crate::Result<Interval> {
90    // radians(x) is bounded by (-π, π)
91    let data_type = input[0].data_type();
92
93    Interval::make_symmetric_pi_interval(&data_type)
94}
95
96pub(super) fn sqrt_bounds(input: &[&Interval]) -> crate::Result<Interval> {
97    // sqrt(x) is bounded by [0, ∞)
98    let data_type = input[0].data_type();
99
100    Interval::make_non_negative_infinity_interval(&data_type)
101}
102
103pub(super) fn tanh_bounds(input: &[&Interval]) -> crate::Result<Interval> {
104    // tanh(x) is bounded by (-1, 1)
105    let data_type = input[0].data_type();
106
107    Interval::make_symmetric_unit_interval(&data_type)
108}