public static bool IsInjective <T, U>(FiniteSet <T> domain, FiniteSet <U> codomain, Func <T, U> map) where T : IEquatable <T> where U : IEquatable <U> { if (domain.Size > codomain.Size) { return(false); } HashSet <U> range = new HashSet <U>(); foreach (T x in domain) { U y = map(x); if (range.Contains(y)) { return(false); } range.Add(y); } return(true); }
private static IEnumerable <Cycle <T> > OneCycleGenerator(FiniteSet <T> set) { foreach (T element in set) { yield return(new Cycle <T>(element)); } }
private Group <T> Subgroup(FiniteSet <T> subset, bool test) { if (test && !IsSubgroup(this, subset)) { return(null); } return(new Group <T>(subset, _product, _inverse, _identity)); }
public bool Equals(FiniteSet <T> other) { if (other == null) { return(false); } return(this.IsEqualTo(other)); }
internal Coset(Group <T> group, Group <T> subgroup, Dictionary <T, Coset <T> > cosets, FiniteSet <T> members, T representative) { _group = group; _subgroup = subgroup; _cosets = cosets; _members = members; _representative = representative; _hashCode = _members.GetHashCode(); }
public Group <Permutation <U> > ActionGroup <U>(Func <T, U, U> action, FiniteSet <U> set) where U : IEquatable <U> { return(new Group <Permutation <U> >( new FiniteSet <Permutation <U> >(_set.Select(g => Permutation <U> .FromFunction(set, x => action(g, x)))), Permutation <U> .Product, Permutation <U> .Inverse, Permutation <U> .Identity(set) )); }
/// <summary> /// Returns the semidirect product N x_f H. /// </summary> public static Group <Pair <T, U> > SemidirectProduct <T, U>(Group <T> n, Group <U> h, Func <U, T, T> f) where T : IEquatable <T> where U : IEquatable <U> { return(new Group <Pair <T, U> >( FiniteSet.CartesianProduct(n.Set, h.Set), (g1, g2) => new Pair <T, U>(n.Product(g1.First, f(g1.Second, g2.First)), h.Product(g1.Second, g2.Second)), g => { U inverse = h.Inverse(g.Second); return new Pair <T, U>(f(inverse, n.Inverse(g.First)), inverse); }, new Pair <T, U>(n.Identity, h.Identity) )); }
/// <summary> /// Returns the direct product G_1 x G_2. /// </summary> public static Group <Pair <T, U> > DirectProduct <T, U>(Group <T> group1, Group <U> group2) where T : IEquatable <T> where U : IEquatable <U> { return(new Group <Pair <T, U> >( FiniteSet.CartesianProduct(group1.Set, group2.Set), (g1, g2) => new Pair <T, U>(group1.Product(g1.First, g2.First), group2.Product(g1.Second, g2.Second)), g => new Pair <T, U>(group1.Inverse(g.First), group2.Inverse(g.Second)), new Pair <T, U>(group1.Identity, group2.Identity) )); }
public static bool IsBijective <T, U>(FiniteSet <T> domain, FiniteSet <U> codomain, Func <T, U> map) where T : IEquatable <T> where U : IEquatable <U> { if (domain.Size != codomain.Size) { return(false); } return(IsSurjective(domain, codomain, map)); }
public bool IsEqualTo(FiniteSet <T> other) { if (other is FiniteSet <T> ) { return(_set.SetEquals(((FiniteSet <T>)other)._set)); } else { return(this.IsSubsetOf(other) && other.IsSubsetOf(this)); } }
public static Func <U, T> Inverse <T, U>(FiniteSet <T> domain, Func <T, U> bijection) where T : IEquatable <T> { Dictionary <U, T> inverseMap = new Dictionary <U, T>(); foreach (T element in domain) { inverseMap.Add(bijection(element), element); } return(u => inverseMap[u]); }
public static FiniteSet <Pair <T, U> > CartesianProduct <T, U>(FiniteSet <T> st, FiniteSet <U> su) where T : IEquatable <T> where U : IEquatable <U> { HashSet <Pair <T, U> > set = new HashSet <Pair <T, U> >(); foreach (T t in st) { foreach (U u in su) { set.Add(new Pair <T, U>(t, u)); } } return(new FiniteSet <Pair <T, U> >(set)); }
public Group(FiniteSet <T> set, Func <T, T, T> product, Func <T, T> inverse) { _set = set; _product = product; _identity = this.FindIdentity(); if (inverse != null) { _inverse = inverse; } else { _inverse = this.DefaultInverse; } }
/// <summary> /// Returns a permutation group on {1,2,...,|G|} isomorphic to this group G. /// </summary> /// <param name="bijection">A bijection from G to {1,2,...,|G|}.</param> /// <param name="bijectionInverse">The inverse of <paramref name="bijection"/>.</param> /// <param name="isomorphism">An isomorphism from G to the permutation group.</param> public Group <Permutation <int> > ToPermutationGroup(Func <T, int> bijection, Func <int, T> bijectionInverse, out Func <T, Permutation <int> > isomorphism) { if (bijectionInverse == null) { bijectionInverse = Discrete.Inverse(_set, bijection); } var set = new FiniteSet <int>(Enumerable.Range(1, _set.Size)); isomorphism = x => Permutation <int> .FromFunction(set, k => bijection(_product(x, bijectionInverse(k)))); var permutations = new FiniteSet <Permutation <int> >(_set.Select(isomorphism)); return(new Group <Permutation <int> >(permutations, Permutation <int> .Product, Permutation <int> .Inverse, Permutation <int> .Identity(set))); }
public IEnumerable <FiniteSet <T> > Partition(Func <T, FiniteSet <T> > equivalenceClass) { HashSet <T> remaining = new HashSet <T>(_set); while (remaining.Count != 0) { FiniteSet <T> c = equivalenceClass(remaining.First()); foreach (T element in c) { remaining.Remove(element); } yield return(c); } }
/// <summary> /// Returns the cyclic group on the vertices {1,2,...,n} of an n-gon. /// </summary> public static Group <Permutation <int> > CyclicGroupP(int n) { FiniteSet <int> set = new FiniteSet <int>(Enumerable.Range(1, n)); HashSet <Permutation <int> > permutations = new HashSet <Permutation <int> >(); Permutation <int> generator = Permutation <int> .FromCycle(set, new Cycle <int>(Enumerable.Range(1, n))); Permutation <int> current = Permutation <int> .Identity(set); for (int i = 0; i < n; i++) { permutations.Add(current); current = Permutation <int> .Product(current, generator); } return(new Group <Permutation <int> >(new FiniteSet <Permutation <int> >(permutations), Permutation <int> .Product, Permutation <int> .Inverse, Permutation <int> .Identity(set))); }
public static bool IsNormal(Group <T> group, FiniteSet <T> subset) { foreach (T g in group.Set) { T inverse = group.Inverse(g); foreach (T n in subset) { if (!subset.IsMember(group.Product(group.Product(g, n), inverse))) { return(false); } } } return(true); }
public static bool IsSurjective <T, U>(FiniteSet <T> domain, FiniteSet <U> codomain, Func <T, U> map) where T : IEquatable <T> where U : IEquatable <U> { if (domain.Size < codomain.Size) { return(false); } HashSet <U> range = new HashSet <U>(); foreach (T element in domain) { range.Add(map(element)); } return(range.Count == codomain.Size); }
public bool IsSubsetOf(FiniteSet <T> superset) { if (superset is FiniteSet <T> ) { return(_set.IsSubsetOf(((FiniteSet <T>)superset)._set)); } else { foreach (T element in _set) { if (!superset.IsMember(element)) { return(false); } } return(true); } }
private static Permutation <int> NGonReflection(FiniteSet <int> set) { List <Cycle <int> > cycles = new List <Cycle <int> >(); int n = set.Size; int k = 1; if (n % 2 != 0) { cycles.Add(new Cycle <int>(k)); k++; n++; } while (k <= n / 2) { cycles.Add(new Cycle <int>(new int[] { k, n - k + 1 })); k++; } return(Permutation <int> .FromDisjointCycles(set, cycles)); }
public static bool IsSubgroup(Group <T> group, FiniteSet <T> subset) { if (!subset.IsSubsetOf(group.Set)) { return(false); } foreach (T a in subset) { foreach (T b in subset) { T inverse = group.Inverse(b); if (!subset.IsMember(group.Product(a, inverse))) { return(false); } } } return(true); }
private Permutation(FiniteSet <T> set, IEnumerable <Cycle <T> > cycles) { _set = set; _cycles = new HashSet <Cycle <T> >(); HashSet <T> seen = new HashSet <T>(); int totalLength = 0; int oddCycles = 0; foreach (Cycle <T> cycle in cycles) { totalLength += cycle.Length; _cycles.Add(cycle); seen.UnionWith(cycle); if (cycle.Sign == -1) { oddCycles++; } } _sign = ((oddCycles + 1) % 2) * 2 - 1; foreach (T element in set) { if (!seen.Contains(element)) { totalLength++; _cycles.Add(new Cycle <T>(element)); } } if (totalLength != set.Size) { throw new ArgumentException("Cycles are not disjoint."); } }
public static Permutation <T> FromFunction(FiniteSet <T> set, Func <T, T> bijection) { HashSet <T> seen = new HashSet <T>(); List <Cycle <T> > cycles = new List <Cycle <T> >(); List <T> currentCycle = new List <T>(); foreach (T element in set) { if (!seen.Contains(element)) { T x = element; T y; currentCycle.Add(x); while (true) { y = bijection(x); if (currentCycle.Count != 0 && currentCycle[0].Equals(y)) { break; } currentCycle.Add(y); x = y; } seen.UnionWith(currentCycle); cycles.Add(new Cycle <T>(currentCycle)); currentCycle.Clear(); } } return(new Permutation <T>(set, cycles)); }
public static IEnumerable <Permutation <T> > SetPermutations(FiniteSet <T> set) { int n = set.Size; Dictionary <int, T> map = new Dictionary <int, T>(); Dictionary <T, int> inverseMap = new Dictionary <T, int>(); int[] permutation = new int[n]; int index = 0; foreach (T element in set) { map.Add(index, element); inverseMap.Add(element, index); permutation[index] = index; index++; } yield return(Identity(set)); // Generate permutations in lexicographic order. while (true) { int k; bool foundK = false; int l; int temp; for (k = n - 2; k >= 0; k--) { if (permutation[k] < permutation[k + 1]) { foundK = true; break; } } if (!foundK) { break; } for (l = n - 1; l >= 0; l--) { if (permutation[k] < permutation[l]) { break; } } temp = permutation[k]; permutation[k] = permutation[l]; permutation[l] = temp; for (int i = 0; i < (n - (k + 1)) / 2; i++) { temp = permutation[k + 1 + i]; permutation[k + 1 + i] = permutation[n - i - 1]; permutation[n - i - 1] = temp; } yield return(Permutation <T> .FromFunction(set, x => map[permutation[inverseMap[x]]])); } }
public static Permutation <T> Identity(FiniteSet <T> set) { return(FromDisjointCycles(set, OneCycleGenerator(set))); }
public static Permutation <T> FromPermutation <U>(FiniteSet <T> set, Permutation <U> permutation, Func <U, T> bijection) where U : IEquatable <U> { return(new Permutation <T>(set, permutation.Select(cycle => new Cycle <T>(cycle.Select(u => bijection(u)))))); }
public static Permutation <T> FromMappings(FiniteSet <T> set, IDictionary <T, T> mappings) { return(FromFunction(set, x => mappings[x])); }
public static Permutation <T> FromDisjointCycles(FiniteSet <T> set, IEnumerable <Cycle <T> > cycles) { return(new Permutation <T>(set, cycles)); }
public static Permutation <T> FromCycle(FiniteSet <T> set, Cycle <T> cycle) { return(new Permutation <T>(set, new Cycle <T>[] { cycle })); }
/// <summary> /// Returns the alternating group Alt(S) of order |S|!/2. /// </summary> public static Group <Permutation <T> > AlternatingGroup <T>(FiniteSet <T> set) where T : IEquatable <T> { FiniteSet <Permutation <T> > permutations = new FiniteSet <Permutation <T> >(Permutation <T> .SetPermutations(set).Where(a => a.Sign == 1)); return(new Group <Permutation <T> >(permutations, Permutation <T> .Product, Permutation <T> .Inverse, Permutation <T> .Identity(set))); }