Beispiel #1
0
    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())
Beispiel #2
0
            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()))
Beispiel #3
0
    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)
Beispiel #4
0
        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())
Beispiel #5
0
    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
Beispiel #6
0
    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))
Beispiel #7
0
    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
Beispiel #9
0
    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)
Beispiel #10
0
                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()))
Beispiel #11
0
            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
Beispiel #12
0
    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