Path: blob/main/crates/polars-core/src/series/arithmetic/owned.rs
8430 views
use super::*;1#[cfg(feature = "performant")]2use crate::utils::align_chunks_binary_owned_series;34#[cfg(feature = "performant")]5pub fn coerce_lhs_rhs_owned(lhs: Series, rhs: Series) -> PolarsResult<(Series, Series)> {6let dtype = try_get_supertype(lhs.dtype(), rhs.dtype())?;7let left = if lhs.dtype() == &dtype {8lhs9} else {10lhs.cast(&dtype)?11};12let right = if rhs.dtype() == &dtype {13rhs14} else {15rhs.cast(&dtype)?16};17Ok((left, right))18}1920fn is_eligible(lhs: &DataType, rhs: &DataType) -> bool {21!lhs.is_logical()22&& lhs.to_physical().is_primitive_numeric()23&& rhs.to_physical().is_primitive_numeric()24}2526#[cfg(feature = "performant")]27fn apply_operation_mut<T, F>(mut lhs: Series, mut rhs: Series, op: F) -> Series28where29T: PolarsNumericType,30F: Fn(ChunkedArray<T>, ChunkedArray<T>) -> ChunkedArray<T> + Copy,31{32let lhs_ca: &mut ChunkedArray<T> = lhs._get_inner_mut().as_mut();33let rhs_ca: &mut ChunkedArray<T> = rhs._get_inner_mut().as_mut();3435let lhs = std::mem::take(lhs_ca);36let rhs = std::mem::take(rhs_ca);3738op(lhs, rhs).into_series()39}4041macro_rules! impl_operation {42($operation:ident, $method:ident, $function:expr) => {43impl $operation for Series {44type Output = PolarsResult<Series>;4546fn $method(self, rhs: Self) -> Self::Output {47#[cfg(feature = "performant")]48{49// only physical numeric values take the mutable path50if is_eligible(self.dtype(), rhs.dtype()) {51let (lhs, rhs) = coerce_lhs_rhs_owned(self, rhs).unwrap();52let (lhs, rhs) = align_chunks_binary_owned_series(lhs, rhs);53use DataType::*;54Ok(match lhs.dtype() {55#[cfg(feature = "dtype-i8")]56Int8 => apply_operation_mut::<Int8Type, _>(lhs, rhs, $function),57#[cfg(feature = "dtype-i16")]58Int16 => apply_operation_mut::<Int16Type, _>(lhs, rhs, $function),59Int32 => apply_operation_mut::<Int32Type, _>(lhs, rhs, $function),60Int64 => apply_operation_mut::<Int64Type, _>(lhs, rhs, $function),61#[cfg(feature = "dtype-i128")]62Int128 => apply_operation_mut::<Int128Type, _>(lhs, rhs, $function),63#[cfg(feature = "dtype-u8")]64UInt8 => apply_operation_mut::<UInt8Type, _>(lhs, rhs, $function),65#[cfg(feature = "dtype-u16")]66UInt16 => apply_operation_mut::<UInt16Type, _>(lhs, rhs, $function),67UInt32 => apply_operation_mut::<UInt32Type, _>(lhs, rhs, $function),68UInt64 => apply_operation_mut::<UInt64Type, _>(lhs, rhs, $function),69#[cfg(feature = "dtype-u128")]70UInt128 => apply_operation_mut::<UInt128Type, _>(lhs, rhs, $function),71#[cfg(feature = "dtype-f16")]72Float16 => apply_operation_mut::<Float16Type, _>(lhs, rhs, $function),73Float32 => apply_operation_mut::<Float32Type, _>(lhs, rhs, $function),74Float64 => apply_operation_mut::<Float64Type, _>(lhs, rhs, $function),75_ => unreachable!(),76})77} else {78(&self).$method(&rhs)79}80}81#[cfg(not(feature = "performant"))]82{83(&self).$method(&rhs)84}85}86}87};88}8990impl_operation!(Add, add, |a, b| a.add(b));91impl_operation!(Sub, sub, |a, b| a.sub(b));92impl_operation!(Mul, mul, |a, b| a.mul(b));93impl_operation!(Div, div, |a, b| a.div(b));9495impl Series {96pub fn try_add_owned(self, other: Self) -> PolarsResult<Self> {97if is_eligible(self.dtype(), other.dtype()) {98self + other99} else {100std::ops::Add::add(&self, &other)101}102}103104pub fn try_sub_owned(self, other: Self) -> PolarsResult<Self> {105if is_eligible(self.dtype(), other.dtype()) {106self - other107} else {108std::ops::Sub::sub(&self, &other)109}110}111112pub fn try_mul_owned(self, other: Self) -> PolarsResult<Self> {113if is_eligible(self.dtype(), other.dtype()) {114self * other115} else {116std::ops::Mul::mul(&self, &other)117}118}119}120121122