Skip to content

Commit

Permalink
3.0.6
Browse files Browse the repository at this point in the history
  • Loading branch information
liborty committed Jan 17, 2024
1 parent 2ac4743 commit 5b407b9
Show file tree
Hide file tree
Showing 6 changed files with 15 additions and 58 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "medians"
version = "3.0.5"
version = "3.0.6"
authors = ["Libor Spacek"]
edition = "2021"
description = "Median, Statistical Measures, Mathematics, Statistics"
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,8 @@ pub trait Median<'a, T> {

## Release Notes

**Version 3.0.6** - Moved `part`, `ref_vec` and `deref_vec` into crate `Indxvec`, to allow their wider use.

**Version 3.0.5** - Obsolete code pruning.

**Version 3.0.4** - Some minor code simplifications.
Expand Down
43 changes: 3 additions & 40 deletions src/algos.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,6 @@
use core::cmp::{Ordering, Ordering::*};
use std::ops::Range;

/// Constructs ref wrapped `Vec<&T>` from `&[T] in rng`
pub fn ref_vec<T>(v: &[T], rng: Range<usize>) -> Vec<&T> {
v.iter().take(rng.end).skip(rng.start).collect()
}
use indxvec::Mutops;

/// Index of the middling value of four refs. Makes only three comparisons
fn middling(
Expand Down Expand Up @@ -80,39 +76,6 @@ pub fn qbalance<T>(s: &[T], centre: &f64, q: impl Fn(&T) -> f64) -> i64 {
1
}

/// Partitions `s: &mut [&T]` within range `rng`, using comparator `c`.
/// The first item `s[rng.start]` is assumed to be the pivot.
/// The three rearranged partitions are demarcated by eqstart,gtstart, where:
/// `rng.start..eqstart` (may be empty) contains refs to items lesser than the pivot,
/// `gtstart-eqstart` is the number (>= 1) of items equal to the pivot (values within this subrange are undefined)
/// `gtstart..rng.end` (may be empty) contains refs to items greater than the pivot.
pub fn part<T>(
s: &mut [&T],
rng: &Range<usize>,
c: &mut impl FnMut(&T, &T) -> Ordering,
) -> (usize, usize) {
// get pivot from the first location
let pivot = s[rng.start];
let mut eqstart = rng.start;
let mut gtstart = eqstart + 1;
for t in rng.start + 1..rng.end {
match c(s[t], pivot) {
Less => {
s[eqstart] = s[t];
eqstart += 1;
s[t] = s[gtstart];
gtstart += 1;
}
Equal => {
s[t] = s[gtstart];
gtstart += 1;
}
Greater => (),
}
}
(eqstart, gtstart)
}

/// Odd median of `&[u8]`
pub fn oddmedianu8(s: &[u8]) -> f64 {
let need = s.len() / 2; // median target position
Expand Down Expand Up @@ -183,7 +146,7 @@ pub fn oddmedian_by<'a, T>(s: &mut [&'a T], c: &mut impl FnMut(&T, &T) -> Orderi
s.swap(rng.start, pivotsub);
};
let pivotref = s[rng.start];
let (eqsub, gtsub) = part(s, &rng, c);
let (eqsub, gtsub) = <&mut [T]>::part(s, &rng, c);
// well inside lt partition, iterate on it
if need + 2 < eqsub {
rng.end = eqsub;
Expand Down Expand Up @@ -235,7 +198,7 @@ pub fn evenmedian_by<'a, T>(
s.swap(rng.start, pivotsub);
};
let pivotref = s[rng.start];
let (eqsub, gtsub) = part(s, &rng, c);
let (eqsub, gtsub) = <&mut [T]>::part(s, &rng, c);
// well inside lt partition, iterate on it narrowing the range
if need + 2 < eqsub {
rng.end = eqsub;
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::algos::*;
pub use crate::error::{merror, MedError};

use core::{cmp::Ordering, fmt::Display};
use indxvec::printing::{GR, UN, YL};
use indxvec::{Vecops,printing::{GR, UN, YL}};

/// Shorthand type for medians errors with message payload specialized to String
pub type Me = MedError<String>;
Expand Down Expand Up @@ -141,7 +141,7 @@ impl Medianf64 for &[f64] {
2 => return (self[0] + self[1]) / 2.0,
_ => (),
};
let mut s = ref_vec(self, 0..self.len());
let mut s = self.ref_vec(0..self.len());
if (n & 1) == 1 {
let oddm = oddmedian_by(&mut s, &mut <f64>::total_cmp);
*oddm
Expand Down Expand Up @@ -211,7 +211,7 @@ impl<'a, T> Median<'a, T> for &'a [T] {
2 => return Ok((q(&self[0]) + q(&self[1])) / 2.0),
_ => (),
};
let mut s = ref_vec(self, 0..self.len());
let mut s = self.ref_vec(0..self.len());
if (n & 1) == 1 {
Ok(q(oddmedian_by(&mut s, c)))
} else {
Expand All @@ -229,7 +229,7 @@ impl<'a, T> Median<'a, T> for &'a [T] {
2 => return Ok(Medians::Even((&self[0], &self[1]))),
_ => (),
};
let mut s = ref_vec(self, 0..self.len());
let mut s = self.ref_vec(0..self.len());
if (n & 1) == 1 {
Ok(Medians::Odd(oddmedian_by(&mut s, c)))
} else {
Expand Down
8 changes: 0 additions & 8 deletions src/oldalgos.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,14 +50,6 @@ pub fn to_f64s(v: &[u64]) -> Vec<f64> {
v.iter().map(|&u| to_f64(u)).collect()
}

/// Builds Vec<T> from refs in Vec<&T> (inverse of ref_vec())
pub fn deref_vec<T>(v: &[&T]) -> Vec<T>
where
T: Clone,
{
v.iter().map(|&x| x.clone()).collect()
}

/// Maps general `quantify` closure to self, converting the type T -> U
pub fn quant_vec<T, U>(v: &[T], quantify: impl Fn(&T) -> U) -> Vec<U> {
v.iter().map(quantify).collect::<Vec<U>>()
Expand Down
10 changes: 5 additions & 5 deletions tests/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
#![allow(dead_code)]
#[cfg(test)]
use indxvec::{here, printing::*, Indices, Mutops, Printing, Vecops};
use medians::algos::{qbalance, part, ref_vec, min, min2};
use medians::algos::{qbalance, min, min2};
// use medians::algosf64::partord;
use medians::{Me, merror, medianu8, Median, Medianf64};
use ran:: *;
Expand All @@ -22,8 +22,8 @@ fn parting() -> Result<(), Me> {
// println!("Scrubbed: {}", scrub_nans(&to_f64s(&to_u64s(&data))).gr());
let len = data.len();
println!("Pivot {}: {}", data[0].yl(), data.gr());
let mut refdata = ref_vec(&data, 0..len);
let (eqsub, gtsub) = part(
let mut refdata = data.ref_vec(0..len);
let (eqsub, gtsub) = <&mut [f64]>::part(
&mut refdata,
&(0..len),
&mut <f64>::total_cmp,
Expand Down Expand Up @@ -75,10 +75,10 @@ fn medf64() -> Result<(), Me> {
];
println!("Data: {}",v.gr());
let len = v.len();
let mut vr = ref_vec(&v,0..len);
let mut vr = v.ref_vec(0..len);
println!("max: {}",min(&vr,0..len,&mut |a:&f64,b:&f64| b.total_cmp(a)).gr());
println!("max2: {}",min2(&vr,0..len,&mut |a:&f64,b:&f64| b.total_cmp(a)).gr());
let (eqsub,gtsub) = part(
let (eqsub,gtsub) = <&mut [f64]>::part(
&mut vr,
&(0..v.len()),
&mut <f64>::total_cmp,
Expand Down

0 comments on commit 5b407b9

Please sign in to comment.