def transitive(self, other=None): r""" TBD """ if other is None: raise ValueError, "Enter a reduction map as a parameter" elif self.get_B() != other.get_A(): raise ValueError, "These are not good candidate sets for reduction mapping" else: dic_h = dict() dic_h0 = dict() A = self.get_A() B = self.get_B() C = other.get_B() f = self.get_SRWP() f0 = self.get_SPWP() g = other.get_SRWP() g0 = other.get_SPWP() for elm in A: if elm in fixed_points(f): if f0(elm) in fixed_points(g): dic_h0[elm] = g0(f0(elm)) dic_h[elm] = elm else: dic_h[elm] = inverse(f0)(g(f0(elm))) else: dic_h[elm] = f(elm) h = FiniteSetMaps(A, A).from_dict(dic_h) h0 = FiniteSetMaps(CombinatorialScalarWrapper(dic_h0.keys()), C).from_dict(dic_h0) return ReductionMaps(A, C, h, h0)
def reduction_matrix_IAB_AB(mat,st = "remove left Identity matrix"): r""" Input IAB and output is AB, that is, we remove the left Combinatorial Object 1 from each triple and return only the other two entries. """ if mat.nrows()!=mat.ncols(): raise ValueError, "Check dimensions" else: dim = mat.nrows() d = dict() for i in range(dim): for j in range(dim): dic_f0 = dict() dic_f = dict() newset = set() for elm in mat[i,j]: newelm1 = elm.get_object()[1] newelm2 = elm.get_object()[2] tmp = newelm1*newelm2 newset.add(tmp) dic_f[elm] = elm dic_f0[elm] = tmp f = FiniteSetMaps(mat[i,j],mat[i,j]).from_dict(dic_f) f0 = FiniteSetMaps(mat[i,j],newset).from_dict(dic_f0) d[i,j] = ReductionMaps(mat[i,j],CombinatorialScalarWrapper(newset),f,f0) return ReductionMapsDict(d,st)
def reduction_matrix_ABCD_to_ApBCpD(A,B,C,D,st = None): r""" returns the reduction/equivalence of the product of ABCD to A(BC)D. """ mat = matrix_multiply(A,matrix_multiply(matrix_multiply(B,C),D)) dim = mat.nrows() d = dict() for i in range(dim): for j in range(dim): newsetA = set() newsetB = set() dic_f = dict() dic_f0 = dict() for elm in mat[i,j]: tmp0 = elm.get_object()[0] tmp1 = elm.get_object()[1].get_object()[0] tmp2 = elm.get_object()[1].get_object()[1] tmpB = CombinatorialObject((tmp0,tmp1,tmp2),elm.get_sign(),elm.get_weight()) newsetB.add(tmpB) tmp10 = tmp1.get_object()[0] tmp11 = tmp1.get_object()[1] tmpA = CombinatorialObject((tmp0,tmp10,tmp11,tmp2),elm.get_sign(),elm.get_weight()) newsetA.add(tmpA) dic_f[tmpA] = tmpA dic_f0[tmpA] = tmpB f = FiniteSetMaps(newsetA,newsetA).from_dict(dic_f) f0 = FiniteSetMaps(newsetA,newsetB).from_dict(dic_f0) d[i,j] = ReductionMaps(CombinatorialScalarWrapper(newsetA),CombinatorialScalarWrapper(newsetB),f,f0) return ReductionMapsDict(d,st)
def __init__(self, automaton, alphabet, category, side): """ sage: automaton = DiGraph( [ (1, 1, "b"), (1, 2, "a"), ... (2, 2, "a"), (2, 2, "c"), (2, 3, "b"), ... (3, 2, "a"), (3, 3, "b"), (3, 3, "c") ] ) sage: from sage.monoids.transition_monoid import TransitionMonoidOfDeterministicAutomaton sage: M = TransitionMonoidOfDeterministicAutomaton(automaton) sage: M.cardinality() 7 sage: M.list() [[], ['a'], ['b'], ['c'], ['a', 'b'], ['b', 'c'], ['c', 'a']] sage: TestSuite(M).run() Since ``automaton`` is mutable, we made a private copy of it:: sage: M.automaton() == automaton True sage: M.automaton() is automaton False """ # Should check that automaton is deterministic self._automaton = automaton # We would want to have FiniteSetPartialMaps ambient = FiniteSetMaps( list(automaton.vertices())+[None], action=side) def generator(a): return ambient( functools.partial(automaton.transition, a = a) ) generators = Family( alphabet, generator ) AutomaticMonoid.__init__(self, generators, ambient, ambient.one(), operator.mul, category)
def reduction_matrix_ABCD_to_pABpCD(A,B,C,D,st = None,reduction = None): r""" returns the reduction/equivalence of the product of ABCD to (AB)CD. """ if reduction == None: mat = matrix_multiply(matrix_multiply(matrix_multiply(A,B),C),D) else: #not used... yet mat = reduction.get_matrix_A() d = dict() dim = mat.nrows() for i in range(dim): for j in range(dim): newsetA = set() newsetB = set() dic_f = dict() dic_f0 = dict() for elm in mat[i,j]: tmp0 = elm.get_object()[0].get_object()[0] tmp01 = tmp0.get_object()[0] tmp02 = tmp0.get_object()[1] tmp1 = elm.get_object()[0].get_object()[1] tmp2 = elm.get_object()[1] tmpB = CombinatorialObject((tmp0,tmp1,tmp2),elm.get_sign(),elm.get_weight()) newsetB.add(tmpB) tmpA = CombinatorialObject((tmp01,tmp02,tmp1,tmp2),elm.get_sign(),elm.get_weight()) newsetA.add(tmpA) dic_f[tmpA] = tmpA dic_f0[tmpA] = tmpB f = FiniteSetMaps(newsetA,newsetA).from_dict(dic_f) f0 = FiniteSetMaps(newsetA,newsetB).from_dict(dic_f0) d[i,j] = ReductionMaps(CombinatorialScalarWrapper(newsetA),CombinatorialScalarWrapper(newsetB),f,f0) return ReductionMapsDict(d,st)
def __init__(self, n=3, action="left"): r""" EXAMPLES:: sage: from sage_semigroups.categories.examples.finite_h_trivial_monoids import MonoidOfOrderPreservingMaps sage: p = MonoidOfOrderPreservingMaps(4) sage: TestSuite(p).run() """ assert n in NN domain = IntegerRange(Integer(1), Integer(n + 1)) index_set = IntegerRange(Integer(1), Integer(n)) ambient_monoid = FiniteSetMaps(domain, action=action) def pi(i): return ambient_monoid.from_dict( dict([(k, k) for k in domain if k != i + 1] + [(i + 1, i)])) def opi(i): return ambient_monoid.from_dict( dict([(k, k) for k in domain if k != i] + [(i, i + 1)])) piopi = Family( dict([[i, pi(i)] for i in index_set] + [[-i, opi(i)] for i in index_set])) AutomaticMonoid.__init__( self, piopi, ambient_monoid, one=ambient_monoid.one(), mul=operator.mul, category=Monoids().HTrivial().Finite().FinitelyGenerated() & Monoids().Transformation().Subobjects())
def restrict_map_fixed(func): r""" Returns the same map whose domain is restricted to its fixed points. """ fxd = fixed_points(func) M = FiniteSetMaps(fxd) d = dict() for i in fxd: d[i] = func(i) return M.from_dict(d)
def HeckeMonoid(W): r""" Return the `0`-Hecke monoid of the Coxeter group `W`. INPUT: - `W` -- a finite Coxeter group Let `s_1,\ldots,s_n` be the simple reflections of `W`. The 0-Hecke monoid is the monoid generated by projections `\pi_1,\ldots,\pi_n` satisfying the same braid and commutation relations as the `s_i`. It is of same cardinality as `W`. .. NOTE:: This is currently a very basic implementation as the submonoid of sorting maps on `W` generated by the simple projections of `W`. It's only functional for `W` finite. .. SEEALSO:: - :class:`CoxeterGroups` - :class:`CoxeterGroups.ParentMethods.simple_projections` - :class:`IwahoriHeckeAlgebra` EXAMPLES:: sage: from sage.monoids.hecke_monoid import HeckeMonoid sage: W = SymmetricGroup(4) sage: H = HeckeMonoid(W); H 0-Hecke monoid of the Symmetric group of order 4! as a permutation group sage: pi = H.monoid_generators(); pi Finite family {1: ..., 2: ..., 3: ...} sage: all(pi[i]^2 == pi[i] for i in pi.keys()) True sage: pi[1] * pi[2] * pi[1] == pi[2] * pi[1] * pi[2] True sage: pi[2] * pi[3] * pi[2] == pi[3] * pi[2] * pi[3] True sage: pi[1] * pi[3] == pi[3] * pi[1] True sage: H.cardinality() 24 """ ambient_monoid = FiniteSetMaps(W, action="right") pi = W.simple_projections(length_increasing=True).map(ambient_monoid) H = ambient_monoid.submonoid(pi) H.rename("0-Hecke monoid of the %s" % W) return H
def HeckeMonoid(W): r""" Return the `0`-Hecke monoid of the Coxeter group `W`. INPUT: - `W` -- a finite Coxeter group Let `s_1,\ldots,s_n` be the simple reflections of `W`. The 0-Hecke monoid is the monoid generated by projections `\pi_1,\ldots,\pi_n` satisfying the same braid and commutation relations as the `s_i`. It is of same cardinality as `W`. .. NOTE:: This is currently a very basic implementation as the submonoid of sorting maps on `W` generated by the simple projections of `W`. It's only functional for `W` finite. .. SEEALSO:: - :class:`CoxeterGroups` - :class:`CoxeterGroups.ParentMethods.simple_projections` - :class:`IwahoriHeckeAlgebra` EXAMPLES:: sage: from sage.monoids.hecke_monoid import HeckeMonoid sage: W = SymmetricGroup(4) sage: H = HeckeMonoid(W); H 0-Hecke monoid of the Symmetric group of order 4! as a permutation group sage: pi = H.monoid_generators(); pi Finite family {1: ..., 2: ..., 3: ...} sage: all(pi[i]^2 == pi[i] for i in pi.keys()) True sage: pi[1] * pi[2] * pi[1] == pi[2] * pi[1] * pi[2] True sage: pi[2] * pi[3] * pi[2] == pi[3] * pi[2] * pi[3] True sage: pi[1] * pi[3] == pi[3] * pi[1] True sage: H.cardinality() 24 """ ambient_monoid = FiniteSetMaps(W, action="right") pi = W.simple_projections(length_increasing=True).map(ambient_monoid) H = ambient_monoid.submonoid(pi) H.rename("0-Hecke monoid of the %s"%W) return H
def reduction_lemma_40(mat, st = "lemma 40"): r""" Returns the reduction of mat = adj_A times A to det_A times I. """ dim = mat.nrows() d = dict() B = matrix_adjoint_lemma_40(mat) A = mat for i in range(dim): for j in range(dim): dic_f = dict() dic_f0 = dict() copyset = deepcopy(A[i,j].get_set()) if i==j: for elm in copyset: tmp = list(elm.get_object()[0].get_object()) #object is tuple, elements come from the actual tuple, hence double get_object() index = tmp.index(CombinatorialObject('_',1)) tmp[index]=elm.get_object()[1] dic_f[elm] = elm copyelm= deepcopy(elm) dic_f0[elm] = copyelm.set_object(tuple(tmp)) f0 = FiniteSetMaps(A[i,j],B[i,j]).from_dict(dic_f0) else: for elm in copyset: tmp = list(elm.get_object()[0].get_object()) #object is tuple, elements come from the actual tuple, hence double get_object() p = tmp[0].get_object() ii = i+1 jj = j+1 q = Permutation((ii,jj)) pq = q*p #p composed with q tmp[0] = CombinatorialObject(pq,pq.signature()) elm_range2 = tmp[jj] tmp[jj] = elm.get_object()[1] sgn = 1 weight = 1 for flop in tmp: sgn *= flop.get_sign() weight *= flop.get_weight() elm_range1 = CombinatorialObject(tuple(tmp),sgn,weight) elm_range = CombinatorialObject((elm_range1,elm_range2),elm_range1.get_sign()*elm_range2.get_sign(),elm_range1.get_weight()*elm_range2.get_weight()) dic_f[elm] = elm_range f0 = FiniteSetMaps(set(),set()).from_dict({}) f = FiniteSetMaps(A[i,j],A[i,j]).from_dict(dic_f) d[i,j] = ReductionMaps(A[i,j],B[i,j],f,f0) return ReductionMapsDict(d,st)
def __init__(self, n): ambient_monoid = FiniteSetMaps(range(-n, 0) + range(1, n + 1), action="right") pi = Family( range(1, n), lambda j: ambient_monoid.from_dict( dict([(i, i) for i in range(1, n + 1) if i != j + 1] + [( j + 1, j)] + [(i, i) for i in range(-n, 0) if i != -j] + [(-j, -j - 1)]))) category = Monoids().JTrivial().Finite() & Monoids().Transformation( ).Subobjects() AutomaticMonoid.__init__(self, pi, ambient_monoid, one=ambient_monoid.one(), mul=operator.mul, category=category)
def reduction_matrix_clean_up(mat, st="standard clean up"): dim = mat.nrows() d = dict() B = matrix_clean_up(mat) A = mat for i in range(dim): for j in range(dim): dic_f = dict() dic_f0 = dict() for elm in A[i,j]: dic_f[elm] = elm dic_f0[elm] = elm.get_cleaned_up_version() f = FiniteSetMaps(A[i,j],A[i,j]).from_dict(dic_f) f0 = FiniteSetMaps(A[i,j],B[i,j]).from_dict(dic_f0) d[i,j] = ReductionMaps(A[i,j],B[i,j],f,f0) return ReductionMapsDict(d,st)
def __init__(self, W): self.lattice = W.domain() self.W = W from sage.sets.finite_set_maps import FiniteSetMaps ambient_monoid = FiniteSetMaps(self.W, action="right") pi = self.W.simple_projections( length_increasing=True).map(ambient_monoid) category = Monoids().JTrivial().Finite() & Monoids().Transformation( ).Subobjects() AutomaticMonoid.__init__(self, pi, ambient_monoid, one=ambient_monoid.one(), mul=operator.mul, category=category) self.domain = self.W self.codomain = self.W
def __init__(self, n, action="right"): ambient_monoid = FiniteSetMaps(range(1, n + 1), action=action) def pii(i): return ambient_monoid.from_dict( {j: j - 1 if j == i + 1 else j for j in range(1, n + 1)}) pi = Family(range(1, n), pii) category = Monoids().JTrivial().Finite() & Monoids().Transformation( ).Subobjects() AutomaticMonoid.__init__(self, pi, ambient_monoid, one=ambient_monoid.one(), mul=operator.mul, category=category)
def confluence(self, other=None): r""" Returns the reduction of C to B, where the usage is: r1.confluence(r2), and r1 maps A to B, B fully cancelled, and r2 maps A to C. """ if other is None: raise ValueError, "Enter a redution map as a parameter" elif self.get_A() != other.get_A(): raise ValueError, """ "A" """ " sets have to match" elif not (self.get_B().is_fully_cancelled()): raise ValueError, """ "B" """ " on the left is not fully cancelled" else: dic_h = dict() dic_h0 = dict() A = self.get_A() B = self.get_B() C = other.get_B() f = self.get_SRWP() f0 = self.get_SPWP() g = other.get_SRWP() g0 = other.get_SPWP() fxd_f = fixed_points(self.get_SRWP()) fxd_g = fixed_points(other.get_SRWP()) for c in C: x = inverse(g0)(c) while True: if x in fxd_f: #a fixed point of h dic_h[c] = c dic_h0[c] = f0(x) break else: x = f(x) if x in fxd_g: #not a fixed point of h dic_h[c] = g0(x) break else: x = g(x) h = FiniteSetMaps(C, C).from_dict(dic_h) h0 = FiniteSetMaps(CombinatorialScalarWrapper(dic_h0.keys()), B).from_dict(dic_h0) return ReductionMaps(C, B, h, h0)
def reduction_identity(mat,involution_dict, st = None): r""" When a matrix reduces to the identity, this returns a ReductionMapDict of from a matrix to I. """ dim = mat.nrows() fs = involution_dict f0s = dict() I = identity_matrix(dim) for i in range(dim): for j in range(dim): if i==j: f0s[i,j] = FiniteSetMaps(mat[i,j],I[i,j]).from_dict({mat[i,j].get_set().pop():CombinatorialObject(1,1)}) else: f0s[i,j] = FiniteSetMaps(set(),set()).from_dict({}) d = dict() for i in range(dim): for j in range(dim): d[i,j] = ReductionMaps(mat[i,j],I[i,j],fs[i,j],f0s[i,j]) return ReductionMapsDict(d,st)
def _involution_dict(mat): r""" Returns a dictionary of arbitrary involutions on the entries of a Combinatorial Matrix. Note all weights must be 1 for this. It may be extended upon in the future. """ mat_gen_func = matrix_generating_function(mat) if mat_gen_func != mat_gen_func.parent().identity_matrix(): raise ValueError, "Input needs to be equal to the identity." else: func = dict() for x in range(mat.nrows()): for y in range(mat.ncols()): if x <> y: func[(x,y)] = mat[x,y].create_involution() else: t = mat[x,y] for i in t: _M = FiniteSetMaps(t,t) func[(x,y)] = _M.from_dict({i:i}) return func
def reverse(self): if self.get_A().get_size() != self.get_B().get_size(): raise ValueError, "Reduction direction cannot be reversed unless scalars are equivalent" else: A = self.get_B() B = self.get_A() f0 = inverse(self.get_SPWP()) dic_f = dict() for elm in A: dic_f[elm] = elm f = FiniteSetMaps(A, A).from_dict(dic_f) return ReductionMaps(A, B, f, f0)
def __init__(self, poset): self.poset = poset support = poset.list() ambient_monoid = FiniteSetMaps(support, action="right") def genij(ij): (i, j) = ij return ambient_monoid.from_dict( {k: i if k == j else k for k in support}) index = map(tuple, poset.cover_relations()) # index elems must be hashable self.pi = Family(index, genij) category = Monoids().JTrivial().Finite() & Monoids().Transformation( ).Subobjects() AutomaticMonoid.__init__(self, self.pi, ambient_monoid, one=ambient_monoid.one(), mul=operator.mul, category=category)
def reduction_identity_matrix(mat,st=None,involution_dict=None): r""" When a matrix reduces to the identity, this returns a ReductionMapDict of from a matrix to I. """ dim = mat.nrows() if involution_dict is None: fs = _involution_dict(mat) else: fs = involution_dict f0s = dict() I = identity_matrix(dim) for i in range(dim): for j in range(dim): if i==j: tmp = CombinatorialScalarWrapper(set(fixed_points(fs[i,j]))) f0s[i,j] = FiniteSetMaps(tmp,I[i,j]).from_dict({tmp.get_set().pop():CombinatorialObject(1,1)}) else: f0s[i,j] = FiniteSetMaps(set(),set()).from_dict({}) d = dict() for i in range(dim): for j in range(dim): d[i,j] = ReductionMaps(mat[i,j],I[i,j],fs[i,j],f0s[i,j]) return ReductionMapsDict(d,st)
def __init__(self, n = 3, action="left"): r""" EXAMPLES:: sage: from sage_semigroups.categories.examples.finite_h_trivial_monoids import MonoidOfOrderPreservingMaps sage: p = MonoidOfOrderPreservingMaps(4) sage: TestSuite(p).run() """ assert n in NN domain = IntegerRange(Integer(1),Integer(n+1)) index_set = IntegerRange(Integer(1),Integer(n)) ambient_monoid = FiniteSetMaps(domain, action=action) def pi(i): return ambient_monoid.from_dict(dict([(k, k) for k in domain if k != i+1]+[(i+1,i)])) def opi(i): return ambient_monoid.from_dict(dict([(k, k) for k in domain if k != i ]+[(i,i+1)])) piopi = Family(dict([ [ i, pi(i) ] for i in index_set] + [ [-i, opi(i) ] for i in index_set])) AutomaticMonoid.__init__(self, piopi, ambient_monoid, one=ambient_monoid.one(), mul=operator.mul, category=Monoids().HTrivial().Finite().FinitelyGenerated() & Monoids().Transformation().Subobjects() )
def reduction_lemma_28_68(mat, red_adjAA_to_I, st = "an application of lemma 28, reduction_68"): r""" Because only one matrix here has a nontrivial SRWP map, we need not apply the formal indexing given in the proof of lemma 28. Simply enter a matrix (adj_AA)BA and the reduction of adj_AA to I. """ d = dict() dim = mat.nrows() for i in range(dim): for j in range(dim): dic_f = dict() dic_f0 = dict() newset = set() for elm in mat[i,j]: #break tuple apart tmp0 = elm.get_object()[0] tmp1 = elm.get_object()[1] tmp2 = elm.get_object()[2] row = tmp0.get_row() col = tmp0.get_col() f_row_col = red_adjAA_to_I[row,col].get_SRWP() f0_row_col = red_adjAA_to_I[row,col].get_SPWP() #assign map tmp = f_row_col(tmp0) sign = tmp.get_sign()*tmp1.get_sign()*tmp2.get_sign() weight = tmp.get_weight()*tmp1.get_weight()*tmp2.get_weight() dic_f[elm] = CombinatorialObject((tmp,tmp1,tmp2),sign,weight) if tmp in fixed_points(f_row_col): tmpfxd = CombinatorialObject((f0_row_col(tmp0),tmp1,tmp2),elm.get_sign(),elm.get_weight()) dic_f0[elm] = tmpfxd newset.add(tmpfxd) f = FiniteSetMaps(mat[i,j],mat[i,j]).from_dict(dic_f) f0 = FiniteSetMaps(dic_f0.keys(),newset).from_dict(dic_f0) d[i,j] = ReductionMaps(mat[i,j],CombinatorialScalarWrapper(newset),f,f0) return ReductionMapsDict(d,st)
def example(self): """ EXAMPLES:: sage: M = Semigroups().SetsWithAction().example() sage: TestSuite(M).run(skip = ["_test_pickling"]) """ from sage.monoids.representations import SetWithAction from sage.rings.finite_rings.integer_mod_ring import IntegerModRing from sage.sets.finite_set_maps import FiniteSetMaps from sage.combinat.automatic_monoid import AutomaticMonoid from sage.sets.family import Family from sage.combinat.j_trivial_monoids import SubFiniteMonoidsOfFunctions Z = IntegerModRing(10) ambient = FiniteSetMaps(Z) S = AutomaticMonoid(Family({2: ambient(lambda x: 2*x), 3: ambient(lambda x: 3*x) }), category=SubFiniteMonoidsOfFunctions()) M = SetWithAction(S, Z, action = lambda f,m: f(m)) M.rename("Representation of the monoid generated by <2,3> acting on Z/10 Z by multiplication") return M
def inverse(func): dic = func.fibers() for i in func.codomain(): dic[i] = set(dic[i]).pop() return FiniteSetMaps(func.codomain(),func.domain()).from_dict(dic)
def __iter__(self): for f in FiniteSetMaps(self._n): yield Endofunction(f)