def __init__(self, m, n, category=None):
        """
        TESTS::

            sage: M = FiniteSetMaps(2,3)
            sage: M.category()
            Category of finite enumerated sets
            sage: M.__class__
            <class 'sage.sets.finite_set_maps.FiniteSetMaps_MN_with_category'>
            sage: TestSuite(M).run()
        """
        Parent.__init__(
            self, category=EnumeratedSets().Finite().or_subcategory(category))
        self._m = Integer(m)
        self._n = Integer(n)
Exemple #2
0
    def __init__(self, n, action, category=None):
        """
        EXAMPLES::

            sage: M = FiniteSetMaps(3)
            sage: M.category()
            Join of Category of finite monoids and Category of finite enumerated sets
            sage: M.__class__
            <class 'sage.sets.finite_set_maps.FiniteSetEndoMaps_N_with_category'>
            sage: TestSuite(M).run()
        """
        category = (EnumeratedSets()
                    & Monoids().Finite()).or_subcategory(category)
        FiniteSetMaps_MN.__init__(self, n, n, category=category)
        self._action = action
Exemple #3
0
    def __init__(self, n=None, k=None, **constraints):
        """
        Initialize ``self``.

        EXAMPLES::

            sage: TestSuite(IntegerVectors(min_slope=0)).run()
            sage: TestSuite(IntegerVectors(3, max_slope=0)).run()
            sage: TestSuite(IntegerVectors(3, max_length=4)).run()
            sage: TestSuite(IntegerVectors(k=2, max_part=4)).run()
            sage: TestSuite(IntegerVectors(k=2, min_part=2, max_part=4)).run()
            sage: TestSuite(IntegerVectors(3, 2, max_slope=0)).run()
        """
        self.n = n
        self.k = k
        if self.k >= 0:
            constraints['length'] = self.k
        if 'outer' in constraints:
            constraints['ceiling'] = constraints['outer']
            del constraints['outer']
        if 'inner' in constraints:
            constraints['floor'] = constraints['inner']
            del constraints['inner']
        self.constraints = constraints

        if n is not None:
            if k is not None or 'max_length' in constraints:
                category = FiniteEnumeratedSets()
            else:
                category = EnumeratedSets()
        elif k is not None and 'max_part' in constraints:  # n is None
            category = FiniteEnumeratedSets()
        else:
            category = EnumeratedSets()
        IntegerVectors.__init__(self,
                                category=category)  # placeholder category
Exemple #4
0
    def __init__(self, e):
        """
        TESTS::

            sage: LW21 = LyndonWords([2,1]); LW21
            Lyndon words with evaluation [2, 1]
            sage: LW21 == loads(dumps(LW21))
            True
        """
        self._e = e
        self._words = FiniteWords(len(e))

        from sage.categories.enumerated_sets import EnumeratedSets
        Parent.__init__(self,
                        category=EnumeratedSets().Finite(),
                        facade=(self._words, ))
Exemple #5
0
    def __init__(self, policy):
        r"""
        TESTS::

            sage: from sage.structure.set_factories_example import XYPairs
            sage: TestSuite(XYPairs()).run()
        """
        ParentWithSetFactory.__init__(self, (),
                                      policy=policy,
                                      category=EnumeratedSets().Finite())
        DisjointUnionEnumeratedSets.__init__(self,
                                             LazyFamily(
                                                 range(MAX), self.pairs_y),
                                             facade=True,
                                             keepkey=False,
                                             category=self.category())
Exemple #6
0
    def __init__(self, roots = None, children = None, post_process = None,
                 algorithm = 'depth', facade = None, category=None):
        r"""
        TESTS::

            sage: S = SearchForest(NN, lambda x : [], lambda x: x^2 if x.is_prime() else None)
            sage: S.category()
            Category of enumerated sets
        """
        if roots is not None:
            self._roots = roots
        if children is not None:
            self.children = children
        if post_process is not None:
            self.post_process = post_process
        self._algorithm = algorithm
        Parent.__init__(self, facade = facade, category = EnumeratedSets().or_subcategory(category))
Exemple #7
0
    def __init__(self, y, policy):
        r"""
        TESTS::

            sage: from sage.structure.set_factories_example import XYPairs
            sage: TestSuite(XYPairs(y=1)).run()
        """
        self._y = y
        ParentWithSetFactory.__init__(self, (None, y),
                                      policy=policy,
                                      category=EnumeratedSets().Finite())
        DisjointUnionEnumeratedSets.__init__(
            self,
            LazyFamily(range(MAX), self.single_pair),
            facade=True,
            keepkey=False,
            category=self.category())  # TODO remove and fix disjoint union.
    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
Exemple #9
0
    def __init__(self, n, k):
        """
        Initialize ``self``.

        TESTS::

            sage: LW23 = LyndonWords(2,3); LW23
            Lyndon words from an alphabet of size 2 of length 3
            sage: LW23== loads(dumps(LW23))
            True
        """
        self._n = n
        self._k = k
        self._words = FiniteWords(self._n)

        from sage.categories.enumerated_sets import EnumeratedSets
        Parent.__init__(self,
                        category=EnumeratedSets().Finite(),
                        facade=(self._words, ))
Exemple #10
0
    def __init__(self, group, element):
        r"""
        Generic conjugacy classes for elements in a group.
        This is the default fall-back implementation to be used whenever
        GAP cannot handle the group.

        EXAMPLES::

            sage: G = SymmetricGroup(4)
            sage: g = G((1,2,3,4))
            sage: ConjugacyClass(G,g)
            Conjugacy class of (1,2,3,4) in Symmetric group of order 4! as a
            permutation group
            sage: TestSuite(G).run()
        """
        self._parent = group
        self._representative = element
        if group.is_finite():
            Parent.__init__(self, category=FiniteEnumeratedSets())
        else:  # If the group is not finite, then we do not know if we are finite or not
            Parent.__init__(self, category=EnumeratedSets())
Exemple #11
0
    def basis(self, region=None):
        if hasattr(self, "_domain"):
            # hack: we're grading a Steenrod algebra module
            gb = []
            for idx in range(0, len(self._summands)):

                def mkfam(emb, xx):
                    return xx.map(lambda u: emb(u))

                x = self._summands[idx].basis(region)
                gb.append(mkfam(self._domain.summand_embedding(idx), x))
            if all(fam.cardinality() < Infinity for fam in gb):
                category = FiniteEnumeratedSets()
            else:
                category = EnumeratedSets()
            return DisjointUnionEnumeratedSets(gb,
                                               keepkey=False,
                                               category=category)

        # this is probably a sample grading...
        return set.union(*[x.basis(region) for x in self._summands])
Exemple #12
0
    def __init__(self, *args, **kwds):
        """
        Initialize ``self``.

        TESTS::

            sage: from sage.combinat.integer_lists import IntegerLists
            sage: C = IntegerLists(2, length=3)
            sage: C == loads(dumps(C))
            True
        """
        if "name" in kwds:
            self.rename(kwds.pop("name"))

        if "global_options" in kwds:
            from sage.misc.superseded import deprecation
            deprecation(15525, 'the global_options argument is deprecated since, in general,'
                               ' pickling is broken; create your own class instead')
            self.global_options = kwds.pop("global_options")

        if "element_class" in kwds:
            self.Element = kwds.pop("element_class")

        if "element_constructor" in kwds:
            element_constructor = kwds.pop("element_constructor")
        elif issubclass(self.Element, ClonableArray):
            # Not all element classes support check=False
            element_constructor = self._element_constructor_nocheck
        else:
            element_constructor = None  # Parent's default

        category = kwds.pop("category", None)
        if category is None:
            category = EnumeratedSets().Finite()

        # Let self.backend be some IntegerListsBackend
        self.backend = self.backend_class(*args, **kwds)

        Parent.__init__(self, element_constructor=element_constructor,
                        category=category)
Exemple #13
0
    def _call_(self, X, enumerated_set_if_possible=False):
        r"""
        Construct an object in this category from the data in ``X``.

        EXAMPLES::

            sage: Sets()(ZZ)
            Integer Ring
            sage: Sets()([1, 2, 3])
            {1, 2, 3}

        .. note::

           Using ``Sets()(A)`` used to implement some sort of
           forgetful functor into the ``Sets()`` category. This
           feature has been removed, because it was not consistent
           with the semantic of :meth:`Category.__call__`. Proper
           forgetful functors will eventually be implemented, with
           another syntax.

        - ``enumerated_set_if_possible`` -- an option to ask Sage to
          try to build an ``EnumeratedSets()`` rather that a
          ``Sets()`` if possible.  This is experimental an may change
          in the future::

              sage: S = Sets()([1, 2, 3]); S.category()
              Category of sets
              sage: S = Sets()([1, 2, 3], True); S.category()
              Category of facade finite enumerated sets
        """
        import sage.sets.all
        if enumerated_set_if_possible:
            from sage.categories.enumerated_sets import EnumeratedSets
            try:
                return EnumeratedSets()(X)
            except NotImplementedError:
                pass
        return sage.sets.all.Set(X)
Exemple #14
0
    def __init__(self, set, function, name=None):
        """
        TESTS::

            sage: from sage.sets.family import LazyFamily
            sage: f = LazyFamily([3,4,7], lambda i: 2*i); f
            Lazy family (<lambda>(i))_{i in [3, 4, 7]}
            sage: TestSuite(f).run()   # __contains__ is not implemented
            Failure ...
            The following tests failed: _test_an_element, _test_enumerated_set_contains, _test_some_elements

        Check for bug #5538::

            sage: l = [3,4,7]
            sage: f = LazyFamily(l, lambda i: 2*i);
            sage: l[1] = 18
            sage: f
            Lazy family (<lambda>(i))_{i in [3, 4, 7]}
        """
        from sage.combinat.combinat import CombinatorialClass  # workaround #12482

        if set in FiniteEnumeratedSets():
            category = FiniteEnumeratedSets()
        elif set in InfiniteEnumeratedSets():
            category = InfiniteEnumeratedSets()
        elif isinstance(set, (list, tuple, CombinatorialClass)):
            category = FiniteEnumeratedSets()
        else:
            category = EnumeratedSets()

        Parent.__init__(self, category=category)
        if name is not None:
            warn(name_warn_message)
        from copy import copy
        self.set = copy(set)
        self.function = function
Exemple #15
0
    def _call_(self, X):
        """
        Construct an object in this category from the data in ``X``.

        EXAMPLES::

            sage: FiniteEnumeratedSets()(GF(3))
            Finite Field of size 3
            sage: Partitions(3)
            Partitions of the integer 3

        For now, lists, tuples, sets, Sets are coerced into finite
        enumerated sets::

            sage: FiniteEnumeratedSets()([1, 2, 3])
            {1, 2, 3}
            sage: FiniteEnumeratedSets()((1, 2, 3))
            {1, 2, 3}
            sage: FiniteEnumeratedSets()(set([1, 2, 3]))
            {1, 2, 3}
            sage: FiniteEnumeratedSets()(Set([1, 2, 3]))
            {1, 2, 3}
        """
        return EnumeratedSets()._call_(X)
    def __init__(self, cartan_type, prefix, finite=True):
        r"""

        EXAMPLES::

            sage: from sage.combinat.root_system.fundamental_group import FundamentalGroupOfExtendedAffineWeylGroup
            sage: F = FundamentalGroupOfExtendedAffineWeylGroup(['A',3,1])
            sage: F in Groups().Commutative().Finite()
            True
            sage: TestSuite(F).run()
        """
        def leading_support(beta):
            r"""
            Given a dictionary with one key, return this key
            """
            supp = beta.support()
            assert len(supp) == 1
            return supp[0]

        self._cartan_type = cartan_type
        self._prefix = prefix
        special_node = cartan_type.special_node()
        self._special_nodes = cartan_type.special_nodes()

        # initialize dictionaries with the entries for the
        # distinguished special node

        # dictionary of inverse elements
        inverse_dict = {}
        inverse_dict[special_node] = special_node
        # dictionary for the action of special automorphisms by
        # permutations of the affine Dynkin nodes
        auto_dict = {}
        for i in cartan_type.index_set():
            auto_dict[special_node, i] = i
        # dictionary for the finite Weyl component of the special automorphisms
        reduced_words_dict = {}
        reduced_words_dict[0] = tuple([])

        if cartan_type.dual().is_untwisted_affine():
            # this combines the computations for an untwisted affine
            # type and its affine dual
            cartan_type = cartan_type.dual()
        if cartan_type.is_untwisted_affine():
            cartan_type_classical = cartan_type.classical()
            I = [i for i in cartan_type_classical.index_set()]
            Q = RootSystem(cartan_type_classical).root_lattice()
            alpha = Q.simple_roots()
            omega = RootSystem(
                cartan_type_classical).weight_lattice().fundamental_weights()
            W = Q.weyl_group(prefix="s")
            for i in self._special_nodes:
                if i == special_node:
                    continue
                antidominant_weight, reduced_word = omega[
                    i].to_dominant_chamber(reduced_word=True, positive=False)
                reduced_words_dict[i] = tuple(reduced_word)
                w0i = W.from_reduced_word(reduced_word)
                idual = leading_support(-antidominant_weight)
                inverse_dict[i] = idual
                auto_dict[i, special_node] = i
                for j in I:
                    if j == idual:
                        auto_dict[i, j] = special_node
                    else:
                        auto_dict[i, j] = leading_support(w0i.action(alpha[j]))

        self._action = Family(
            self._special_nodes, lambda i: Family(cartan_type.index_set(),
                                                  lambda j: auto_dict[i, j]))
        self._dual_node = Family(self._special_nodes, inverse_dict.__getitem__)
        self._reduced_words = Family(self._special_nodes,
                                     reduced_words_dict.__getitem__)

        if finite:
            cat = Category.join(
                (Groups().Commutative().Finite(), EnumeratedSets()))
        else:
            cat = Groups().Commutative().Infinite()
        Parent.__init__(self, category=cat)
 def __classcall__(cls, semigroup, set, action, side = None, category = None):
     set = EnumeratedSets()(set)
     assert set in EnumeratedSets().Finite()
     category = semigroup.category().SetsWithAction().or_subcategory(category)
     return super(SetWithAction, cls).__classcall__(cls, semigroup, set, action, side, category)
Exemple #18
0
def unrank(L, i):
    r"""
    Return the `i`-th element of `L`.

    INPUT:

    - ``L`` -- a list, tuple, finite enumerated set, ...
    - ``i`` -- an int or :class:`Integer`

    The purpose of this utility is to give a uniform idiom to recover
    the `i`-th element of an object ``L``, whether ``L`` is a list,
    tuple (or more generally a :class:`collections.abc.Sequence`), an
    enumerated set, some old parent of Sage still implementing
    unranking in the method ``__getitem__``, or an iterable (see
    :class:`collections.abc.Iterable`). See :trac:`15919`.

    EXAMPLES:

    Lists, tuples, and other :class:`sequences <collections.abc.Sequence>`::

        sage: from sage.combinat.ranker import unrank
        sage: unrank(['a','b','c'], 2)
        'c'
        sage: unrank(('a','b','c'), 1)
        'b'
        sage: unrank(range(3,13,2), 1)
        5

    Enumerated sets::

        sage: unrank(GF(7), 2)
        2
        sage: unrank(IntegerModRing(29), 10)
        10

    An iterable::

        sage: unrank(NN,4)
        4

    An iterator::

        sage: unrank(('a{}'.format(i) for i in range(20)), 0)
        'a0'
        sage: unrank(('a{}'.format(i) for i in range(20)), 2)
        'a2'

    .. WARNING::

        When unranking an iterator, it returns the ``i``-th element
        beyond where it is currently at::

            sage: from sage.combinat.ranker import unrank
            sage: it = iter(range(20))
            sage: unrank(it, 2)
            2
            sage: unrank(it, 2)
            5

    TESTS::

        sage: from sage.combinat.ranker import unrank
        sage: unrank(list(range(3)), 10)
        Traceback (most recent call last):
        ...
        IndexError: list index out of range

        sage: unrank(('a{}'.format(i) for i in range(20)), 22)
        Traceback (most recent call last):
        ...
        IndexError: index out of range
    """
    if L in EnumeratedSets():
        return L.unrank(i)
    if isinstance(L, Sequence):
        return L[i]
    if isinstance(L, Parent):
        # handle parents still implementing unranking in __getitem__
        try:
            return L[i]
        except (AttributeError, TypeError, ValueError):
            pass
    if isinstance(L, Iterable):
        try:
            it = iter(L)
            for _ in range(i):
                next(it)
            return next(it)
        except StopIteration:
            raise IndexError("index out of range")
    raise ValueError("Don't know how to unrank on {}".format(L))
Exemple #19
0
def Family(indices,
           function=None,
           hidden_keys=[],
           hidden_function=None,
           lazy=False,
           name=None):
    r"""
    A Family is an associative container which models a family
    `(f_i)_{i \in I}`. Then, ``f[i]`` returns the element of the family
    indexed by `i`. Whenever available, set and combinatorial class
    operations (counting, iteration, listing) on the family are induced
    from those of the index set.

    There are several available implementations (classes) for different
    usages; Family serves as a factory, and will create instances of
    the appropriate classes depending on its arguments.

    INPUT:

    - ``indices`` -- the indices for the family
    - ``function`` -- (optional) the function `f` applied to all visible
      indices; the default is the identity function
    - ``hidden_keys`` -- (optional) a list of hidden indices that can be
      accessed through ``my_family[i]``
    - ``hidden_function`` -- (optional) a function for the hidden indices
    - ``lazy`` -- boolean (default: ``False``); whether the family is lazily
      created or not; if the indices are infinite, then this is automatically
      made ``True``
    - ``name`` -- (optional) the name of the function; only used when the
      family is lazily created via a function

    EXAMPLES:

    In its simplest form, a list `l = [l_0, l_1, \ldots, l_{\ell}]` or a
    tuple by itself is considered as the family `(l_i)_{i \in I}` where
    `I` is the set `\{0, \ldots, \ell\}` where `\ell` is ``len(l) - 1``.
    So ``Family(l)`` returns the corresponding family::

        sage: f = Family([1,2,3])
        sage: f
        Family (1, 2, 3)
        sage: f = Family((1,2,3))
        sage: f
        Family (1, 2, 3)

    Instead of a list you can as well pass any iterable object::

        sage: f = Family(2*i+1 for i in [1,2,3]);
        sage: f
        Family (3, 5, 7)

    A family can also be constructed from a dictionary ``t``. The resulting
    family is very close to ``t``, except that the elements of the family
    are the values of ``t``. Here, we define the family
    `(f_i)_{i \in \{3,4,7\}}` with `f_3 = a`, `f_4 = b`, and `f_7 = d`::

        sage: f = Family({3: 'a', 4: 'b', 7: 'd'})
        sage: f
        Finite family {3: 'a', 4: 'b', 7: 'd'}
        sage: f[7]
        'd'
        sage: len(f)
        3
        sage: list(f)
        ['a', 'b', 'd']
        sage: [ x for x in f ]
        ['a', 'b', 'd']
        sage: f.keys()
        [3, 4, 7]
        sage: 'b' in f
        True
        sage: 'e' in f
        False

    A family can also be constructed by its index set `I` and
    a function `f`, as in `(f(i))_{i \in I}`::

        sage: f = Family([3,4,7], lambda i: 2*i)
        sage: f
        Finite family {3: 6, 4: 8, 7: 14}
        sage: f.keys()
        [3, 4, 7]
        sage: f[7]
        14
        sage: list(f)
        [6, 8, 14]
        sage: [x for x in f]
        [6, 8, 14]
        sage: len(f)
        3

    By default, all images are computed right away, and stored in an internal
    dictionary::

        sage: f = Family((3,4,7), lambda i: 2*i)
        sage: f
        Finite family {3: 6, 4: 8, 7: 14}

    Note that this requires all the elements of the list to be
    hashable. One can ask instead for the images `f(i)` to be computed
    lazily, when needed::

        sage: f = Family([3,4,7], lambda i: 2*i, lazy=True)
        sage: f
        Lazy family (<lambda>(i))_{i in [3, 4, 7]}
        sage: f[7]
        14
        sage: list(f)
        [6, 8, 14]
        sage: [x for x in f]
        [6, 8, 14]

    This allows in particular for modeling infinite families::

        sage: f = Family(ZZ, lambda i: 2*i, lazy=True)
        sage: f
        Lazy family (<lambda>(i))_{i in Integer Ring}
        sage: f.keys()
        Integer Ring
        sage: f[1]
        2
        sage: f[-5]
        -10
        sage: i = iter(f)
        sage: i.next(), i.next(), i.next(), i.next(), i.next()
        (0, 2, -2, 4, -4)

    Note that the ``lazy`` keyword parameter is only needed to force
    laziness. Usually it is automatically set to a correct default value (ie:
    ``False`` for finite data structures and ``True`` for enumerated sets::

        sage: f == Family(ZZ, lambda i: 2*i)
        True

    Beware that for those kind of families len(f) is not supposed to
    work. As a replacement, use the .cardinality() method::

       sage: f = Family(Permutations(3), attrcall("to_lehmer_code"))
       sage: list(f)
       [[0, 0, 0], [0, 1, 0], [1, 0, 0], [1, 1, 0], [2, 0, 0], [2, 1, 0]]
       sage: f.cardinality()
       6

    Caveat: Only certain families with lazy behavior can be pickled. In
    particular, only functions that work with Sage's pickle_function
    and unpickle_function (in sage.misc.fpickle) will correctly
    unpickle. The following two work::

       sage: f = Family(Permutations(3), lambda p: p.to_lehmer_code()); f
       Lazy family (<lambda>(i))_{i in Standard permutations of 3}
       sage: f == loads(dumps(f))
       True

       sage: f = Family(Permutations(3), attrcall("to_lehmer_code")); f
       Lazy family (i.to_lehmer_code())_{i in Standard permutations of 3}
       sage: f == loads(dumps(f))
       True

    But this one does not::

       sage: def plus_n(n): return lambda x: x+n
       sage: f = Family([1,2,3], plus_n(3), lazy=True); f
       Lazy family (<lambda>(i))_{i in [1, 2, 3]}
       sage: f == loads(dumps(f))
       Traceback (most recent call last):
       ...
       ValueError: Cannot pickle code objects from closures

    Finally, it can occasionally be useful to add some hidden elements
    in a family, which are accessible as ``f[i]``, but do not appear in the
    keys or the container operations::

        sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
        sage: f
        Finite family {3: 6, 4: 8, 7: 14}
        sage: f.keys()
        [3, 4, 7]
        sage: f.hidden_keys()
        [2]
        sage: f[7]
        14
        sage: f[2]
        4
        sage: list(f)
        [6, 8, 14]
        sage: [x for x in f]
        [6, 8, 14]
        sage: len(f)
        3

    The following example illustrates when the function is actually
    called::

        sage: def compute_value(i):
        ...       print('computing 2*'+str(i))
        ...       return 2*i
        sage: f = Family([3,4,7], compute_value, hidden_keys=[2])
        computing 2*3
        computing 2*4
        computing 2*7
        sage: f
        Finite family {3: 6, 4: 8, 7: 14}
        sage: f.keys()
        [3, 4, 7]
        sage: f.hidden_keys()
        [2]
        sage: f[7]
        14
        sage: f[2]
        computing 2*2
        4
        sage: f[2]
        4
        sage: list(f)
        [6, 8, 14]
        sage: [x for x in f]
        [6, 8, 14]
        sage: len(f)
        3

    Here is a close variant where the function for the hidden keys is
    different from that for the other keys::

        sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2], hidden_function = lambda i: 3*i)
        sage: f
        Finite family {3: 6, 4: 8, 7: 14}
        sage: f.keys()
        [3, 4, 7]
        sage: f.hidden_keys()
        [2]
        sage: f[7]
        14
        sage: f[2]
        6
        sage: list(f)
        [6, 8, 14]
        sage: [x for x in f]
        [6, 8, 14]
        sage: len(f)
        3

    Family accept finite and infinite EnumeratedSets as input::

        sage: f = Family(FiniteEnumeratedSet([1,2,3]))
        sage: f
        Family (1, 2, 3)
        sage: from sage.categories.examples.infinite_enumerated_sets import NonNegativeIntegers
        sage: f = Family(NonNegativeIntegers())
        sage: f
        Family (An example of an infinite enumerated set: the non negative integers)

    ::

        sage: f = Family(FiniteEnumeratedSet([3,4,7]), lambda i: 2*i)
        sage: f
        Finite family {3: 6, 4: 8, 7: 14}
        sage: f.keys()
        {3, 4, 7}
        sage: f[7]
        14
        sage: list(f)
        [6, 8, 14]
        sage: [x for x in f]
        [6, 8, 14]
        sage: len(f)
        3

    TESTS::

        sage: f = Family({1:'a', 2:'b', 3:'c'})
        sage: f
        Finite family {1: 'a', 2: 'b', 3: 'c'}
        sage: f[2]
        'b'
        sage: loads(dumps(f)) == f
        True

    ::

        sage: f = Family({1:'a', 2:'b', 3:'c'}, lazy=True)
        Traceback (most recent call last):
        ValueError: lazy keyword only makes sense together with function keyword !

    ::

        sage: f = Family(range(1,27), lambda i: chr(i+96))
        sage: f
            Finite family {1: 'a', 2: 'b', 3: 'c', 4: 'd', 5: 'e', 6: 'f', 7: 'g', 8: 'h', 9: 'i', 10: 'j', 11: 'k', 12: 'l', 13: 'm', 14: 'n', 15: 'o', 16: 'p', 17: 'q', 18: 'r', 19: 's', 20: 't', 21: 'u', 22: 'v', 23: 'w', 24: 'x', 25: 'y', 26: 'z'}
        sage: f[2]
        'b'

    The factory ``Family`` is supposed to be idempotent. We test this feature here::

        sage: from sage.sets.family import FiniteFamily, LazyFamily, TrivialFamily
        sage: f = FiniteFamily({3: 'a', 4: 'b', 7: 'd'})
        sage: g = Family(f)
        sage: f == g
        True

        sage: f = Family([3,4,7], lambda i: 2*i, hidden_keys=[2])
        sage: g = Family(f)
        sage: f == g
        True

        sage: f = LazyFamily([3,4,7], lambda i: 2*i)
        sage: g = Family(f)
        sage: f == g
        True

        sage: f = TrivialFamily([3,4,7])
        sage: g = Family(f)
        sage: f == g
        True

    The family should keep the order of the keys::

        sage: f = Family(["c", "a", "b"], lambda x: x+x)
        sage: list(f)
        ['cc', 'aa', 'bb']

    TESTS:

    Only the hidden function is applied to the hidden keys::

        sage: f = lambda x : 2*x
        sage: h_f = lambda x:x%2
        sage: F = Family([1,2,3,4],function = f, hidden_keys=[5],hidden_function=h_f)
        sage: F[5]
        1
    """
    assert (type(hidden_keys) == list)
    assert (isinstance(lazy, bool))

    if hidden_keys == []:
        if hidden_function is not None:
            raise ValueError("hidden_function keyword only makes sense "
                             "together with hidden_keys keyword !")
        if function is None:
            if lazy:
                raise ValueError(
                    "lazy keyword only makes sense together with function keyword !"
                )
            if isinstance(indices, dict):
                return FiniteFamily(indices)
            if isinstance(indices, (list, tuple)):
                return TrivialFamily(indices)
            if isinstance(indices, (FiniteFamily, LazyFamily, TrivialFamily)):
                return indices
            from sage.combinat.combinat import CombinatorialClass  # workaround #12482
            if (indices in EnumeratedSets()
                    or isinstance(indices, CombinatorialClass)):
                return EnumeratedFamily(indices)
            if hasattr(indices, "__iter__"):
                return TrivialFamily(indices)

            raise NotImplementedError
        if (isinstance(indices, (list, tuple, FiniteEnumeratedSet))
                and not lazy):
            return FiniteFamily(dict([(i, function(i)) for i in indices]),
                                keys=indices)

        return LazyFamily(indices, function, name)
    if lazy:
        raise ValueError("lazy keyword is incompatible with hidden keys !")
    if hidden_function is None:
        hidden_function = function
    return FiniteFamilyWithHiddenKeys(
        dict([(i, function(i)) for i in indices]), hidden_keys,
        hidden_function)
Exemple #20
0
 def __init__(self, category=EnumeratedSets()):
     Parent.__init__(self, ZZ, category=category)
    def __classcall_private__(cls,
                              universe,
                              *predicates,
                              vars=None,
                              names=None,
                              category=None):
        r"""
        Normalize init arguments.

        TESTS::

            sage: ConditionSet(ZZ, names=["x"]) is ConditionSet(ZZ, names=x)
            True
            sage: ConditionSet(RR, x > 0, names=x) is ConditionSet(RR, (x > 0).function(x))
            True
        """
        if category is None:
            category = Sets()
        if isinstance(universe, Parent):
            if universe in Sets().Finite():
                category &= Sets().Finite()
            if universe in EnumeratedSets():
                category &= EnumeratedSets()

        if vars is not None:
            if names is not None:
                raise ValueError(
                    'cannot use names and vars at the same time; they are aliases'
                )
            names, vars = vars, None

        if names is not None:
            names = normalize_names(-1, names)

        callable_symbolic_predicates = []
        other_predicates = []

        for predicate in predicates:
            if isinstance(predicate, Expression) and predicate.is_callable():
                if names is None:
                    names = tuple(str(var) for var in predicate.args())
                elif len(names) != len(predicate.args()):
                    raise TypeError('mismatch in number of arguments')
                if vars is None:
                    vars = predicate.args()
                callable_symbolic_predicates.append(predicate)
            elif isinstance(predicate, Expression):
                if names is None:
                    raise TypeError(
                        'use callable symbolic expressions or provide variable names'
                    )
                if vars is None:
                    from sage.symbolic.ring import SR
                    vars = tuple(SR.var(name) for name in names)
                callable_symbolic_predicates.append(predicate.function(*vars))
            else:
                other_predicates.append(predicate)

        predicates = list(
            _stable_uniq(callable_symbolic_predicates + other_predicates))

        if not other_predicates and not callable_symbolic_predicates:
            if names is None and category is None:
                # No conditions, no variable names, no category, just use Set.
                return Set(universe)

        if any(predicate.args() != vars
               for predicate in callable_symbolic_predicates):
            # TODO: Implement safe renaming of the arguments of a callable symbolic expressions
            raise NotImplementedError(
                'all callable symbolic expressions must use the same arguments'
            )

        if names is None:
            names = ("x", )
        return super().__classcall__(cls,
                                     universe,
                                     *predicates,
                                     names=names,
                                     category=category)
Exemple #22
0
        def _test_yacop_grading(self, tester=None, **options):
            from sage.misc.sage_unittest import TestSuite
            from sage.misc.lazy_format import LazyFormat
            from sage.categories.enumerated_sets import EnumeratedSets
            from sage.categories.finite_enumerated_sets import FiniteEnumeratedSets

            is_sub_testsuite = tester is not None
            tester = self._tester(tester=tester, **options)

            if hasattr(self.grading(), "_domain"):
                tester.assertTrue(
                    self is self.grading()._domain,
                    LazyFormat("grading of %s has wrong _domain attribute %s")
                    % (self, self.grading()._domain),
                )

            bbox = self.bbox()
            tester.assertTrue(
                bbox.__class__ == region,
                LazyFormat("bounding box of %s is not a region") % (self, ),
            )

            # make sure we can get a basis of the entire module
            basis = self.graded_basis()
            tester.assertTrue(
                basis in EnumeratedSets(),
                LazyFormat("graded basis of %s is not an EnumeratedSet") %
                (self, ),
            )

            # nontrivial_degrees
            ntdegs = self.nontrivial_degrees()
            tester.assertTrue(
                basis in EnumeratedSets(),
                LazyFormat("nontrivial_degrees of %s is not an EnumeratedSet")
                % (self, ),
            )

            # check whether a presumably finite piece is also an EnumeratedSet
            rg = region(tmax=10,
                        tmin=-10,
                        smax=10,
                        smin=-10,
                        emax=10,
                        emin=-10)
            basis = self.graded_basis(rg)
            tester.assertTrue(
                basis in EnumeratedSets(),
                LazyFormat(
                    "graded basis of %s in the region %s is not an EnumeratedSet"
                ) % (self, rg),
            )

            for (deg, elem) in self._some_homogeneous_elements():
                deg2 = self.degree(elem)
                if hasattr(elem, "degree"):
                    deg3 = elem.degree()
                    tester.assertEqual(
                        deg2,
                        deg3,
                        LazyFormat(
                            "parent.degree(el) != (el).degree() for parent %s and element %s"
                        ) % (self, elem),
                    )

                tester.assertEqual(
                    deg2,
                    deg,
                    LazyFormat(
                        "homogeneuous_decomposition claims %s has degree %s, but degree says %s"
                    ) % (elem, deg, deg2),
                )

                # test graded_basis_coefficients
                b = self.grading().basis(deg)
                tester.assertTrue(
                    b.cardinality() < Infinity,
                    LazyFormat("%s not finite in degree %s") % (self, deg),
                )

            from sage.categories.commutative_additive_groups import (
                CommutativeAdditiveGroups, )

            if self in CommutativeAdditiveGroups():
                el = self.an_element()
                sp = el.homogeneous_decomposition()
                for (deg, elem) in list(sp.items()):
                    b = self.grading().basis(deg)
                    c = self.graded_basis_coefficients(elem, deg)
                    sm = sum(cf * be for (cf, be) in zip(c, b))
                    if elem != sm:
                        print(("self=", self))
                        print(("elem=", elem))
                        print(("deg=", deg))
                        print(("graded basis=", list(b)))
                        print(("lhs=", elem.monomial_coefficients()))
                        print(("rhs=", sm.monomial_coefficients()))
                    tester.assertEqual(
                        elem,
                        sm,
                        LazyFormat(
                            "graded_basis_coefficients failed on element %s of %s: sums to %s"
                        ) % (elem, self, sm),
                    )

                el2 = sum(smd for (key, smd) in list(sp.items()))
                tester.assertEqual(
                    el.parent(),
                    el2.parent(),
                    LazyFormat(
                        "%s and the sum of its homogeneous pieces have different parents:\n   %s\n!= %s"
                    ) % (
                        el,
                        el.parent(),
                        el2.parent(),
                    ),
                )
                if el.parent() is el2.parent():
                    tester.assertEqual(
                        el,
                        el2,
                        LazyFormat(
                            "%s is not the sum of its homogeneous pieces (which is %s)"
                        ) % (
                            el,
                            el2,
                        ),
                    )