haar_lib/algebra/
transform.rs1pub use crate::algebra::traits::*;
3use crate::impl_algebra;
4
5#[derive(Clone, Debug, Default)]
7pub struct Transformation {
8 value: Option<Vec<usize>>,
9}
10
11impl Transformation {
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
48impl TryFrom<Vec<usize>> for Transformation {
49 type Error = &'static str;
50
51 fn try_from(value: Vec<usize>) -> Result<Self, Self::Error> {
52 let n = value.len();
53 value
54 .iter()
55 .all(|&i| i < n)
56 .then_some(Self { value: Some(value) })
57 .ok_or("すべての値は`.len()`未満でなければならない。")
58 }
59}
60
61impl PartialEq for Transformation {
62 fn eq(&self, other: &Self) -> bool {
63 match (&self.value, &other.value) {
64 (Some(a), Some(b)) => a == b,
65 _ => self.is_identity() && other.is_identity(),
66 }
67 }
68}
69
70impl_algebra!(
71 Transformation;
72 op: |a: Self, b: Self| a.compose(b);
73 id: Self { value: None };
74 assoc;
75);