Skip to content

Commit f8cbf58

Browse files
committed
Bump ndarray-slice.
Reduces time complexity in the length of `indexes`.
1 parent 2c3af42 commit f8cbf58

File tree

5 files changed

+55
-23
lines changed

5 files changed

+55
-23
lines changed

Cargo.toml

+4-2
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,12 @@ categories = ["data-structures", "science"]
1717

1818
[dependencies]
1919
ndarray = "0.15.0"
20-
ndarray-slice = "0.1.1"
20+
ndarray-slice = "0.2.0"
2121
noisy_float = "0.2.0"
2222
num-integer = "0.1"
2323
num-traits = "0.2"
2424
rand = "0.8.3"
2525
itertools = { version = "0.10.0", default-features = false }
26-
indexmap = "1.6.2"
2726

2827
[dev-dependencies]
2928
ndarray = { version = "0.15.0", features = ["approx"] }
@@ -45,3 +44,6 @@ harness = false
4544
[[bench]]
4645
name = "deviation"
4746
harness = false
47+
48+
[profile.test]
49+
opt-level = 2

benches/sort.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,8 @@ fn get_many_from_sorted_mut(c: &mut Criterion) {
4242
b.iter_batched(
4343
|| Array1::from(data.clone()),
4444
|mut arr| {
45-
black_box(arr.select_many_nth_unstable(&indices));
45+
let mut values = Vec::with_capacity(indices.len());
46+
black_box(arr.select_many_nth_unstable(&indices, &mut values));
4647
},
4748
BatchSize::SmallInput,
4849
)

src/quantile/mod.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,11 @@ use self::interpolate::{higher_index, lower_index, Interpolate};
22
use crate::errors::QuantileError;
33
use crate::errors::{EmptyInput, MinMaxError, MinMaxError::UndefinedOrder};
44
use crate::{MaybeNan, MaybeNanExt};
5-
use indexmap::IndexMap;
65
use ndarray::prelude::*;
76
use ndarray::{Data, DataMut, RemoveAxis, Zip};
87
use ndarray_slice::Slice1Ext;
98
use noisy_float::types::N64;
10-
use std::cmp;
9+
use std::{cmp, collections::HashMap};
1110

1211
/// Quantile methods for `ArrayBase`.
1312
pub trait QuantileExt<A, S, D>
@@ -480,20 +479,16 @@ where
480479
Zip::from(results.lanes_mut(axis))
481480
.and(data.lanes_mut(axis))
482481
.for_each(|mut results, mut data| {
483-
let (lower_values, _higher) = data.select_many_nth_unstable(&indexes);
484-
let index_map = indexes
485-
.iter()
486-
.copied()
487-
.zip(lower_values.iter().map(|(_lower, value)| (*value).clone()))
488-
.collect::<IndexMap<usize, A>>();
482+
let mut values = HashMap::new();
483+
data.select_many_nth_unstable(&indexes, &mut values);
489484
for (result, &q) in results.iter_mut().zip(qs) {
490485
let lower = if I::needs_lower(q, axis_len) {
491-
Some(index_map[&lower_index(q, axis_len)].clone())
486+
Some(values[&lower_index(q, axis_len)].clone())
492487
} else {
493488
None
494489
};
495490
let higher = if I::needs_higher(q, axis_len) {
496-
Some(index_map[&higher_index(q, axis_len)].clone())
491+
Some(values[&higher_index(q, axis_len)].clone())
497492
} else {
498493
None
499494
};

tests/quantile.rs

+39
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,45 @@ fn test_max_skipnan_all_nan() {
168168
assert!(a.max_skipnan().is_nan());
169169
}
170170

171+
#[test]
172+
fn test_quantile_mut_with_large_array_of_equal_floats() {
173+
let mut array: Array1<N64> = Array1::ones(10_000_000);
174+
array.quantile_mut(n64(0.5), &Linear).unwrap();
175+
}
176+
177+
#[test]
178+
fn test_quantile_mut_with_large_array_of_sorted_floats() {
179+
let mut array: Array1<N64> = Array1::range(n64(0.0), n64(1e7), n64(1.0));
180+
array.quantile_mut(n64(0.5), &Linear).unwrap();
181+
}
182+
183+
#[test]
184+
fn test_quantile_mut_with_large_array_of_rev_sorted_floats() {
185+
let mut array: Array1<N64> = Array1::range(n64(1e7), n64(0.0), n64(-1.0));
186+
array.quantile_mut(n64(0.5), &Linear).unwrap();
187+
}
188+
189+
#[test]
190+
fn test_quantiles_mut_with_large_array_of_equal_floats() {
191+
let mut array: Array1<N64> = Array1::ones(10_000_000);
192+
let quantiles: Array1<N64> = Array1::range(n64(0.0), n64(1.0), n64(1e-5));
193+
array.quantiles_mut(&quantiles, &Linear).unwrap();
194+
}
195+
196+
#[test]
197+
fn test_quantiles_mut_with_large_array_of_sorted_floats() {
198+
let mut array: Array1<N64> = Array1::range(n64(0.0), n64(1e7), n64(1.0));
199+
let quantiles: Array1<N64> = Array1::range(n64(0.0), n64(1.0), n64(1e-5));
200+
array.quantiles_mut(&quantiles, &Linear).unwrap();
201+
}
202+
203+
#[test]
204+
fn test_quantiles_mut_with_large_array_of_rev_sorted_floats() {
205+
let mut array: Array1<N64> = Array1::range(n64(1e7), n64(0.0), n64(-1.0));
206+
let quantiles: Array1<N64> = Array1::range(n64(0.0), n64(1.0), n64(1e-5));
207+
array.quantiles_mut(&quantiles, &Linear).unwrap();
208+
}
209+
171210
#[test]
172211
fn test_quantile_axis_mut_with_odd_axis_length() {
173212
let mut a = arr2(&[[1, 3, 2, 10], [2, 4, 3, 11], [3, 5, 6, 12]]);

tests/sort.rs

+5-10
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use ndarray::prelude::*;
22
use ndarray_slice::Slice1Ext;
33
use quickcheck_macros::quickcheck;
4+
use std::collections::HashMap;
45

56
#[test]
67
fn test_sorted_get_mut() {
@@ -28,18 +29,12 @@ fn test_sorted_get_many_mut(mut xs: Vec<i64>) -> bool {
2829
indexes.sort_unstable();
2930
let (indexes, _duplicates) = indexes.partition_dedup();
3031

31-
let mut sorted_v = Vec::with_capacity(n);
32-
for value in v
33-
.select_many_nth_unstable(&indexes)
34-
.0
35-
.into_iter()
36-
.map(|(_, value)| *value)
37-
{
38-
sorted_v.push(value);
39-
}
32+
let mut map = HashMap::new();
33+
v.select_many_nth_unstable(&indexes, &mut map);
34+
let sorted_v = indexes.map(|index| *map[index]);
4035
xs.sort();
4136
println!("Sorted: {:?}. Truth: {:?}", sorted_v, xs);
42-
xs == sorted_v
37+
Array::from_vec(xs) == sorted_v
4338
}
4439
}
4540

0 commit comments

Comments
 (0)