haar_lib/algebra/
permutation.rs1pub use crate::algebra::traits::*;
3use crate::impl_algebra;
4
5#[derive(Clone, Debug, Default)]
7pub struct Permutation {
8 value: Option<Vec<usize>>,
9}
10
11impl Permutation {
12 pub fn get(&self, i: usize) -> usize {
14 self.value.as_ref().map_or_else(|| i, |a| a[i])
15 }
16
17 pub fn apply<T: Clone>(&self, a: Vec<T>) -> Vec<T> {
19 self.value
20 .as_ref()
21 .map(|t| t.iter().map(|&i| a[i].clone()).collect())
22 .unwrap_or(a)
23 }
24
25 pub fn is_identity(&self) -> bool {
27 self.value
28 .as_ref()
29 .is_none_or(|a| a.iter().enumerate().all(|(i, &x)| i == x))
30 }
31
32 pub fn compose(self, other: Self) -> Self {
34 Self {
35 value: match (self.value, other.value) {
36 (Some(a), Some(b)) => {
37 let n = a.len();
38 assert_eq!(a.len(), b.len());
39 Some((0..n).map(|i| a[b[i]]).collect())
40 }
41 (a, None) => a,
42 (None, b) => b,
43 },
44 }
45 }
46
47 pub fn inv(self) -> Self {
49 self.value
50 .as_ref()
51 .map(|a| {
52 let n = a.len();
53 let mut ret = vec![0; n];
54 for i in 0..n {
55 ret[a[i]] = i;
56 }
57 Self { value: Some(ret) }
58 })
59 .unwrap_or(self)
60 }
61}
62
63impl TryFrom<Vec<usize>> for Permutation {
64 type Error = &'static str;
65
66 fn try_from(value: Vec<usize>) -> Result<Self, Self::Error> {
67 let mut check = vec![false; value.len()];
68
69 for &x in &value {
70 if x >= value.len() || check[x] {
71 return Err("0から`.len()`未満の値からなる順列でなければならない。");
72 }
73 check[x] = true;
74 }
75 Ok(Self { value: Some(value) })
76 }
77}
78
79impl PartialEq for Permutation {
80 fn eq(&self, other: &Self) -> bool {
81 match (&self.value, &other.value) {
82 (Some(a), Some(b)) => a == b,
83 _ => self.is_identity() && other.is_identity(),
84 }
85 }
86}
87
88impl_algebra!(
89 Permutation;
90 op: |a: Self, b: Self| a.compose(b);
91 inv: |a: Self| a.inv();
92 id: Self { value: None };
93 assoc;
94);
95
96#[cfg(test)]
97mod tests {
98 use super::*;
99 use rand::seq::SliceRandom;
100
101 #[test]
102 fn test() {
103 let mut rng = rand::thread_rng();
104
105 let n = 100;
106
107 let mut a = (0..n).collect::<Vec<_>>();
108 a.shuffle(&mut rng);
109 let a = Permutation::try_from(a).unwrap();
110
111 let b = a.clone().inv();
112
113 assert_eq!(a.op(b), Permutation::id());
114 }
115}