mz_ore/
permutations.rs

1// Copyright Materialize, Inc. and contributors. All rights reserved.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License in the LICENSE file at the
6// root of this repository, or online at
7//
8//     http://www.apache.org/licenses/LICENSE-2.0
9//
10// Unless required by applicable law or agreed to in writing, software
11// distributed under the License is distributed on an "AS IS" BASIS,
12// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13// See the License for the specific language governing permissions and
14// limitations under the License.
15
16//! Functions for working with permutations
17
18use std::collections::BTreeMap;
19
20/// Given a permutation, construct its inverse.
21pub fn invert<I>(permutation: I) -> impl Iterator<Item = (usize, usize)>
22where
23    I: IntoIterator<Item = usize>,
24{
25    permutation.into_iter().enumerate().map(|(idx, c)| (c, idx))
26}
27
28/// Construct the permutation that sorts `data`.
29pub fn argsort<T>(data: &[T]) -> Vec<usize>
30where
31    T: Ord,
32{
33    let mut indices = (0..data.len()).collect::<Vec<_>>();
34    indices.sort_by_key(|&i| &data[i]);
35    indices
36}
37
38/// Construct the permutation that takes `data.sorted()` to `data`.
39pub fn inverse_argsort<T>(data: &[T]) -> Vec<usize>
40where
41    T: Ord,
42{
43    let map = invert(argsort(data)).collect::<BTreeMap<_, _>>();
44    (0..data.len()).map(|i| map[&i]).collect()
45}