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)
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
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
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, ))
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())
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))
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
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, ))
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())
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])
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)
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)
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
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)
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))
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)
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)
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, ), )