Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
pola-rs
GitHub Repository: pola-rs/polars
Path: blob/main/crates/polars-compute/src/arithmetic/float.rs
8406 views
1
use arrow::array::PrimitiveArray as PArr;
2
use num_traits::{One, Zero};
3
use polars_utils::float16::pf16;
4
5
use super::PrimitiveArithmeticKernelImpl;
6
use crate::arity::{prim_binary_values, prim_unary_values};
7
8
macro_rules! impl_float_arith_kernel {
9
($T:ty) => {
10
impl PrimitiveArithmeticKernelImpl for $T {
11
type TrueDivT = $T;
12
13
fn prim_wrapping_abs(lhs: PArr<$T>) -> PArr<$T> {
14
prim_unary_values(lhs, |x| x.abs())
15
}
16
17
fn prim_wrapping_neg(lhs: PArr<$T>) -> PArr<$T> {
18
prim_unary_values(lhs, |x| -x)
19
}
20
21
fn prim_wrapping_add(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
22
prim_binary_values(lhs, rhs, |l, r| l + r)
23
}
24
25
fn prim_wrapping_sub(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
26
prim_binary_values(lhs, rhs, |l, r| l - r)
27
}
28
29
fn prim_wrapping_mul(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
30
prim_binary_values(lhs, rhs, |l, r| l * r)
31
}
32
33
fn prim_wrapping_floor_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
34
prim_binary_values(lhs, rhs, |l, r| (l / r).floor())
35
}
36
37
fn prim_wrapping_trunc_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
38
prim_binary_values(lhs, rhs, |l, r| (l / r).trunc())
39
}
40
41
fn prim_wrapping_mod(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<$T> {
42
prim_binary_values(lhs, rhs, |l, r| l - r * (l / r).floor())
43
}
44
45
fn prim_wrapping_add_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
46
if rhs == <$T>::zero() {
47
return lhs;
48
}
49
prim_unary_values(lhs, |x| x + rhs)
50
}
51
52
fn prim_wrapping_sub_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
53
if rhs == <$T>::zero() {
54
return lhs;
55
}
56
Self::prim_wrapping_add_scalar(lhs, -rhs)
57
}
58
59
fn prim_wrapping_sub_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
60
if lhs == <$T>::zero() {
61
Self::prim_wrapping_neg(rhs)
62
} else {
63
prim_unary_values(rhs, |x| lhs - x)
64
}
65
}
66
67
fn prim_wrapping_mul_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
68
// No optimization for multiplication by zero, would invalidate NaNs/infinities.
69
if rhs == <$T>::one() {
70
lhs
71
} else if rhs == -<$T>::one() {
72
Self::prim_wrapping_neg(lhs)
73
} else {
74
prim_unary_values(lhs, |x| x * rhs)
75
}
76
}
77
78
fn prim_wrapping_floor_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
79
let inv = <$T>::one() / rhs;
80
prim_unary_values(lhs, |x| (x * inv).floor())
81
}
82
83
fn prim_wrapping_floor_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
84
prim_unary_values(rhs, |x| (lhs / x).floor())
85
}
86
87
fn prim_wrapping_trunc_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
88
let inv = <$T>::one() / rhs;
89
prim_unary_values(lhs, |x| (x * inv).trunc())
90
}
91
92
fn prim_wrapping_trunc_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
93
prim_unary_values(rhs, |x| (lhs / x).trunc())
94
}
95
96
fn prim_wrapping_mod_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<$T> {
97
let inv = <$T>::one() / rhs;
98
prim_unary_values(lhs, |x| x - rhs * (x * inv).floor())
99
}
100
101
fn prim_wrapping_mod_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<$T> {
102
prim_unary_values(rhs, |x| lhs - x * (lhs / x).floor())
103
}
104
105
fn prim_checked_mul_scalar(_lhs: PArr<$T>, _rhs: $T) -> PArr<$T> {
106
unimplemented!()
107
}
108
109
fn prim_true_div(lhs: PArr<$T>, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {
110
prim_binary_values(lhs, rhs, |l, r| l / r)
111
}
112
113
fn prim_true_div_scalar(lhs: PArr<$T>, rhs: $T) -> PArr<Self::TrueDivT> {
114
Self::prim_wrapping_mul_scalar(lhs, <$T>::one() / rhs)
115
}
116
117
fn prim_true_div_scalar_lhs(lhs: $T, rhs: PArr<$T>) -> PArr<Self::TrueDivT> {
118
prim_unary_values(rhs, |x| lhs / x)
119
}
120
}
121
};
122
}
123
124
impl_float_arith_kernel!(pf16);
125
impl_float_arith_kernel!(f32);
126
impl_float_arith_kernel!(f64);
127
128