def unrank(self, x): """ For finite Cartesian products, we can reduce unrank to the constituent iterators. EXAMPLES:: sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: C = CartesianProduct_iters(range(1000), range(1000), range(1000)) sage: C[238792368] [238, 792, 368] Check for :trac:`15919`:: sage: FF = IntegerModRing(29) sage: C = CartesianProduct_iters(FF, FF, FF) sage: C.unrank(0) [0, 0, 0] """ try: lens = [_len(it) for it in self.iters] except (TypeError, AttributeError): return CartesianProduct_iters.unrank(self, x) positions = [] for n in lens: if n is infinity: return CartesianProduct_iters.unrank(self, x) if n == 0: raise IndexError("Cartesian Product is empty") positions.append(x % n) x = x // n if x != 0: raise IndexError("x larger than the size of the Cartesian Product") positions.reverse() return [unrank(L, i) for L, i in zip(self.iters, positions)]
def unrank(self, x): """ For finite Cartesian products, we can reduce unrank to the constituent iterators. EXAMPLES:: sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: C = CartesianProduct_iters(range(1000), range(1000), range(1000)) sage: C[238792368] [238, 792, 368] Check for :trac:`15919`:: sage: FF = IntegerModRing(29) sage: C = CartesianProduct_iters(FF, FF, FF) sage: C.unrank(0) [0, 0, 0] """ try: lens = [_len(it) for it in self.iters] except (TypeError, AttributeError): return CartesianProduct_iters.unrank(self, x) positions = [] for n in lens: if n is infinity: return CartesianProduct_iters.unrank(self, x) if n == 0: raise IndexError("Cartesian Product is empty") positions.append(x % n) x = x // n if x != 0: raise IndexError("x larger than the size of the Cartesian Product") positions.reverse() return [unrank(L, i) for L,i in zip(self.iters, positions)]
def is_finite(self): """ The Cartesian product is finite if all of its inputs are finite, or if any input is empty. EXAMPLES:: sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: CartesianProduct_iters(ZZ, []).is_finite() True sage: CartesianProduct_iters(4,4).is_finite() Traceback (most recent call last): ... ValueError: Unable to determine whether this product is finite """ finites = [_is_finite(L, fallback=None) for L in self.iters] if any(f is None for f in finites): raise ValueError( "Unable to determine whether this product is finite") if all(f is True for f in finites): return True lens = [_len(L) for L in self.iters] if any(l == 0 for l in lens): return True return False
def unrank(self, x): """ For finite cartesian products, we can reduce unrank to the constituent iterators. EXAMPLES:: sage: C = CartesianProduct(xrange(1000), xrange(1000), xrange(1000)) sage: C[238792368] [238, 792, 368] """ try: lens = [_len(it) for it in self.iters] except (TypeError, AttributeError): return CartesianProduct_iters.unrank(self, x) positions = [] for n in lens: if n is infinity: return CartesianProduct_iters.unrank(self, x) if n == 0: raise IndexError("Cartesian Product is empty") positions.append(x % n) x = x // n if x != 0: raise IndexError("x larger than the size of the Cartesian Product") positions.reverse() return [L[i] for L, i in zip(self.iters, positions)]
def unrank(self, x): """ For finite cartesian products, we can reduce unrank to the constituent iterators. EXAMPLES:: sage: C = CartesianProduct(xrange(1000), xrange(1000), xrange(1000)) sage: C[238792368] [238, 792, 368] """ try: lens = [_len(it) for it in self.iters] except (TypeError, AttributeError): return CartesianProduct_iters.unrank(self, x) positions = [] for n in lens: if n is infinity: return CartesianProduct_iters.unrank(self, x) if n == 0: raise IndexError("Cartesian Product is empty") positions.append(x % n) x = x // n if x != 0: raise IndexError("x larger than the size of the Cartesian Product") positions.reverse() return [L[i] for L,i in zip(self.iters, positions)]
def is_finite(self): """ The cartesian product is finite if all of its inputs are finite, or if any input is empty. EXAMPLES:: sage: CartesianProduct(ZZ, []).is_finite() True sage: CartesianProduct(4,4).is_finite() Traceback (most recent call last): ... ValueError: Unable to determine whether this product is finite """ finites = [_is_finite(L, fallback=None) for L in self.iters] if any(f is None for f in finites): raise ValueError("Unable to determine whether this product is finite") if all(f is True for f in finites): return True lens = [_len(L) for L in self.iters] if any(l == 0 for l in lens): return True return False
def some_elements(self, S=None): """ Returns a list (or iterable) of elements of ``self`` on which the tests should be run. This is only meaningful for container objects like parents. INPUT: - ``S`` -- a set of elements to select from. By default this will use the elements passed to this tester at creation time, or the result of :meth:`.some_elements` if no elements were specified. OUTPUT: A list of at most ``self._max_runs`` elements of ``S``. EXAMPLES: By default, this calls :meth:`.some_elements` on the instance:: sage: from sage.misc.sage_unittest import InstanceTester sage: class MyParent(Parent): ... def some_elements(self): ... return [1,2,3,4,5] ... sage: tester = InstanceTester(MyParent()) sage: list(tester.some_elements()) [1, 2, 3, 4, 5] sage: tester = InstanceTester(ZZ, elements = [1,3,5]) sage: list(tester.some_elements()) [1, 3, 5] sage: tester = InstanceTester(ZZ, elements = srange(100), max_runs=20) sage: S = tester.some_elements() sage: len(S) 20 sage: C = CartesianProduct(S, S, S, S) sage: len(C) 160000 sage: S = tester.some_elements(C) sage: len(S) 20 """ if S is None: if self._elements is None: S = self._instance.some_elements() else: S = self._elements from sage.misc.mrange import _len try: n = _len(S) if n > self._max_runs: from random import sample S = sample(S, self._max_runs) except (TypeError, AttributeError): # We already can't tell what the length of n is, so # there's no harm in obscuring it further. import itertools return itertools.islice(S,0,self._max_runs) return S
def some_elements(self, S=None): """ Returns a list (or iterable) of elements of ``self`` on which the tests should be run. This is only meaningful for container objects like parents. INPUT: - ``S`` -- a set of elements to select from. By default this will use the elements passed to this tester at creation time, or the result of :meth:`.some_elements` if no elements were specified. OUTPUT: A list of at most ``self._max_runs`` elements of ``S``. EXAMPLES: By default, this calls :meth:`.some_elements` on the instance:: sage: from sage.misc.sage_unittest import InstanceTester sage: class MyParent(Parent): ... def some_elements(self): ... return [1,2,3,4,5] ... sage: tester = InstanceTester(MyParent()) sage: list(tester.some_elements()) [1, 2, 3, 4, 5] sage: tester = InstanceTester(ZZ, elements = [1,3,5]) sage: list(tester.some_elements()) [1, 3, 5] sage: tester = InstanceTester(ZZ, elements = srange(100), max_runs=20) sage: S = tester.some_elements() sage: len(S) 20 sage: C = CartesianProduct(S, S, S, S) sage: len(C) 160000 sage: S = tester.some_elements(C) sage: len(S) 20 """ if S is None: if self._elements is None: S = self._instance.some_elements() else: S = self._elements from sage.misc.mrange import _len try: n = _len(S) if n > self._max_runs: from random import sample S = sample(S, self._max_runs) except (TypeError, AttributeError): # We already can't tell what the length of n is, so # there's no harm in obscuring it further. import itertools return itertools.islice(S, 0, self._max_runs) return S