@@ -154,6 +154,41 @@ where
154
154
A : Ord + Clone ,
155
155
S : DataMut ;
156
156
157
+ /// Equally spaces `sample` indexes around the center of `array` and sorts them by their values.
158
+ ///
159
+ /// `sample` content is ignored but its length defines the sample size and sample space divider.
160
+ ///
161
+ /// **Panics** if `self.len() < sample.len() + 2`.
162
+ ///
163
+ /// ```
164
+ /// use ndarray::Array1;
165
+ /// use ndarray_stats::Sort1dExt;
166
+ /// use noisy_float::types::n64;
167
+ ///
168
+ /// // Define sample size of 5.
169
+ /// let mut sample = [0; 5];
170
+ ///
171
+ /// // Create array from 100 down to 1;
172
+ /// let mut array = Array1::range(n64(100.0), n64(0.0), n64(-1.0));
173
+ /// assert_eq!(array.len(), 100);
174
+ ///
175
+ /// // Find `sample` indices and sort their values `array[sample[s]]`.
176
+ /// array.sample_mut(&mut sample);
177
+ ///
178
+ /// // Equally spaced by 13 non-sample elements around center of 50.
179
+ /// let assert = [22, 36, 50, 64, 78];
180
+ /// assert_eq!(sample, &assert[..]);
181
+ /// // Ensure `array[sample[s]]` is sorted.
182
+ /// assert_eq!(sample.map(|s| array[s]), assert.map(|s| s as f64));
183
+ /// // Ensure reverse order of non-sample elements is preserved.
184
+ /// assert_eq!(array[49], n64(51.0));
185
+ /// assert_eq!(array[51], n64(49.0));
186
+ /// ```
187
+ fn sample_mut ( & mut self , sample : & mut [ usize ] )
188
+ where
189
+ A : Ord + Clone ,
190
+ S : DataMut ;
191
+
157
192
private_decl ! { }
158
193
}
159
194
@@ -179,7 +214,7 @@ where
179
214
} else {
180
215
// Sorted sample of 5 equally spaced elements around the center.
181
216
let mut sample = [ 0 ; 5 ] ;
182
- sample_mut ( self , & mut sample) ;
217
+ self . sample_mut ( & mut sample) ;
183
218
// Adapt pivot sampling to relative sought rank and switch from dual-pivot to
184
219
// single-pivot partitioning for extreme sought ranks.
185
220
let sought_rank = i as f64 / n as f64 ;
@@ -344,6 +379,29 @@ where
344
379
( lower, upper)
345
380
}
346
381
382
+ fn sample_mut ( & mut self , sample : & mut [ usize ] )
383
+ where
384
+ A : Ord + Clone ,
385
+ S : DataMut ,
386
+ {
387
+ // Assumes arrays of at least `sample.len() + 2` elements.
388
+ assert ! ( self . len( ) >= sample. len( ) + 2 ) ;
389
+ // Space between sample indexes.
390
+ let space = self . len ( ) / ( sample. len ( ) + 2 ) ;
391
+ // Lowermost sample index.
392
+ let lowermost = self . len ( ) / 2 - ( sample. len ( ) / 2 ) * space;
393
+ // Equally space sample indexes and sort them by their values by looking up their indexes.
394
+ for mut index in 0 ..sample. len ( ) {
395
+ // Equally space sample indexes based on their lowermost index.
396
+ sample[ index] = lowermost + index * space;
397
+ // Insertion sort looking up only the already equally spaced sample indexes.
398
+ while index > 0 && self [ sample[ index - 1 ] ] > self [ sample[ index] ] {
399
+ self . swap ( sample[ index - 1 ] , sample[ index] ) ;
400
+ index -= 1 ;
401
+ }
402
+ }
403
+ }
404
+
347
405
private_impl ! { }
348
406
}
349
407
@@ -423,7 +481,7 @@ fn _get_many_from_sorted_mut_unchecked<A>(
423
481
424
482
// Sorted sample of 5 equally spaced elements around the center.
425
483
let mut sample = [ 0 ; 5 ] ;
426
- sample_mut ( & mut array , & mut sample) ;
484
+ array . sample_mut ( & mut sample) ;
427
485
// Since there is no single sought rank to adapt pivot sampling to, the recommended skewed
428
486
// pivot sampling of dual-pivot Quicksort is used in the assumption that multiple indexes
429
487
// change characteristics from Quickselect towards Quicksort.
@@ -505,29 +563,3 @@ fn _get_many_from_sorted_mut_unchecked<A>(
505
563
) ;
506
564
} ) ;
507
565
}
508
-
509
- /// Equally space `sample` indexes around the center of `array` and sort them by their values.
510
- ///
511
- /// `sample` content is ignored but its length defines the sample size and the sample space divider.
512
- ///
513
- /// Assumes arrays of at least `sample.len() + 2` elements.
514
- pub ( crate ) fn sample_mut < A , S > ( array : & mut ArrayBase < S , Ix1 > , sample : & mut [ usize ] )
515
- where
516
- A : Ord + Clone ,
517
- S : DataMut < Elem = A > ,
518
- {
519
- // Space between sample indexes.
520
- let space = array. len ( ) / ( sample. len ( ) + 2 ) ;
521
- // Lowermost sample index.
522
- let lowermost = array. len ( ) / 2 - ( sample. len ( ) / 2 ) * space;
523
- // Equally space sample indexes and sort them by their values by looking up their indexes.
524
- for mut index in 0 ..sample. len ( ) {
525
- // Equally space sample indexes based on their lowermost index.
526
- sample[ index] = lowermost + index * space;
527
- // Insertion sort looking up only the already equally spaced sample indexes.
528
- while index > 0 && array[ sample[ index - 1 ] ] > array[ sample[ index] ] {
529
- array. swap ( sample[ index - 1 ] , sample[ index] ) ;
530
- index -= 1 ;
531
- }
532
- }
533
- }
0 commit comments