def __init__(self, Sym, k, t='t'): r""" The class modeling the abstract vector space of `k`-Schur functions; if `t=1` this is actually an abstract ring. Another way to describe this space is as the subspace of a ring of symmetric functions generated by the complete homogeneous symmetric functions `h_i` for `1\le i \le k`. TESTS:: sage: Sym = SymmetricFunctions(QQ) sage: from sage.combinat.sf.new_kschur import KBoundedSubspace sage: L3 = KBoundedSubspace(Sym,3,1) sage: TestSuite(L3).run(skip=["_test_not_implemented_methods"]) sage: Sym.kBoundedSubspace(0,1) Traceback (most recent call last): ... ValueError: k must be a positive integer sage: Sym = SymmetricFunctions(QQ['t']) sage: TestSuite(Sym.kBoundedSubspace(1)).run(skip=["_test_not_implemented_methods"]) """ if not isinstance(k, (int, Integer)) or (k < 1): raise ValueError, "k must be a positive integer" if not isinstance(Sym,SymmetricFunctions): raise ValueError, "Sym must be an algebra of symmetric functions" self.indices = ConstantFunction(Partitions_all_bounded(k)) R = Sym.base_ring() # The following line is a work around for the fact that Parent defines # self.base_ring as NotImplemented, hence it cannot be defined by the # category framework. self.base_ring = ConstantFunction(R) self.ambient = ConstantFunction(Sym) self.k = k self.t = R(t) category = GradedHopfAlgebras(R) if t == 1 else GradedCoalgebras(R) Parent.__init__(self, category = category.Subobjects().WithRealizations()) ks = self.kschur() # Coercions if t == 1: s = ks.ambient() kh = self.khomogeneous(); h = kh.ambient() h_to_s = s.coerce_map_from(h) kh_to_ks = ks.retract * h_to_s * kh.lift ks.register_coercion(kh_to_ks) s_to_h = h.coerce_map_from(s) ks_to_kh = kh.retract * s_to_h * ks.lift kh.register_coercion(ks_to_kh) # temporary workaround until handled by trac 125959 self.one = ConstantFunction(ks.one()) self.zero = ConstantFunction(ks.zero())
def zero(self): """ EXAMPLES:: sage: E = CombinatorialFreeModule(ZZ, [1,2,3]) sage: F = CombinatorialFreeModule(ZZ, [2,3,4]) sage: H = Hom(E, F) sage: f = H.zero() sage: f Generic morphism: From: Free module generated by {1, 2, 3} over Integer Ring To: Free module generated by {2, 3, 4} over Integer Ring sage: f(E.monomial(2)) 0 sage: f(E.monomial(3)) == F.zero() True TESTS: We check that ``H.zero()`` is picklable:: sage: loads(dumps(f.parent().zero())) Generic morphism: From: Free module generated by {1, 2, 3} over Integer Ring To: Free module generated by {2, 3, 4} over Integer Ring """ from sage.misc.constant_function import ConstantFunction return self(ConstantFunction(self.codomain().zero()))
def __init__(self, kBoundedRing): r""" TESTS:: sage: Sym = SymmetricFunctions(QQ) sage: from sage.combinat.sf.new_kschur import kHomogeneous sage: KB = Sym.kBoundedSubspace(3,t=1) sage: kHomogeneous(KB) 3-bounded Symmetric Functions over Rational Field with t=1 in the 3-bounded homogeneous basis """ CombinatorialFreeModule.__init__(self, kBoundedRing.base_ring(), kBoundedRing.indices(), category= KBoundedSubspaceBases(kBoundedRing, kBoundedRing.t), prefix='h%d'%kBoundedRing.k) self._kBoundedRing = kBoundedRing self.k = kBoundedRing.k h = self.realization_of().ambient().homogeneous() self.lift = self._module_morphism(lambda x: h[x], codomain=h, triangular='lower', unitriangular=True, inverse_on_support=lambda p:p if p.get_part(0) <= self.k else None) self.ambient = ConstantFunction(h) self.lift.register_as_coercion() self.retract = SetMorphism(Hom(h, self, SetsWithPartialMaps()), self.lift.preimage) self.register_conversion(self.retract)
def binary_factorizations(self, predicate=ConstantFunction(True)): """ Returns the set of all the factorizations `self = u v` such that `l(self) = l(u) + l(v)`. Iterating through this set is Constant Amortized Time (counting arithmetic operations in the coxeter group as constant time) complexity, and memory linear in the length of `self`. One can pass as optional argument a predicate p such that `p(u)` implies `p(u')` for any `u` left factor of `self` and `u'` left factor of `u`. Then this returns only the factorizations `self = uv` such `p(u)` holds. EXAMPLES: We construct the set of all factorizations of the maximal element of the group:: sage: W = WeylGroup(['A',3]) sage: s = W.simple_reflections() sage: w0 = W.from_reduced_word([1,2,3,1,2,1]) sage: w0.binary_factorizations().cardinality() 24 The same number of factorizations, by bounded length:: sage: [w0.binary_factorizations(lambda u: u.length() <= l).cardinality() for l in [-1,0,1,2,3,4,5,6]] [0, 1, 4, 9, 15, 20, 23, 24] The number of factorizations of the elements just below the maximal element:: sage: [(s[i]*w0).binary_factorizations().cardinality() for i in [1,2,3]] [12, 12, 12] sage: w0.binary_factorizations(lambda u: False).cardinality() 0 TESTS:: sage: w0.binary_factorizations().category() Category of finite enumerated sets """ W = self.parent() if not predicate(W.one()): return FiniteCombinatorialClass([]) s = W.simple_reflections() def succ((u, v)): for i in v.descents(side='left'): u1 = u * s[i] if i == u1.first_descent() and predicate(u1): yield (u1, s[i] * v) return SearchForest(((W.one(), self), ), succ, category=FiniteEnumeratedSets())
def __init__(self, rule, width=None, initial_state=None, boundary=(0, 0)): """ Initialize ``self``. EXAMPLES:: sage: ECA = cellular_automata.Elementary(110, width=300) sage: TestSuite(ECA).run() """ if rule not in ZZ or rule < 0 or rule > 255: raise ValueError("invalid rule") self._rule = ZZ(rule).binary() # We reverse the rule to make it easier to work with self._rule = [ ZZ(x) for x in reversed('0' * (8 - len(self._rule)) + self._rule) ] if isinstance(width, list): initial_state = width width = len(initial_state) if initial_state is None: self._width = width initial_state = [ZZ.random_element(0, 2) for d in range(width)] else: if not all(d in [0, 1] for d in initial_state): raise ValueError("invalid initial state") initial_state = list( initial_state) # make sure it is a list and a copy if width is None: self._width = len(initial_state) elif width >= len(initial_state): self._width = width initial_state = ([0] * (width - len(initial_state)) + initial_state) else: raise ValueError("the width must be at least the length of" " the initial state") self._states = [initial_state] if boundary is not None: self._bdry = tuple(boundary) self._lbdry = ConstantFunction( boundary[0]) if boundary[0] in [0, 1] else boundary[0] self._rbdry = ConstantFunction( boundary[1]) if boundary[1] in [0, 1] else boundary[1] else: self._bdry = boundary
def cardinality(self): r""" EXAMPLES:: sage: WeylGroup(["A", 3, 1]).pieri_factors().cardinality() 15 """ if self._min_length == len(self._min_support) and self._max_length == len(self._max_support) -1: return Integer(2**(len(self._extra_support)) - 1) else: return self.generating_series(weight = ConstantFunction(1))
def __init__(self, parent, codomain=None): """ The Python constructor. EXAMPLES:: sage: X = Spec(ZZ) sage: Hom = X.Hom(X) sage: from sage.schemes.generic.morphism import SchemeMorphism sage: f = SchemeMorphism(Hom) sage: type(f) <class 'sage.schemes.generic.morphism.SchemeMorphism'> """ if codomain is not None: parent = Hom(parent, codomain) if not isinstance(parent, Homset): raise TypeError("parent (=%s) must be a Homspace"%parent) Element.__init__(self, parent) self.domain = ConstantFunction(parent.domain()) self._codomain = parent.codomain() self.codomain = ConstantFunction(self._codomain)
def __init__(self, semigroup, set, action, side, category): """ EXAMPLES:: sage: from sage.monoids.representations import SetWithAction sage: S = SetWithAction(ZZ, IntegerModRing(5), operator.mul) sage: TestSuite(S).run() """ self._set = set self._semigroup = semigroup self._action = action self._side = side self.action = action # This could be made into an Action # TODO: simplify what's below once we have support for *isomorphic facade sets* category = (EnumeratedSets().Finite().IsomorphicObjects(), category) Parent.__init__(self, facade = set, category = category) self.ambient = ConstantFunction(set) self.lift = identity self.retract = identity
def __init__(self, kBoundedRing): r""" TESTS:: sage: from sage.combinat.sf.new_kschur import K_kSchur sage: kB = SymmetricFunctions(QQ).kBoundedSubspace(3,1) sage: g = K_kSchur(kB) sage: g 3-bounded Symmetric Functions over Rational Field with t=1 in the K-3-Schur basis sage: g[2,1]*g[1] -2*Kks3[2, 1] + Kks3[2, 1, 1] + Kks3[2, 2] sage: g([]) Kks3[] sage: TestSuite(g).run() # long time (11s on sage.math, 2013) sage: h = SymmetricFunctions(QQ).h() sage: g(h[1,1]) -Kks3[1] + Kks3[1, 1] + Kks3[2] """ CombinatorialFreeModule.__init__(self, kBoundedRing.base_ring(), kBoundedRing.indices(), category= KBoundedSubspaceBases(kBoundedRing, kBoundedRing.base_ring().one()), prefix='Kks%d'%kBoundedRing.k) self._kBoundedRing = kBoundedRing self.k = kBoundedRing.k s = self.realization_of().ambient().schur() self.ambient = ConstantFunction(s) kh = self.realization_of().khomogeneous() g_to_kh = self.module_morphism(self._g_to_kh_on_basis,codomain=kh) g_to_kh.register_as_coercion() kh_to_g = kh.module_morphism(self._kh_to_g_on_basis, codomain=self) kh_to_g.register_as_coercion() h = self.realization_of().ambient().h() lift = self._module_morphism(self.lift, triangular='lower', unitriangular=True, codomain=h) lift.register_as_coercion() retract = h._module_morphism(self.retract, codomain=self) #retract = SetMorphism(Hom(h, self, SetsWithPartialMaps()), lift.preimage) self.register_conversion(retract)
def zero(self): """ EXAMPLES:: sage: R = QQ['x'] sage: H = Hom(ZZ, R, AdditiveMagmas().AdditiveUnital()) sage: f = H.zero() sage: f Generic morphism: From: Integer Ring To: Univariate Polynomial Ring in x over Rational Field sage: f(3) 0 sage: f(3) is R.zero() True TESTS: sage: TestSuite(f).run() """ from sage.misc.constant_function import ConstantFunction return self(ConstantFunction(self.codomain().zero()))
def annihilator_module_with_apex(self, J): """ INPUT: - ``J`` -- the index of a regular J-class This attempts to construct a submodule of `self` with apex `J`. To this hand, this constructs the annihilator with apex `J` (see :meth:`annihilator_with_apex`), and checks whether it is indeed a submodule, and that its apex is `J`. If not, `None` is returned. EXAMPLES:: sage: M = Semigroups().SetsWithAction().example().algebra(QQ); M Free module generated by Representation of the monoid generated by <2,3> acting on Z/10 Z by multiplication over Rational Field sage: S = M.semigroup() This semigroup has two regular `J`-classes, with that indexed by `1` being smaller than that indexed by `0` (no luck in the random indexing chosen by Sage):: sage: S.j_poset_on_regular_classes().cover_relations() [[1, 0]] To those `J`-classes correspond two submodules of M:: sage: M.annihilator_module_with_apex(0) Vector space of degree 10 and dimension 5 over Rational Field Basis matrix: [ 1 0 0 0 0 -1 0 0 0 0] [ 0 1 0 0 0 0 -1 0 0 0] [ 0 0 1 0 0 0 0 -1 0 0] [ 0 0 0 1 0 0 0 0 -1 0] [ 0 0 0 0 1 0 0 0 0 -1] sage: M.annihilator_module_with_apex(1) Vector space of degree 10 and dimension 10 over Rational Field Basis matrix: [1 0 0 0 0 0 0 0 0 0] [0 1 0 0 0 0 0 0 0 0] [0 0 1 0 0 0 0 0 0 0] [0 0 0 1 0 0 0 0 0 0] [0 0 0 0 1 0 0 0 0 0] [0 0 0 0 0 1 0 0 0 0] [0 0 0 0 0 0 1 0 0 0] [0 0 0 0 0 0 0 1 0 0] [0 0 0 0 0 0 0 0 1 0] [0 0 0 0 0 0 0 0 0 1] sage: M.annihilator_module_with_apex(0).apex() 0 sage: M.annihilator_module_with_apex(1).apex() 1 We conclude with a case where the construction fails. Consider the right class module of the BiHecke Monoid of type A_3, indexed by `2314 = s_2 s_1`: sage: W = SymmetricGroup(4) sage: S = BiHeckeMonoid(W); S bi-Hecke monoid of Symmetric group of order 4! as a permutation group sage: w = W([2,3,1,4]) sage: R = S.lr_regular_class_module(w, side='right') sage: list(f(W.one()) for f in R.basis().keys()) [(2,3), (1,2,3), ()] In this case, the construction fails:: sage: R.annihilator_module_with_apex(W([2,1,3,4])) # long time sage: R.annihilator_module_with_apex(W([1,3,2,4])) # long time Indeed, the annihilator subspaces (which are respectively the kernels of pi_2 and pi_1) are not submodules:: sage: R.annihilator_with_apex(W([2,1,3,4])) Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 -1 0] [ 0 0 1] sage: R.annihilator_with_apex(W([1,3,2,4])) Vector space of degree 3 and dimension 2 over Rational Field Basis matrix: [ 1 0 -1] [ 0 1 0] Could the map J -> R.annihilator_module_with_apexAnn(J) be extended to a morphism of posets from the poset of regular J-classes? Then, the pair of maps: J \mapsto self.annihilator_module_with_apex(J) and A \mapsto A.apex() should give a Galois connection. """ S = self.semigroup() AnnJ = self.annihilator_with_apex(J) # If the apex of AnnJ is not J if all(self.action(s, self.from_vector(x)).is_zero() for x in AnnJ.basis() for s in S.regular_j_class_semigroup_generators(J)): return None # If AnnJ is a submodule if any(self.action(s, self.from_vector(x)).to_vector() not in AnnJ for x in AnnJ.basis() for s in S.semigroup_generators()): return None # Problem: make sure that the subspace AnnJ is private to self assert not hasattr(AnnJ, 'apex') AnnJ.apex = ConstantFunction(J) return AnnJ
def __init__(self, generators, operators={}, add_degrees=operator.add, extend_word=ConstantFunction([]), hilbert_parent=None, degree=None, ambient=None, verbose=False): self._stats = {} self._verbose = verbose if self._verbose is not False: import tqdm if isinstance(self._verbose, tqdm.tqdm): self._bar = self._verbose else: self._bar = tqdm.tqdm(leave=True, unit=" extensions") if isinstance(self._verbose, str): self._bar.set_description(self._verbose) self._degree = degree if not isinstance(generators, dict): if self._degree is None: generators = {0: generators} else: gens = dict() for g in generators: d = self._degree(g) gens.setdefault(d, []) gens[d].append(g) generators = gens self._generators = generators if ambient is not None: assert all( ambient.is_parent_of(g) for gens in generators.values() for g in gens) else: ambient = { g.parent() for gens in generators.values() for g in gens } assert len(ambient) == 1 ambient = ambient.pop() self._ambient = ambient self._base_ring = ambient.base_ring() if hilbert_parent is None: if generators.keys()[0] in NN: hilbert_parent = QQ['q'] self._hilbert_parent = hilbert_parent if not isinstance(operators, dict): operators = {0: operators} self._operators = operators self._bases = {} self._todo = [] self._add_degrees = add_degrees self._extend_word = extend_word for d, gens in generators.iteritems(): basis = EchelonMatrixOfVectors(ambient=self._ambient, stats=self._stats) for g in gens: if basis.extend(g): self.todo(g, d, []) self._bases[d] = basis