1use std::{collections::BTreeMap, fmt, ops::Index};
2
3use crate::half_edge::{
4 involution::Hedge,
5 subgraph::{InternalSubGraph, SubGraph, SubGraphOps},
6 HedgeGraph, NodeIndex,
7};
8use ahash::AHashSet;
9use bitvec::vec::BitVec;
10use thiserror::Error;
11
12use crate::half_edge::involution::Flow;
13
14#[derive(Debug, Clone, PartialEq, Eq, Hash)]
30pub struct Permutation {
31 map: Vec<usize>,
32 inv: Vec<usize>,
33}
34
35impl PartialOrd for Permutation {
37 fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
38 self.map.partial_cmp(&other.map)
39 }
40}
41
42impl Permutation {
43 pub fn id(n: usize) -> Self {
57 Permutation {
58 map: (0..n).collect(),
59 inv: (0..n).collect(),
60 }
61 }
62
63 pub fn from_map(map: Vec<usize>) -> Self {
74 let mut inv = vec![0; map.len()];
75 for (i, &j) in map.iter().enumerate() {
76 inv[j] = i;
77 }
78 Permutation { map, inv }
79 }
80
81 pub fn map(&self) -> &[usize] {
92 &self.map
93 }
94
95 pub fn inv(&self) -> &[usize] {
106 &self.inv
107 }
108
109 pub fn inverse(&self) -> Self {
124 Permutation {
125 map: self.inv.clone(),
126 inv: self.map.clone(),
127 }
128 }
129
130 pub fn apply_slice<T: Clone, S>(&self, slice: S) -> Vec<T>
141 where
142 S: AsRef<[T]>,
143 {
144 let s = slice.as_ref();
145 self.map.iter().map(|&idx| s[idx].clone()).collect()
146 }
147
148 pub fn apply_slice_inv<T: Clone, S>(&self, slice: S) -> Vec<T>
159 where
160 S: AsRef<[T]>,
161 {
162 let s = slice.as_ref();
163 self.inv.iter().map(|&idx| s[idx].clone()).collect()
164 }
165
166 pub fn apply_slice_in_place<T: Clone, S>(&self, slice: &mut S)
179 where
180 S: AsMut<[T]>,
181 {
182 let transpositions = self.transpositions();
183 for (i, j) in transpositions.iter().rev() {
184 slice.as_mut().swap(*i, *j);
185 }
186 }
187
188 pub fn apply_slice_in_place_inv<T: Clone, S>(&self, slice: &mut S)
201 where
202 S: AsMut<[T]>,
203 {
204 let transpositions = self.transpositions();
205 for (i, j) in transpositions {
206 slice.as_mut().swap(i, j);
207 }
208 }
209
210 pub fn compose(&self, other: &Self) -> Self {
213 let map = other.map.iter().map(|&i| self.map[i]).collect();
214 Self::from_map(map)
215 }
216
217 pub fn sort<T, S>(slice: S) -> Permutation
234 where
235 T: Ord,
236 S: AsRef<[T]>,
237 {
238 let s = slice.as_ref();
239 let mut permutation: Vec<usize> = (0..s.len()).collect();
240 permutation.sort_by_key(|&i| &s[i]);
241 Self::from_map(permutation)
242 }
243
244 pub fn find_cycles(&self) -> Vec<Vec<usize>> {
262 let mut visited = vec![false; self.map.len()];
263 let mut cycles = Vec::new();
264 for i in 0..self.map.len() {
265 if visited[i] {
266 continue;
267 }
268 let mut cycle = Vec::new();
269 let mut j = i;
270 while !visited[j] {
271 visited[j] = true;
272 cycle.push(j);
273 j = self.map[j];
274 }
275 if !cycle.is_empty() {
276 cycles.push(cycle);
277 }
278 }
279 cycles
280 }
281
282 pub fn cycle_to_transpositions(cycle: &[usize]) -> Vec<(usize, usize)> {
295 let mut transpositions = Vec::new();
296 for i in (1..cycle.len()).rev() {
297 transpositions.push((cycle[0], cycle[i]));
298 }
299 transpositions
300 }
301
302 pub fn transpositions(&self) -> Vec<(usize, usize)> {
314 let cycles = self.find_cycles();
315 let mut transpositions = Vec::new();
316 for cycle in cycles {
317 transpositions.extend(Self::cycle_to_transpositions(&cycle));
318 }
319 transpositions
320 }
321
322 pub fn myrvold_ruskey_rank1(mut self) -> usize {
340 let n = self.map.len();
341 if self.map.len() == 1 {
342 return 0;
343 }
344
345 let s = self.map[n - 1];
346 self.map.swap_remove(self.inv[n - 1]);
347 self.inv.swap_remove(s);
348
349 s + n * self.myrvold_ruskey_rank1()
350 }
351
352 pub fn myrvold_ruskey_unrank1(n: usize, mut rank: usize) -> Self {
362 let mut p = (0..n).collect::<Vec<_>>();
363 for i in (1..=n).rev() {
364 let j = rank % i;
365 rank /= i;
366 p.swap(i - 1, j);
367 }
368 Permutation::from_map(p)
369 }
370
371 fn factorial(n: usize) -> usize {
372 (1..=n).product()
373 }
374
375 pub fn myrvold_ruskey_rank2(mut self) -> usize {
388 let n = self.map.len();
389 if n == 1 {
390 return 0;
391 }
392 let s = self.map[n - 1];
393 self.map.swap_remove(self.inv[n - 1]);
394 self.inv.swap_remove(s);
395 s * Self::factorial(n - 1) + self.myrvold_ruskey_rank2()
396 }
397
398 pub fn myrvold_ruskey_unrank2(n: usize, mut rank: usize) -> Self {
408 let mut p = (0..n).collect::<Vec<_>>();
409 for i in (1..=n).rev() {
410 let s = rank / (Self::factorial(i - 1));
411 p.swap(i - 1, s);
412 rank %= Self::factorial(i - 1);
413 }
414 Permutation::from_map(p)
415 }
416
417 pub fn is_identity(&self) -> bool {
435 self.map.iter().enumerate().all(|(i, &m)| i == m)
436 }
437
438 pub fn sign(&self) -> i8 {
453 let mut sign = 1i8;
455 for cycle in self.find_cycles() {
456 let k = cycle.len();
458 if k > 1 && (k - 1) % 2 == 1 {
459 sign = -sign;
460 }
461 }
462 sign
463 }
464
465 pub fn pow(&self, k: usize) -> Self {
479 if k == 0 {
480 return Permutation::id(self.map.len());
481 }
482 let mut result = Permutation::id(self.map.len());
483 let mut base = self.clone();
484 let mut exp = k;
485
486 while exp > 0 {
487 if exp % 2 == 1 {
488 result = result.compose(&base);
489 }
490 base = base.compose(&base);
491 exp /= 2;
492 }
493 result
494 }
495}
496
497#[derive(Debug, Copy, Clone, Eq, PartialEq)]
499pub enum CycleOrder {
500 LastFirst,
502 FirstFirst,
504}
505
506impl fmt::Display for Permutation {
507 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
508 let cycles = self.find_cycles();
510 let mut first = true;
511 for cycle in cycles {
512 if cycle.len() > 1 {
513 if !first {
515 write!(f, " ")?;
516 }
517 write!(f, "(")?;
518 for (i, &x) in cycle.iter().enumerate() {
519 if i > 0 {
520 write!(f, " ")?;
521 }
522 write!(f, "{}", x)?;
523 }
524 write!(f, ")")?;
525 first = false;
526 }
527 }
528 if first {
529 write!(f, "()")?;
531 }
532
533 write!(f, " [")?;
535 for (i, &x) in self.map.iter().enumerate() {
536 if i > 0 {
537 write!(f, " ")?;
538 }
539 write!(f, "{}", x)?;
540 }
541 write!(f, "]")
542 }
543}
544
545impl Permutation {
546 pub fn from_disjoint_cycles(cycles: &[Vec<usize>]) -> Result<Self, String> {
563 let n = cycles
565 .iter()
566 .flat_map(|cycle| cycle.iter())
567 .max()
568 .map(|&max| max + 1)
569 .unwrap_or(0);
570
571 let mut seen = vec![false; n];
573 for cycle in cycles {
574 for &idx in cycle {
575 if seen[idx] {
576 return Err("Cycles are not disjoint".to_string());
577 }
578 seen[idx] = true;
579 }
580 }
581
582 let mut map = (0..n).collect::<Vec<_>>();
584 for cycle in cycles {
585 if cycle.len() <= 1 {
586 continue;
587 }
588
589 for i in 0..cycle.len() {
591 let from = cycle[i];
592 let to = cycle[(i + 1) % cycle.len()];
593 map[from] = to;
594 }
595 }
596
597 Ok(Permutation::from_map(map))
598 }
599 pub fn from_cycles_ordered(cycles: &[Vec<usize>], order: CycleOrder) -> Self {
601 let n = cycles
603 .iter()
604 .flat_map(|cycle| cycle.iter())
605 .max()
606 .map(|&max| max + 1)
607 .unwrap_or(0);
608
609 let mut result = Permutation::id(n);
611
612 let cycle_iter: Box<dyn Iterator<Item = &Vec<usize>>> = match order {
614 CycleOrder::LastFirst => Box::new(cycles.iter().rev()),
615 CycleOrder::FirstFirst => Box::new(cycles.iter()),
616 };
617
618 for cycle in cycle_iter {
620 if cycle.len() <= 1 {
621 continue;
622 }
623
624 let mut cycle_map = (0..n).collect::<Vec<_>>();
626 for i in 0..cycle.len() {
627 let from = cycle[i];
628 let to = cycle[(i + 1) % cycle.len()];
629 cycle_map[from] = to;
630 }
631 let cycle_perm = Permutation::from_map(cycle_map);
632 result = cycle_perm.compose(&result);
633 }
634
635 result
636 }
637
638 pub fn from_cycles(cycles: &[Vec<usize>]) -> Self {
650 Self::from_cycles_ordered(cycles, CycleOrder::LastFirst)
651 }
652
653 pub fn length(&self) -> usize {
654 self.map.len()
655 }
656
657 pub fn generate_all(generators: &[Permutation]) -> Result<Vec<Permutation>, PermutationError> {
658 let size = if let Some(generator) = generators.first() {
659 generator.length()
660 } else {
661 return Err(PermutationError::EmptyGenerators);
662 };
663 let mut all = AHashSet::new();
664 let mut stack = vec![Permutation::id(size)];
665 for g in generators {
666 if g.length() != size {
667 return Err(PermutationError::InvalidGeneratorLength);
668 }
669 }
670
671 while let Some(current) = stack.pop() {
672 for g in generators {
673 let next = current.compose(g);
674 if all.insert(next.clone()) {
675 stack.push(next);
676 }
677 }
678 }
679
680 Ok(all.drain().collect())
681 }
682}
683
684#[derive(Error, Debug)]
685pub enum PermutationError {
686 #[error("Invalid generator length")]
687 InvalidGeneratorLength,
688
689 #[error("Empty generators")]
690 EmptyGenerators,
691}
692
693pub trait HedgeGraphExt {
694 fn hedges_between(&self, a: NodeIndex, b: NodeIndex) -> BitVec;
695
696 fn permute_subgraph<S: SubGraph>(&self, subgraph: &S, hedge_perm: &Permutation) -> BitVec;
697
698 fn orientation_ord(&self, hedge: Hedge) -> u8;
699}
700
701pub trait PermutationExt<Orderer: Ord = ()> {
702 type Output;
705 type Edges;
706
707 fn permute_vertices(
708 &self,
709 perm: &Permutation,
710 ord: &impl Fn(&Self::Edges) -> Orderer,
711 ) -> Vec<Self::Output>;
712
713 fn sort_by(&self, hedge: Hedge, ord: &impl Fn(&Self::Edges) -> Orderer) -> impl Ord;
714
715 fn sort_by_perm(
716 &self,
717 hedge: Hedge,
718 perm: &Permutation,
719 ord: &impl Fn(&Self::Edges) -> Orderer,
720 ) -> impl Ord;
721}
722
723impl<E, V> HedgeGraphExt for HedgeGraph<E, V> {
724 fn hedges_between(&self, a: NodeIndex, b: NodeIndex) -> BitVec {
725 let a_ext =
726 InternalSubGraph::cleaned_filter_optimist(self.hairs_from_id(a).hairs.clone(), self)
727 .filter;
728 let b_ext =
729 InternalSubGraph::cleaned_filter_optimist(self.hairs_from_id(b).hairs.clone(), self)
730 .filter;
731 a_ext.intersection(&b_ext)
732 }
733
734 fn permute_subgraph<S: SubGraph>(&self, subgraph: &S, hedge_perm: &Permutation) -> BitVec {
735 let mut permuted_subgraph: BitVec = self.empty_subgraph();
736
737 for h in subgraph.included_iter() {
738 permuted_subgraph.set(hedge_perm[h.0], true);
739 }
740 permuted_subgraph
741 }
742
743 fn orientation_ord(&self, hedge: Hedge) -> u8 {
744 match self.superficial_hedge_orientation(hedge) {
745 Some(Flow::Sink) => 1,
746 Some(Flow::Source) => 2,
747 None => 0,
748 }
749 }
750}
751
752impl<E, V, O: Ord> PermutationExt<O> for HedgeGraph<E, V> {
753 type Output = Permutation;
754 type Edges = E;
755
756 fn permute_vertices(
757 &self,
758 perm: &Permutation,
759 ord: &impl Fn(&Self::Edges) -> O,
760 ) -> Vec<Self::Output> {
761 fn generator_pair(n: usize) -> [Permutation; 2] {
773 let mut map = Vec::new();
774 for i in 0..n {
775 map.push((i + 1) % n)
776 }
777 [
778 Permutation::from_map(map),
779 Permutation::from_cycles(&[vec![0, n - 1]]),
780 ]
781 }
782 let transpositions = perm.map();
783 let mut perms = Vec::new();
784
785 let n = self.n_hedges();
786 let mut map = (0..n).collect::<Vec<_>>();
787
788 for (from, &to) in transpositions.iter().enumerate() {
789 let from_hairs = &self.hairs_from_id(NodeIndex(from)).hairs;
790 let mut from_hedges = from_hairs.included_iter().collect::<Vec<_>>();
791 let to_hairs = &self.hairs_from_id(NodeIndex(to)).hairs;
792 let mut to_hedges = to_hairs.included_iter().collect::<Vec<_>>();
793
794 let mut to = BTreeMap::new();
795
796 to_hedges.iter().for_each(|&hedge| {
797 to.entry(self.sort_by_perm(hedge, perm, ord))
798 .or_insert_with(Vec::new)
799 .push(hedge);
800 });
801 to_hedges = to
802 .values()
803 .flat_map(|values| {
804 if values.len() > 1
805 && self.node_id(self.inv(values[0])).0 <= self.node_id(values[0]).0
806 {
808 let gen_pair = generator_pair(values.len());
809
810 let cycle = gen_pair[0].apply_slice(values);
811 let trans = gen_pair[1].apply_slice(values);
812
813 println!("{values:?}{cycle:?}{trans:?}");
814
815 let mut cycle_map = (0..n).collect::<Vec<_>>();
816 let mut trans_map = (0..n).collect::<Vec<_>>();
817 for i in 0..values.len() {
818 cycle_map[cycle[i].0] = values[i].0;
819 trans_map[trans[i].0] = values[i].0;
820 }
821
822 perms.push(Permutation::from_map(cycle_map));
823 perms.push(Permutation::from_map(trans_map));
824 }
825 values
826 })
827 .cloned()
828 .collect();
829
830 from_hedges.sort_by(|a, b| self.sort_by(*a, ord).cmp(&self.sort_by(*b, ord)));
839
840 for (from_hedge, to_hedge) in from_hedges.iter().zip(to_hedges.iter()) {
848 map[from_hedge.0] = to_hedge.0;
850 }
851 }
852 let mut maps = vec![];
853 let map = Permutation::from_map(map);
854 match Permutation::generate_all(&perms) {
856 Ok(a) => {
857 for p in a {
858 println!("Permutation:{p}");
859 println!("Composition:{}", map.compose(&p));
860 maps.push(map.compose(&p));
861 }
862 }
863 Err(PermutationError::EmptyGenerators) => maps.push(map),
864 Err(e) => panic!("Error generating permutations: {}", e),
865 }
866 maps
867 }
868
869 fn sort_by(&self, hedge: Hedge, ord: &impl Fn(&Self::Edges) -> O) -> impl Ord {
870 (
871 self.involved_node_id(hedge)
872 .unwrap_or(self.node_id(hedge))
873 .0,
874 self.orientation_ord(hedge),
875 ord(self.get_edge_data(hedge)),
876 )
877 }
878
879 fn sort_by_perm(
880 &self,
881 hedge: Hedge,
882 perm: &Permutation,
883 ord: &impl Fn(&Self::Edges) -> O,
884 ) -> impl Ord {
885 (
886 perm.inv()[self
887 .involved_node_id(hedge)
888 .unwrap_or(self.node_id(hedge))
889 .0],
890 self.orientation_ord(hedge),
891 ord(self.get_edge_data(hedge)),
892 )
893 }
894}
895
896impl Index<usize> for Permutation {
897 type Output = usize;
898
899 fn index(&self, index: usize) -> &Self::Output {
900 &self.map()[index]
901 }
902}
903
904#[cfg(test)]
905mod tests {
906 use crate::half_edge::{builder::HedgeGraphBuilder, involution::Flow};
907
908 use super::*;
909
910 #[test]
911 fn test_from_disjoint_cycles() {
912 let cycles = vec![vec![0, 3, 2], vec![1, 4]];
914 let p = Permutation::from_disjoint_cycles(&cycles).unwrap();
915 assert_eq!(p.map(), &[3, 4, 0, 2, 1]);
916
917 let cycles = vec![vec![0, 1, 2]];
919 let p = Permutation::from_disjoint_cycles(&cycles).unwrap();
920 assert_eq!(p.map(), &[1, 2, 0]);
921
922 let cycles = vec![vec![0, 1], vec![1, 2]];
924 assert!(Permutation::from_disjoint_cycles(&cycles).is_err());
925
926 let cycles: Vec<Vec<usize>> = vec![];
928 let p = Permutation::from_disjoint_cycles(&cycles).unwrap();
929 assert!(p.map().is_empty());
930
931 let cycles = vec![vec![0]];
933 let p = Permutation::from_disjoint_cycles(&cycles).unwrap();
934 assert_eq!(p.map(), &[0]);
935 }
936
937 #[test]
938 fn test_from_cycles_ordered() {
939 let cycles = vec![vec![0, 1, 2], vec![1, 2]];
940
941 let p = Permutation::from_cycles_ordered(&cycles, CycleOrder::LastFirst);
945 assert_eq!(p.map(), &[1, 0, 2]);
946
947 let p = Permutation::from_cycles_ordered(&cycles, CycleOrder::FirstFirst);
951 assert_eq!(p.map(), &[2, 1, 0]);
952 }
953
954 #[test]
955 fn test_cycle_composition_both_orders() {
956 let cycles = vec![vec![1, 2], vec![0, 1]];
958
959 let p = Permutation::from_cycles_ordered(&cycles, CycleOrder::LastFirst);
961 assert_eq!(p.map(), &[2, 0, 1]);
962
963 let p = Permutation::from_cycles_ordered(&cycles, CycleOrder::FirstFirst);
965 assert_eq!(p.map(), &[1, 2, 0]);
966 }
967
968 #[test]
969 fn test_default_order() {
970 let cycles = vec![vec![0, 1, 2], vec![1, 2]];
971 let p1 = Permutation::from_cycles(&cycles);
972 let p2 = Permutation::from_cycles_ordered(&cycles, CycleOrder::LastFirst);
973 assert_eq!(p1, p2);
974 }
975
976 #[test]
977 fn test_disjoint_cycles_order_invariant() {
978 let cycles = vec![vec![0, 1], vec![2, 3]];
979 let p1 = Permutation::from_cycles_ordered(&cycles, CycleOrder::LastFirst);
980 let p2 = Permutation::from_cycles_ordered(&cycles, CycleOrder::FirstFirst);
981 assert_eq!(p1, p2);
983 }
984
985 #[test]
986 fn test_from_cycles() {
987 let cycles = vec![vec![0, 1, 2]];
989 let p = Permutation::from_cycles(&cycles);
990 assert_eq!(p.map(), &[1, 2, 0]);
991
992 let cycles = vec![vec![0, 1, 2], vec![1, 2]];
994 let p = Permutation::from_cycles(&cycles);
995 assert_eq!(p.map(), &[1, 0, 2]);
996
997 let cycles = vec![vec![0, 1], vec![2, 3]];
999 let p = Permutation::from_cycles(&cycles);
1000 assert_eq!(p.map(), &[1, 0, 3, 2]);
1001
1002 let cycles = vec![vec![0, 1], vec![1, 2]]; let p = Permutation::from_cycles(&cycles);
1005 assert_eq!(p.map(), &[1, 2, 0]);
1006 }
1007
1008 #[test]
1009 fn test_cycle_composition_properties() {
1010 let p = Permutation::from_cycles(&[vec![0, 1, 2], vec![1, 2]]);
1012 let q = Permutation::from_cycles(&[vec![1, 0], vec![2]]);
1013 assert_eq!(p, q);
1014
1015 let p = Permutation::from_cycles(&[vec![0, 1], vec![1, 2]]);
1017 let q = Permutation::from_cycles(&[vec![1, 2, 0]]);
1018 assert_eq!(p, q);
1019 }
1020
1021 #[test]
1022 fn test_myrvold_ruskey_rank1() {
1023 let p = Permutation::from_map(vec![2, 1, 3, 0]);
1024 assert_eq!(p.myrvold_ruskey_rank1(), 12);
1025 for i in 0..=23 {
1026 assert_eq!(
1027 i,
1028 Permutation::myrvold_ruskey_rank1(Permutation::myrvold_ruskey_unrank1(4, i))
1029 );
1030 }
1031 }
1032
1033 #[test]
1034 fn test_myrvold_ruskey_rank2() {
1035 let p = Permutation::myrvold_ruskey_unrank2(4, 1);
1036 assert_eq!(p.map, vec![2, 1, 3, 0]);
1037 for i in 0..=23 {
1038 assert_eq!(
1039 i,
1040 Permutation::myrvold_ruskey_rank2(Permutation::myrvold_ruskey_unrank2(4, i))
1041 );
1042 }
1043 }
1044
1045 #[test]
1046 fn test_apply_slice() {
1047 let p = Permutation::from_map(vec![2, 1, 3, 0]);
1048 let data = vec![10, 20, 30, 40];
1049 let permuted = p.apply_slice(&data);
1050 assert_eq!(permuted, vec![30, 20, 40, 10]);
1051 }
1052
1053 #[test]
1054 fn test_apply_slice_inv() {
1055 let p = Permutation::from_map(vec![2, 1, 3, 0]);
1056 let data = vec![10, 20, 30, 40];
1057 let permuted = p.apply_slice_inv(&data);
1058 assert_eq!(permuted, vec![40, 20, 10, 30]);
1059 }
1060
1061 #[test]
1062 fn test_find_cycles() {
1063 let p = Permutation::from_map(vec![2, 0, 1, 3]);
1064 let cycles = p.find_cycles();
1065 assert_eq!(cycles, vec![vec![0, 2, 1], vec![3]]);
1066 }
1067
1068 #[test]
1069 fn test_cycle_to_transpositions() {
1070 let cycle = vec![0, 2, 1];
1071 let transpositions = Permutation::cycle_to_transpositions(&cycle);
1072 assert_eq!(transpositions, vec![(0, 1), (0, 2)]);
1073 }
1074
1075 #[test]
1076 fn test_transpositions() {
1077 let p = Permutation::sort([2, 1, 0, 3]);
1078
1079 let transpositions = p.transpositions();
1080 println!("{:?}", transpositions.len());
1081
1082 let p = Permutation::from_map(vec![2, 0, 1, 3]);
1083 let transpositions = p.transpositions();
1084 assert_eq!(transpositions, vec![(0, 1), (0, 2)]);
1085 }
1086
1087 #[test]
1088 fn test_apply_slice_in_place() {
1089 let p = Permutation::from_map(vec![2, 0, 1, 3]);
1090 let mut data = vec![10, 20, 30, 40];
1091 p.apply_slice_in_place(&mut data);
1092 assert_eq!(data, vec![20, 30, 10, 40]);
1093 }
1094
1095 #[test]
1096 fn test_apply_slice_in_place_inv() {
1097 let p = Permutation::from_map(vec![2, 0, 1, 3]);
1098 let mut data = vec![10, 20, 30, 40];
1099 p.apply_slice_in_place_inv(&mut data);
1100 assert_eq!(data, vec![30, 10, 20, 40]);
1101 }
1102
1103 #[test]
1104 fn test_sort() {
1105 let data = vec![30, 10, 20, 40];
1106 let perm = Permutation::sort(&data);
1107 assert_eq!(perm.map, vec![1, 2, 0, 3]);
1108
1109 let sorted_data = perm.apply_slice(&data);
1110 assert_eq!(sorted_data, vec![10, 20, 30, 40]);
1111 }
1112
1113 #[test]
1114 fn test_sort_inverse() {
1115 let data = vec![30, 10, 20, 40];
1116 let perm = Permutation::sort(&data);
1117 let sorted_data = perm.apply_slice(&data);
1118 assert_eq!(sorted_data, vec![10, 20, 30, 40]);
1119
1120 let inv_perm = perm.inverse();
1121 let original_data = inv_perm.apply_slice(&sorted_data);
1122 assert_eq!(original_data, data);
1123 }
1124
1125 #[test]
1128 fn test_is_identity() {
1129 let p = Permutation::id(5);
1130 assert!(p.is_identity());
1131
1132 let q = Permutation::from_map(vec![1, 0, 2]);
1133 assert!(!q.is_identity());
1134 }
1135
1136 #[test]
1137 fn test_sign() {
1138 let p = Permutation::from_map(vec![1, 0, 3, 2]);
1140 assert_eq!(p.sign(), 1);
1141
1142 let q = Permutation::from_map(vec![2, 1, 0]);
1144 assert_eq!(q.sign(), -1);
1145 }
1146
1147 #[test]
1148 fn test_pow() {
1149 let p = Permutation::from_map(vec![1, 2, 0]);
1150 assert_eq!(p.pow(1), p);
1152
1153 let p2 = p.pow(2);
1155 assert_eq!(p2.map(), &[2, 0, 1]);
1156
1157 let p3 = p.pow(3);
1159 assert_eq!(p3, Permutation::id(3));
1160 }
1161
1162 #[test]
1163 fn test_compose() {
1164 let p1 = Permutation::from_map(vec![1, 2, 0]);
1166
1167 let p2 = Permutation::from_map(vec![2, 0, 1]);
1169
1170 let c1 = p1.compose(&p2);
1175 assert_eq!(c1, Permutation::id(3), "Expected p2 ∘ p1 = identity");
1176
1177 let c2 = p2.compose(&p1);
1179 assert_eq!(c2, Permutation::id(3), "Expected p1 ∘ p2 = identity");
1180
1181 {
1182 let p1 = Permutation::from_map(vec![1, 0, 2]); let p2 = Permutation::from_map(vec![0, 2, 1]); let c1 = p1.compose(&p2); let c2 = p2.compose(&p1); assert_ne!(
1189 c1, c2,
1190 "Different order of composition should give different results"
1191 );
1192 assert_eq!(c1.map(), &[1, 2, 0]);
1193 assert_eq!(c2.map(), &[2, 0, 1]);
1194 }
1195
1196 {
1198 let p1 = Permutation::from_map(vec![1, 2, 0]);
1199 let p2 = Permutation::from_map(vec![2, 0, 1]);
1200 let p3 = Permutation::from_map(vec![0, 2, 1]);
1201
1202 let c1 = p1.compose(&p2).compose(&p3);
1203 let c2 = p1.compose(&p2.compose(&p3));
1204
1205 assert_eq!(c1, c2, "Composition should be associative");
1206 }
1207
1208 {
1210 let p1 = Permutation::from_map(vec![1, 0, 2, 3]); let p2 = Permutation::from_map(vec![0, 1, 3, 2]); let c = p1.compose(&p2);
1214 assert_eq!(
1215 c.map(),
1216 &[1, 0, 3, 2],
1217 "Disjoint cycles should compose independently"
1218 );
1219 }
1220
1221 {
1223 let p1 = Permutation::from_map(vec![1, 2, 3, 0]); let p2 = Permutation::from_map(vec![3, 2, 1, 0]); let c = p1.compose(&p2);
1227 assert_eq!(
1228 c.map(),
1229 &[0, 3, 2, 1],
1230 "Complex composition should work correctly"
1231 );
1232 }
1233 }
1234
1235 #[test]
1236 fn test_permute_graph() {
1237 let mut triangle = HedgeGraphBuilder::new();
1238
1239 let a = triangle.add_node(());
1240 let b = triangle.add_node(());
1241 let c = triangle.add_node(());
1242
1243 triangle.add_edge(a, b, (), false);
1244 triangle.add_edge(b, c, (), false);
1245 triangle.add_edge(c, a, (), false);
1246
1247 let graph = triangle.build();
1248 let perm = Permutation::from_cycles(&[vec![0, 2], vec![1]]); let perm2 = Permutation::from_cycles(&[vec![0, 1, 2]]); let a_b_edge = graph.hedges_between(a, b);
1252 let b_c_edge = graph.hedges_between(b, c);
1253 let c_a_edge = graph.hedges_between(c, a);
1254
1255 let hedge_perm = graph.permute_vertices(&perm, &|_| ());
1256 let hedge_perm2 = graph.permute_vertices(&perm2, &|_| ());
1257 let permuted_b_c_edge = graph.permute_subgraph(&b_c_edge, &hedge_perm[0]);
1258 let permuted_b_c_edge2 = graph.permute_subgraph(&b_c_edge, &hedge_perm2[0]);
1259 let permuted_a_b_edge = graph.permute_subgraph(&a_b_edge, &hedge_perm[0]);
1260 let permuted_a_b_edge2 = graph.permute_subgraph(&a_b_edge, &hedge_perm2[0]);
1261 let permuted_c_a_edge = graph.permute_subgraph(&c_a_edge, &hedge_perm[0]);
1262 let permuted_c_a_edge2 = graph.permute_subgraph(&c_a_edge, &hedge_perm2[0]);
1263
1264 assert_eq!(hedge_perm.len(), 1);
1265
1266 println!(
1267 "//a-c\n{}\n//a-b\n{}\n//b-c\n{}",
1268 graph.dot(&c_a_edge),
1269 graph.dot(&a_b_edge),
1270 graph.dot(&b_c_edge)
1271 );
1272 println!(
1273 "//permuted a-b\n{}\n//permuted b-c\n{}\n//permuted c-a\n{}",
1274 graph.dot(&permuted_a_b_edge),
1275 graph.dot(&permuted_b_c_edge),
1276 graph.dot(&permuted_c_a_edge)
1277 );
1278 println!(
1279 "//permuted a-b\n{}\n//permuted b-c\n{}\n//permuted c-a\n{}",
1280 graph.dot(&permuted_a_b_edge2),
1281 graph.dot(&permuted_b_c_edge2),
1282 graph.dot(&permuted_c_a_edge2)
1283 );
1284
1285 assert_eq!(a_b_edge, permuted_b_c_edge);
1286 assert_eq!(b_c_edge, permuted_a_b_edge);
1287 assert_eq!(c_a_edge, permuted_c_a_edge);
1288
1289 }
1296
1297 #[test]
1298 fn test_permute_graph_double_edges() {
1299 let mut triangle = HedgeGraphBuilder::new();
1300
1301 let a = triangle.add_node(());
1302 let b = triangle.add_node(());
1303 let c = triangle.add_node(());
1304
1305 triangle.add_edge(a, b, (), false);
1306
1307 triangle.add_external_edge(a, (), false, Flow::Sink);
1308 triangle.add_edge(b, c, (), false);
1309 triangle.add_external_edge(c, (), false, Flow::Source);
1310 triangle.add_edge(c, a, (), false);
1311 triangle.add_edge(c, a, (), false);
1312 let graph = triangle.build();
1313 let perm = Permutation::from_cycles(&[vec![0, 2], vec![1]]); let a_b_edge = graph.hedges_between(a, b);
1316 let b_c_edge = graph.hedges_between(b, c);
1317 let c_a_edge = graph.hedges_between(c, a);
1318
1319 let hedge_perm = graph.permute_vertices(&perm, &|_| ());
1320 let permuted_b_c_edge = graph.permute_subgraph(&b_c_edge, &hedge_perm[0]);
1321 let permuted_a_b_edge = graph.permute_subgraph(&a_b_edge, &hedge_perm[0]);
1322 let permuted_c_a_edge = graph.permute_subgraph(&c_a_edge, &hedge_perm[0]);
1323
1324 assert_eq!(hedge_perm.len(), 2);
1325 assert_eq!(a_b_edge, permuted_b_c_edge);
1326 assert_eq!(b_c_edge, permuted_a_b_edge);
1327 assert_eq!(c_a_edge, permuted_c_a_edge);
1328
1329 println!(
1330 "//a-c\n{}\n//a-b\n{}\n//b-c\n{}",
1331 graph.dot(&c_a_edge),
1332 graph.dot(&a_b_edge),
1333 graph.dot(&b_c_edge)
1334 );
1335 println!(
1336 "//permuted a-b\n{}\n//permuted b-c\n{}\n//permuted c-a\n{}",
1337 graph.dot(&permuted_a_b_edge),
1338 graph.dot(&permuted_b_c_edge),
1339 graph.dot(&permuted_c_a_edge)
1340 );
1341 }
1343
1344 #[test]
1345 fn test_permute_double_triangle() {
1346 let mut doubletriangle = HedgeGraphBuilder::new();
1347
1348 let a = doubletriangle.add_node(());
1349 let b = doubletriangle.add_node(());
1350 let c = doubletriangle.add_node(());
1351 let d = doubletriangle.add_node(());
1352
1353 doubletriangle.add_edge(a, b, (), false);
1354
1355 doubletriangle.add_edge(b, c, (), false);
1356 doubletriangle.add_edge(c, d, (), false);
1357 doubletriangle.add_edge(d, a, (), false);
1358 doubletriangle.add_edge(c, a, (), false);
1359 let graph = doubletriangle.build();
1360 let perm = Permutation::from_cycles(&[vec![0, 2], vec![3]]); let a_b_edge = graph.hedges_between(a, b);
1363 let b_c_edge = graph.hedges_between(b, c);
1364 let c_a_edge = graph.hedges_between(c, a);
1365
1366 let hedge_perm = graph.permute_vertices(&perm, &|_| ());
1367 let permuted_b_c_edge = graph.permute_subgraph(&b_c_edge, &hedge_perm[0]);
1368 let permuted_a_b_edge = graph.permute_subgraph(&a_b_edge, &hedge_perm[0]);
1369 let permuted_c_a_edge = graph.permute_subgraph(&c_a_edge, &hedge_perm[0]);
1370
1371 assert_eq!(hedge_perm.len(), 1);
1372 assert_eq!(a_b_edge, permuted_b_c_edge);
1373 assert_eq!(b_c_edge, permuted_a_b_edge);
1374 assert_eq!(c_a_edge, permuted_c_a_edge);
1375
1376 println!(
1377 "//a-c\n{}\n//a-b\n{}\n//b-c\n{}",
1378 graph.dot(&c_a_edge),
1379 graph.dot(&a_b_edge),
1380 graph.dot(&b_c_edge)
1381 );
1382 println!(
1383 "//permuted a-b\n{}\n//permuted b-c\n{}\n//permuted c-a\n{}",
1384 graph.dot(&permuted_a_b_edge),
1385 graph.dot(&permuted_b_c_edge),
1386 graph.dot(&permuted_c_a_edge)
1387 );
1388 }
1390
1391 #[test]
1392 fn cyclic_doubled_triangle() {
1393 let mut doubledtriangle = HedgeGraphBuilder::new();
1394
1395 let a = doubledtriangle.add_node(());
1396 let b = doubledtriangle.add_node(());
1397 let c = doubledtriangle.add_node(());
1398
1399 doubledtriangle.add_edge(a, b, (), false);
1400 doubledtriangle.add_edge(a, b, (), false);
1401 doubledtriangle.add_edge(b, c, (), false);
1402 doubledtriangle.add_edge(b, c, (), false);
1403 doubledtriangle.add_edge(c, a, (), false);
1404 doubledtriangle.add_edge(c, a, (), false);
1405 let graph = doubledtriangle.build();
1406 let perm = Permutation::from_cycles(&[vec![0, 1, 2]]); let a_b_edge = graph.hedges_between(a, b);
1409 let b_c_edge = graph.hedges_between(b, c);
1410 let c_a_edge = graph.hedges_between(c, a);
1411
1412 let hedge_perm = graph.permute_vertices(&perm, &|_| ());
1413 let permuted_b_c_edge = graph.permute_subgraph(&b_c_edge, &hedge_perm[0]);
1414 let permuted_a_b_edge = graph.permute_subgraph(&a_b_edge, &hedge_perm[0]);
1415 let permuted_c_a_edge = graph.permute_subgraph(&c_a_edge, &hedge_perm[0]);
1416
1417 assert_eq!(hedge_perm.len(), 8); println!(
1420 "//a-c\n{}\n//a-b\n{}\n//b-c\n{}",
1421 graph.dot(&c_a_edge),
1422 graph.dot(&a_b_edge),
1423 graph.dot(&b_c_edge)
1424 );
1425 println!(
1426 "//permuted a-b\n{}\n//permuted b-c\n{}\n//permuted c-a\n{}",
1427 graph.dot(&permuted_a_b_edge),
1428 graph.dot(&permuted_b_c_edge),
1429 graph.dot(&permuted_c_a_edge)
1430 );
1431 assert_eq!(a_b_edge, permuted_c_a_edge);
1432 assert_eq!(c_a_edge, permuted_b_c_edge);
1433 assert_eq!(b_c_edge, permuted_a_b_edge);
1434 }
1436
1437 #[test]
1438 fn cycle_permutation() {
1439 let mut cycle = HedgeGraphBuilder::new();
1440
1441 let a = cycle.add_node(());
1442 let b = cycle.add_node(());
1443
1444 cycle.add_edge(a, b, (), false);
1445 cycle.add_edge(b, a, (), false);
1446
1447 let graph = cycle.build();
1448 let perm = Permutation::from_cycles(&[vec![0, 1]]); let h = Hedge(0);
1451 let mut h_sub: BitVec = graph.empty_subgraph();
1452 h_sub.set(h.0, true);
1453
1454 let hedge_perm = graph.permute_vertices(&perm, &|_| ());
1455 let permuted_h = graph.permute_subgraph(&h_sub, &hedge_perm[0]);
1456 println!("n perms{}", hedge_perm.len());
1457
1458 println!("//origninal:\n{}", graph.dot(&h_sub));
1459 println!("//permuted:\n{}", graph.dot(&permuted_h));
1460 }
1462
1463 #[test]
1464 fn triple_loop_two_nodes() {
1465 let mut cycle = HedgeGraphBuilder::new();
1466
1467 let a = cycle.add_node(());
1468 let b = cycle.add_node(());
1469
1470 cycle.add_edge(a, b, (), false);
1471 cycle.add_edge(b, a, (), false);
1472 cycle.add_edge(b, a, (), false);
1473
1474 let graph = cycle.build();
1475 let perm = Permutation::from_cycles(&[vec![0, 1]]); let h = Hedge(0);
1478 let mut h_sub: BitVec = graph.empty_subgraph();
1479 h_sub.set(h.0, true);
1480
1481 let hedge_perm = graph.permute_vertices(&perm, &|_| ());
1482 let permuted_h = graph.permute_subgraph(&h_sub, &hedge_perm[0]);
1483 println!("n perms{}", hedge_perm.len());
1484
1485 println!("//origninal:\n{}", graph.dot(&h_sub));
1486 println!("//permuted:\n{}", graph.dot(&permuted_h));
1487 }
1489
1490 #[test]
1491 fn generate_all() {
1492 fn generator_pair(n: usize) -> [Permutation; 2] {
1493 let mut map = Vec::new();
1494 for i in 0..n {
1495 map.push((i + 1) % n)
1496 }
1497 [
1498 Permutation::from_map(map),
1499 Permutation::from_cycles(&[vec![0, n - 1]]),
1500 ]
1501 }
1502
1503 let all_2 = Permutation::generate_all(&generator_pair(2)).unwrap();
1504
1505 let all_3 = Permutation::generate_all(&generator_pair(3)).unwrap();
1506 let all_4 = Permutation::generate_all(&generator_pair(4)).unwrap();
1507 assert_eq!(all_2.len(), 2);
1508 assert_eq!(all_3.len(), 6);
1509 assert_eq!(all_4.len(), 24);
1510 }
1511}