Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions encodings/alp/src/alp/compute/compare.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ where
Operator::Gt | Operator::Gte => {
// Per IEEE 754 totalOrder semantics the ordering is -Nan < -Inf < Inf < Nan.
// All values in the encoded array are definitely finite
let is_not_finite = value.is_infinite() || NativePType::is_nan(value);
let is_not_finite = NativePType::is_infinite(value) || NativePType::is_nan(value);
if is_not_finite {
Ok(Some(
ConstantArray::new(value.is_sign_negative(), alp.len()).into_array(),
Expand All @@ -97,7 +97,7 @@ where
Operator::Lt | Operator::Lte => {
// Per IEEE 754 totalOrder semantics the ordering is -Nan < -Inf < Inf < Nan.
// All values in the encoded array are definitely finite
let is_not_finite = value.is_infinite() || NativePType::is_nan(value);
let is_not_finite = NativePType::is_infinite(value) || NativePType::is_nan(value);
if is_not_finite {
Ok(Some(
ConstantArray::new(value.is_sign_positive(), alp.len()).into_array(),
Expand Down
38 changes: 36 additions & 2 deletions vortex-array/src/arrays/primitive/compute/min_max.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,10 +38,13 @@ where

fn compute_min_max<'a, T>(iter: impl Iterator<Item = &'a T>, dtype: &DType) -> Option<MinMaxResult>
where
T: Into<ScalarValue> + NativePType + Copy,
T: Into<ScalarValue> + NativePType,
{
// this `compare` function provides a total ordering (even for NaN values)
match iter.minmax_by(|a, b| a.total_compare(**b)) {
match iter
.filter(|v| !v.is_nan() && !v.is_infinite())
.minmax_by(|a, b| a.total_compare(**b))
{
itertools::MinMaxResult::NoElements => None,
itertools::MinMaxResult::OneElement(&x) => {
let scalar = Scalar::new(dtype.clone(), x.into());
Expand All @@ -56,3 +59,34 @@ where
}),
}
}

#[cfg(test)]
mod tests {
use vortex_buffer::buffer;

use crate::arrays::PrimitiveArray;
use crate::compute::min_max;
use crate::validity::Validity;

#[test]
fn min_max_nan() {
let array = PrimitiveArray::new(
buffer![f32::NAN, -1.0 / 0.0, -1.0, 1.0],
Validity::NonNullable,
);
let min_max = min_max(&array).unwrap().unwrap();
assert_eq!(f32::try_from(min_max.min).unwrap(), -1.0);
assert_eq!(f32::try_from(min_max.max).unwrap(), 1.0);
}

#[test]
fn min_max_inf() {
let array = PrimitiveArray::new(
buffer![f32::INFINITY, f32::NEG_INFINITY, -1.0, 1.0],
Validity::NonNullable,
);
let min_max = min_max(&array).unwrap().unwrap();
assert_eq!(f32::try_from(min_max.min).unwrap(), -1.0);
assert_eq!(f32::try_from(min_max.max).unwrap(), 1.0);
}
}
14 changes: 14 additions & 0 deletions vortex-dtype/src/ptype.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,10 @@ pub trait NativePType:
/// For integer types, this is always `false`
fn is_nan(self) -> bool;

/// Whether this instance (`self`) is Infinite
/// For integer types, this is always `false`
fn is_infinite(self) -> bool;

/// Compare another instance of this type to `self`, providing a total ordering
fn total_compare(self, other: Self) -> Ordering;

Expand Down Expand Up @@ -121,6 +125,11 @@ macro_rules! native_ptype {
false
}

#[inline]
fn is_infinite(self) -> bool {
false
}

#[inline]
fn total_compare(self, other: Self) -> Ordering {
self.cmp(&other)
Expand All @@ -144,6 +153,11 @@ macro_rules! native_float_ptype {
<$T>::is_nan(self)
}

#[inline]
fn is_infinite(self) -> bool {
<$T>::is_infinite(self)
}

#[inline]
fn total_compare(self, other: Self) -> Ordering {
self.total_cmp(&other)
Expand Down
Loading