Tue, 07 Jul 2026 11:53:22 +0300
num_traits::float::TotalOrder to Float trait bounds. Remove NaNLeast.
| Cargo.lock | file | annotate | diff | comparison | revisions | |
| Cargo.toml | file | annotate | diff | comparison | revisions | |
| src/bisection_tree/refine.rs | file | annotate | diff | comparison | revisions | |
| src/lib.rs | file | annotate | diff | comparison | revisions | |
| src/nanleast.rs | file | annotate | diff | comparison | revisions | |
| src/types.rs | file | annotate | diff | comparison | revisions |
--- a/Cargo.lock Fri May 15 14:46:30 2026 -0500 +++ b/Cargo.lock Tue Jul 07 11:53:22 2026 +0300 @@ -4,7 +4,7 @@ [[package]] name = "alg_tools" -version = "0.4.1-dev" +version = "0.5.1-dev" dependencies = [ "anyhow", "colored",
--- a/Cargo.toml Fri May 15 14:46:30 2026 -0500 +++ b/Cargo.toml Tue Jul 07 11:53:22 2026 +0300 @@ -1,6 +1,6 @@ [package] name = "alg_tools" -version = "0.4.1-dev" +version = "0.5.1-dev" edition = "2021" rust-version = "1.85" authors = ["Tuomo Valkonen <tuomov@iki.fi>"]
--- a/src/bisection_tree/refine.rs Fri May 15 14:46:30 2026 -0500 +++ b/src/bisection_tree/refine.rs Tue Jul 07 11:53:22 2026 +0300 @@ -1,12 +1,12 @@ use super::aggregator::*; use super::bt::*; use super::support::*; -use crate::nanleast::NaNLeast; use crate::parallelism::TaskBudget; use crate::parallelism::{thread_pool, thread_pool_size}; use crate::sets::Cube; use crate::types::*; -use std::cmp::{max, Ord, Ordering, Ordering::*, PartialOrd}; +use num_traits::float::TotalOrder; +use std::cmp::{Ord, Ordering, Ordering::*, PartialOrd}; use std::collections::BinaryHeap; use std::marker::PhantomData; use std::sync::{Arc, Condvar, Mutex, MutexGuard}; @@ -19,7 +19,11 @@ pub trait AggregatorSorting: Sync + Send + 'static { // Priority type Agg: Aggregator; - type Sort: Ord + Copy + std::fmt::Debug + Sync + Send; + /// This is temporarily a Float, after removal of NanLeast, to use [ + /// `num_traits::float::TotalOrder`] and [`num_traits::float::Float::max`]. + /// It should be generalised by introducing a general PseudoTotalOrder trait + /// (because Rust's standard one is not implemented for `Float`s) + type Sort: Float + Copy + std::fmt::Debug + Sync + Send; /// Returns lower sorting key fn sort_lower(aggregator: &Self::Agg) -> Self::Sort; @@ -43,41 +47,41 @@ impl<F: Float> AggregatorSorting for UpperBoundSorting<F> { type Agg = Bounds<F>; - type Sort = NaNLeast<F>; + type Sort = F; #[inline] fn sort_lower(aggregator: &Bounds<F>) -> Self::Sort { - NaNLeast(aggregator.lower()) + aggregator.lower() } #[inline] fn sort_upper(aggregator: &Bounds<F>) -> Self::Sort { - NaNLeast(aggregator.upper()) + aggregator.upper() } #[inline] fn bottom() -> Self::Sort { - NaNLeast(F::NEG_INFINITY) + F::NEG_INFINITY } } impl<F: Float> AggregatorSorting for LowerBoundSorting<F> { type Agg = Bounds<F>; - type Sort = NaNLeast<F>; + type Sort = F; #[inline] fn sort_upper(aggregator: &Bounds<F>) -> Self::Sort { - NaNLeast(-aggregator.lower()) + -aggregator.lower() } #[inline] fn sort_lower(aggregator: &Bounds<F>) -> Self::Sort { - NaNLeast(-aggregator.upper()) + -aggregator.upper() } #[inline] fn bottom() -> Self::Sort { - NaNLeast(F::NEG_INFINITY) + F::NEG_INFINITY } } @@ -240,9 +244,11 @@ #[inline] fn cmp(&self, other: &Self) -> Ordering { self.with_aggregator(|agg1| { - other.with_aggregator(|agg2| match S::sort_upper(agg1).cmp(&S::sort_upper(agg2)) { - Equal => S::sort_lower(agg1).cmp(&S::sort_lower(agg2)), - order => order, + other.with_aggregator(|agg2| { + match S::sort_upper(agg1).total_cmp(&S::sort_upper(agg2)) { + Equal => S::sort_lower(agg1).total_cmp(&S::sort_lower(agg2)), + order => order, + } }) }) } @@ -318,12 +324,7 @@ { // Insert all subnodes into the refinement heap. for (node, cube) in self.nodes_and_cubes_mut(&domain) { - container.push(RefinementInfo { - cube, - node, - refiner_info: None, - sorting: PhantomData, - }); + container.push(RefinementInfo { cube, node, refiner_info: None, sorting: PhantomData }); } } } @@ -540,7 +541,12 @@ // Do priority queue maintenance if container.insert_counter > container.heap_prune_threshold { // Make sure glb is good. - match container.heap.iter().map(|ri| ri.sort_lower()).reduce(max) { + match container + .heap + .iter() + .map(|ri| ri.sort_lower()) + .reduce(num_traits::Float::max) + { Some(glb) => { container.glb = glb; // Prune
--- a/src/lib.rs Fri May 15 14:46:30 2026 -0500 +++ b/src/lib.rs Tue Jul 07 11:53:22 2026 +0300 @@ -23,7 +23,6 @@ pub mod euclidean; pub mod instance; pub mod maputil; -pub mod nanleast; pub mod norms; pub mod parallelism; pub mod tuple;
--- a/src/nanleast.rs Fri May 15 14:46:30 2026 -0500 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,44 +0,0 @@ -/*! -This module provides an artificial total order of floating point numbers. - -The [`NaNLeast`]`<F>` container for `F` a [`Float`] puts `F` in an [`Ord`] total order with -`NaN` the least element. This allows the numbers to be sorted with `NaN` the “least important” -element when looking for the maximum. Thus erroneous computations producing `NaN` can be ignored -when there are good results. -*/ - -use crate::types::Float; -use std::cmp::{PartialOrd,Ord,Ordering,Ordering::*}; - -/// A container for floating point numbers. -/// -/// The implementation of [`Ord`] for this type type sorts `NaN` as the least element. -#[derive(Debug, Clone, Copy)] -pub struct NaNLeast<F : Float>(pub F); - -impl<F : Float> Ord for NaNLeast<F> { - #[inline] - fn cmp(&self, NaNLeast(b) : &Self) -> Ordering { - let NaNLeast(a) = self; - match a.partial_cmp(b) { - None => match (a.is_nan(), b.is_nan()) { - (true, false) => Less, - (false, true) => Greater, - _ => Equal // The case (true, true) should not occur! - } - Some(order) => order - } - } -} - -impl<F : Float> PartialEq for NaNLeast<F> { - #[inline] - fn eq(&self, other : &Self) -> bool { self.cmp(other)==Equal } -} - -impl<F : Float> Eq for NaNLeast<F> { } - -impl<F : Float> PartialOrd for NaNLeast<F> { - #[inline] - fn partial_cmp(&self, other : &Self) -> Option<Ordering> { Some(self.cmp(other)) } -}
--- a/src/types.rs Fri May 15 14:46:30 2026 -0500 +++ b/src/types.rs Tue Jul 07 11:53:22 2026 +0300 @@ -11,6 +11,7 @@ //use trait_set::trait_set; pub use num_traits::cast::AsPrimitive; +pub use num_traits::float::TotalOrder; pub use num_traits::Float as NumTraitsFloat; // needed to re-export functions. pub use simba::scalar::{ @@ -97,7 +98,10 @@ impl<U: Num + num::Signed + std::ops::Neg<Output = Self>> SignedNum for U {} /// Trait for floating point numbers -pub trait Float: SignedNum + std::fmt::LowerExp + num::Float /*+ From<Self::CompatibleSize>*/ { +pub trait Float: + SignedNum + std::fmt::LowerExp + num::Float + num_traits::float::TotalOrder +/*+ From<Self::CompatibleSize>*/ +{ // An unsigned integer that can be used for indexing operations and // converted to F without loss. //type CompatibleSize : CompatibleUnsigned<Self>;