haar_lib/algebra/
transform.rs

1//! 配列の並び替えの合成
2pub use crate::algebra::traits::*;
3use crate::impl_algebra;
4
5/// 変換操作
6#[derive(Clone, Debug, Default, PartialEq, Eq)]
7pub struct Transformation {
8    value: Vec<usize>,
9}
10
11impl Transformation {
12    /// 恒等変換を返す。
13    pub fn id(n: usize) -> Self {
14        Self {
15            value: (0..n).collect(),
16        }
17    }
18
19    /// `i`番目の要素を返す。
20    pub fn get(&self, i: usize) -> usize {
21        self.value[i]
22    }
23
24    /// $b_i = a_{T_i}$を満たすbを返す。
25    pub fn apply<T: Clone>(&self, a: Vec<T>) -> Vec<T> {
26        self.value.iter().map(|&i| a[i].clone()).collect()
27    }
28
29    /// 操作を合成する。
30    pub fn compose(self, other: Self) -> Self {
31        let (a, b) = (self.value, other.value);
32        let n = a.len();
33        assert_eq!(a.len(), b.len());
34        Self {
35            value: (0..n).map(|i| a[b[i]]).collect(),
36        }
37    }
38}
39
40impl TryFrom<Vec<usize>> for Transformation {
41    type Error = &'static str;
42
43    fn try_from(value: Vec<usize>) -> Result<Self, Self::Error> {
44        let n = value.len();
45        value
46            .iter()
47            .all(|&i| i < n)
48            .then_some(Self { value })
49            .ok_or("すべての値は`.len()`未満でなければならない。")
50    }
51}
52
53/// [`Transformation`]の合成
54#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
55pub struct Composition(pub usize);
56
57impl_algebra!(
58    Composition;
59    set: Transformation;
60    op: |_, a: Transformation, b: Transformation| a.compose(b);
61    id: |s: &Self| Transformation::id(s.0);
62    assoc;
63);