feanor_math/seq/
permute.rs1use std::alloc::{Allocator, Global};
2
3use super::SwappableVectorViewMut;
4
5#[stability::unstable(feature = "enable")]
9pub fn permute<V, T, F>(values: V, perm: F)
10 where V: SwappableVectorViewMut<T>, F: Fn(usize) -> usize
11{
12 permute_using_allocator(values, perm, Global)
13}
14
15#[stability::unstable(feature = "enable")]
19pub fn permute_using_allocator<V, T, F, A: Allocator>(mut values: V, perm: F, allocator: A)
20 where V: SwappableVectorViewMut<T>, F: Fn(usize) -> usize
21{
22 let mut swapped_indices = Vec::with_capacity_in(values.len(), allocator);
23 swapped_indices.extend((0..values.len()).map(|_| false));
24 let mut start = 0;
25 while start < values.len() {
26 let mut current = start;
27 let mut next = perm(current);
28 while !swapped_indices[next] {
29 swapped_indices[current] = true;
30 values.swap(current, next);
31 current = next;
32 next = perm(current);
33 }
34 swapped_indices[current] = true;
35 start += 1;
36 }
37}
38
39#[stability::unstable(feature = "enable")]
44pub fn permute_inv<V, T, F>(values: V, perm: F)
45 where V: SwappableVectorViewMut<T>, F: Fn(usize) -> usize
46{
47 permute_inv_using_allocator(values, perm, Global)
48}
49
50#[stability::unstable(feature = "enable")]
55pub fn permute_inv_using_allocator<V, T, F, A: Allocator>(mut values: V, perm: F, allocator: A)
56 where V: SwappableVectorViewMut<T>, F: Fn(usize) -> usize
57{
58 let mut swapped_indices = Vec::with_capacity_in(values.len(), allocator);
59 swapped_indices.extend((0..values.len()).map(|_| false));
60 let mut start = 0;
61 while start < values.len() {
62 let mut current = perm(start);
63 swapped_indices[start] = true;
64 while !swapped_indices[current] {
65 swapped_indices[current] = true;
66 values.swap(current, start);
67 current = perm(current);
68 }
69 start += 1;
70 }
71}
72
73#[test]
74fn test_permute() {
75 let mut values = [0, 1, 2, 3, 4, 5, 6, 7];
76 let permutation = [2, 1, 7, 5, 6, 3, 4, 0];
77 permute(&mut values, |i| permutation[i]);
78 assert_eq!(values, permutation);
79}
80
81#[test]
82fn test_permute_inv() {
83 let mut values = [2, 1, 7, 5, 6, 3, 4, 0];
84 let permutation = [2, 1, 7, 5, 6, 3, 4, 0];
85 permute_inv(&mut values, |i| permutation[i]);
86 assert_eq!(values, [0, 1, 2, 3, 4, 5, 6, 7]);
87}