Cartesian Products#
- class sage.combinat.cartesian_product.CartesianProduct_iters(*iters)[source]#
Bases:
EnumeratedSetFromIterator
Cartesian product of finite sets.
This class will soon be deprecated (see Issue #18411 and Issue #19195). One should instead use the functorial construction
cartesian_product
. The main differences in behavior are:construction:
CartesianProduct
takes as many argument as there are factors whereascartesian_product
takes a single list (or iterable) of factors;representation of elements: elements are represented by plain Python list for
CartesianProduct
versus a custom element class forcartesian_product
;membership testing: because of the above, plain Python lists are not considered as elements of a
cartesian_product
.
All of these is illustrated in the examples below.
EXAMPLES:
sage: F1 = ['a', 'b'] sage: F2 = [1, 2, 3, 4] sage: F3 = Permutations(3) sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: C = CartesianProduct_iters(F1, F2, F3) sage: c = cartesian_product([F1, F2, F3]) sage: type(C.an_element()) <class 'list'> sage: type(c.an_element()) <class 'sage.sets.cartesian_product.CartesianProduct_with_category.element_class'> sage: l = ['a', 1, Permutation([3,2,1])] sage: l in C True sage: l in c False sage: elt = c(l) sage: elt ('a', 1, [3, 2, 1]) sage: elt in c True sage: elt.parent() is c True
>>> from sage.all import * >>> F1 = ['a', 'b'] >>> F2 = [Integer(1), Integer(2), Integer(3), Integer(4)] >>> F3 = Permutations(Integer(3)) >>> from sage.combinat.cartesian_product import CartesianProduct_iters >>> C = CartesianProduct_iters(F1, F2, F3) >>> c = cartesian_product([F1, F2, F3]) >>> type(C.an_element()) <class 'list'> >>> type(c.an_element()) <class 'sage.sets.cartesian_product.CartesianProduct_with_category.element_class'> >>> l = ['a', Integer(1), Permutation([Integer(3),Integer(2),Integer(1)])] >>> l in C True >>> l in c False >>> elt = c(l) >>> elt ('a', 1, [3, 2, 1]) >>> elt in c True >>> elt.parent() is c True
- cardinality()[source]#
Returns the number of elements in the Cartesian product of everything in *iters.
EXAMPLES:
sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: CartesianProduct_iters(range(2), range(3)).cardinality() 6 sage: CartesianProduct_iters(range(2), range(3)).cardinality() 6 sage: CartesianProduct_iters(range(2), range(3), range(4)).cardinality() 24
>>> from sage.all import * >>> from sage.combinat.cartesian_product import CartesianProduct_iters >>> CartesianProduct_iters(range(Integer(2)), range(Integer(3))).cardinality() 6 >>> CartesianProduct_iters(range(Integer(2)), range(Integer(3))).cardinality() 6 >>> CartesianProduct_iters(range(Integer(2)), range(Integer(3)), range(Integer(4))).cardinality() 24
This works correctly for infinite objects:
sage: CartesianProduct_iters(ZZ, QQ).cardinality() +Infinity sage: CartesianProduct_iters(ZZ, []).cardinality() 0
>>> from sage.all import * >>> CartesianProduct_iters(ZZ, QQ).cardinality() +Infinity >>> CartesianProduct_iters(ZZ, []).cardinality() 0
- is_finite()[source]#
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
>>> from sage.all import * >>> from sage.combinat.cartesian_product import CartesianProduct_iters >>> CartesianProduct_iters(ZZ, []).is_finite() True >>> CartesianProduct_iters(Integer(4),Integer(4)).is_finite() Traceback (most recent call last): ... ValueError: unable to determine whether this product is finite
- list()[source]#
Returns
EXAMPLES:
sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: CartesianProduct_iters(range(3), range(3)).list() [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]] sage: CartesianProduct_iters('dog', 'cat').list() [['d', 'c'], ['d', 'a'], ['d', 't'], ['o', 'c'], ['o', 'a'], ['o', 't'], ['g', 'c'], ['g', 'a'], ['g', 't']]
>>> from sage.all import * >>> from sage.combinat.cartesian_product import CartesianProduct_iters >>> CartesianProduct_iters(range(Integer(3)), range(Integer(3))).list() [[0, 0], [0, 1], [0, 2], [1, 0], [1, 1], [1, 2], [2, 0], [2, 1], [2, 2]] >>> CartesianProduct_iters('dog', 'cat').list() [['d', 'c'], ['d', 'a'], ['d', 't'], ['o', 'c'], ['o', 'a'], ['o', 't'], ['g', 'c'], ['g', 'a'], ['g', 't']]
- random_element()[source]#
Return a random element from the Cartesian product of *iters.
EXAMPLES:
sage: from sage.combinat.cartesian_product import CartesianProduct_iters sage: c = CartesianProduct_iters('dog', 'cat').random_element() sage: c in CartesianProduct_iters('dog', 'cat') True
>>> from sage.all import * >>> from sage.combinat.cartesian_product import CartesianProduct_iters >>> c = CartesianProduct_iters('dog', 'cat').random_element() >>> c in CartesianProduct_iters('dog', 'cat') True
- unrank(x)[source]#
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]
>>> from sage.all import * >>> from sage.combinat.cartesian_product import CartesianProduct_iters >>> C = CartesianProduct_iters(range(Integer(1000)), range(Integer(1000)), range(Integer(1000))) >>> C[Integer(238792368)] [238, 792, 368]
Check for Issue #15919:
sage: FF = IntegerModRing(29) sage: C = CartesianProduct_iters(FF, FF, FF) sage: C.unrank(0) [0, 0, 0]
>>> from sage.all import * >>> FF = IntegerModRing(Integer(29)) >>> C = CartesianProduct_iters(FF, FF, FF) >>> C.unrank(Integer(0)) [0, 0, 0]