Cartesian n-product of set for given n

55 views
Skip to first unread message

Jori Mantysalo

unread,
Aug 14, 2014, 7:47:42 AM8/14/14
to sage-s...@googlegroups.com
To get for example all bit vectors of size 3 one can say

CartesianProduct(range(2), range(2), range(2)).list()

To get this done for given n one can say at least

a=CartesianProduct(range(2)).list()
for n in range(1,n):
a=[flatten(x) for x in CartesianProduct(a, range(2)).list()]

Is there any direct (and quite possibly faster) way to accomplish this?

--
Jori Mäntysalo

Vincent Delecroix

unread,
Aug 14, 2014, 10:59:49 AM8/14/14
to sage-s...@googlegroups.com
"range(2)" is not suited for cartesian product. If you want to
consider integer mod 2 you can use

cartesian_product([Zmod(2)] * 10)

Vincent

2014-08-14 11:47 UTC, Jori Mantysalo <Jori.Ma...@uta.fi>:
> --
> You received this message because you are subscribed to the Google Groups
> "sage-support" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to sage-support...@googlegroups.com.
> To post to this group, send email to sage-s...@googlegroups.com.
> Visit this group at http://groups.google.com/group/sage-support.
> For more options, visit https://groups.google.com/d/optout.
>

Nils Bruin

unread,
Aug 14, 2014, 12:52:30 PM8/14/14
to sage-s...@googlegroups.com
On Thursday, August 14, 2014 4:47:42 AM UTC-7, jori.ma...@uta.fi wrote:
To get for example all bit vectors of size 3 one can say

CartesianProduct(range(2), range(2), range(2)).list()


If you want to generate a list of arguments that have to be passed as separate arguments, you can use in python:

CartesianProduct( * [range(2) for i in range(3)] )

(Note the star).

As Vincent points out, there are also alternative constructions, such as "cartesian_product", which return more intricately wrapped results. It depends on your applications if that is useful.
 

Jori Mantysalo

unread,
Aug 15, 2014, 3:28:25 AM8/15/14
to sage-s...@googlegroups.com
On Thu, 14 Aug 2014, Vincent Delecroix wrote:

> "range(2)" is not suited for cartesian product. If you want to
> consider integer mod 2 you can use
>
> cartesian_product([Zmod(2)] * 10)

Uh, cartesian_product and CartesianProduct on same system. My love-hate
-relationship to Sage just moved slightly to hate-side.

On Thu, 14 Aug 2014, Nils Bruin wrote:

> If you want to generate a list of arguments that have to be passed as
> separate arguments, you can use in python:
>
> CartesianProduct( * [range(2) for i in range(3)] )

Moved few degrees to love-side for this. Thanks!

> As Vincent points out, there are also alternative constructions, such as
> "cartesian_product", which return more intricately wrapped results. It
> depends on your applications if that is useful.

Actually I was asked to check some properties of square matrices. With

matrix(QQ,n,n,B)

, where B is a vector made of bits or values from [1,2,3] or whatever I
can construct all needed matrices. But this got more complicated: Now I
should generate lower triangular matrices with 1's as diagonal. Continuing
to think...

And thanks to you also!

--
Jori Mäntysalo

Nathann Cohen

unread,
Aug 17, 2014, 2:36:16 PM8/17/14
to sage-s...@googlegroups.com
Yo !

Uh, cartesian_product and CartesianProduct on same system. My love-hate
-relationship to Sage just moved slightly to hate-side.

Please, be respectful of other people's work and focus your hate on Sage's categories. The rest is quite fine :-P

I only wanted to add on the same topic that you should beware of everything related to categories, and that unless you want something more complicated than "just a cartesian product in order to list its elements", it is better and safer to use itertools.

What you asked in your first post can be done with

from itertools import product
product(range(n),repeat=n)

And if you want the product of more complicated things (with sets of different size) you can use the trick that was first proposed above, i.e.:

product(* [range(x) for x in [2,2,2,3,3,3,2,3]] )

Nathann

P.S. : Sage is open source: when you hate something, come and change it. Unless it's categories, in which case you're stuck.

Jori Mantysalo

unread,
Aug 19, 2014, 4:07:46 AM8/19/14
to sage-s...@googlegroups.com
On Sun, 17 Aug 2014, Nathann Cohen wrote:

> Please, be respectful of other people's work and focus your hate on Sage's
> categories. The rest is quite fine :-P

OK, I'll try to remember this. :=)

> And if you want the product of more complicated things (with sets of
> different size) you can use the trick that was first proposed above, i.e.:
>
> product(* [range(x) for x in [2,2,2,3,3,3,2,3]] )

Ah, seems to be quite a compact form!

But after two days of wondering I don't know how to generate all lower
triangular matrices with non-zero elements taken from, say, [0,1]. For all
matrices it seems simple:

N=3; v=[0,1];
p=product(product(v, repeat=N), repeat=N)
print matrix(ZZ, p.next())
print matrix(ZZ, p.next())
. . .

> P.S. : Sage is open source: when you hate something, come and change it.

It's not always possible. Or what_to_do to DifferentNamingStyles like
KleinFourGroup vs. is_isomorphic?

--
Jori Mäntysalo

Nathann Cohen

unread,
Aug 19, 2014, 5:16:11 AM8/19/14
to Sage Support
Yo !

> Ah, seems to be quite a compact form!

Yeah, but it only does what you want. Nothing involving more
complicated objects like category functions do.

> But after two days of wondering I don't know how to generate all lower
> triangular matrices with non-zero elements taken from, say, [0,1]. For all
> matrices it seems simple:

Try to understand how that works then:

from itertools import product
n = 3
S = [-1,1]
for m in product(*[S if i>=j else [0] for i in range(n) for j in range(n)]):
m = Matrix(n,n,m)

print m.str()


>
> N=3; v=[0,1];
> p=product(product(v, repeat=N), repeat=N)
> print matrix(ZZ, p.next())
> print matrix(ZZ, p.next())
> . . .
>
>
>> P.S. : Sage is open source: when you hate something, come and change it.
>
>
> It's not always possible. Or what_to_do to DifferentNamingStyles like
> KleinFourGroup vs. is_isomorphic?
>
> --
> Jori Mäntysalo
>
>
> --
> You received this message because you are subscribed to a topic in the
> Google Groups "sage-support" group.
> To unsubscribe from this topic, visit
> https://groups.google.com/d/topic/sage-support/OqnJVbY7NRU/unsubscribe.
> To unsubscribe from this group and all its topics, send an email to

Nathann Cohen

unread,
Aug 19, 2014, 5:20:02 AM8/19/14
to Sage Support
Yo !

> Ah, seems to be quite a compact form!

Yeah, but it only does what you want. Nothing involving more
complicated objects like category functions do.

> But after two days of wondering I don't know how to generate all lower
> triangular matrices with non-zero elements taken from, say, [0,1]. For all
> matrices it seems simple:

Try to understand how that works then:

from itertools import product
n = 3
S = [-1,1]
for m in product(*[S if i>=j else [0] for i in range(n) for j in range(n)]):
m = Matrix(n,n,m)
print m.str()
print '-'*20

>> P.S. : Sage is open source: when you hate something, come and change it.
>
> It's not always possible. Or what_to_do to DifferentNamingStyles like
> KleinFourGroup vs. is_isomorphic?

Believe me: this is the kind of stuff that frequent developpers do not
see anymore on sage-devel, and if you don't bring it up it will never
change. My answer, which is just a description of what is going on, is
that you will see upper case in functions which "create a mathematical
object", i.e. a group, a graph, that sort of things, while the methods
applied to them are in lower case.

But basically I was not even conscious of that, even though I have
been applying it for years. So write to sage-devel whenever something
feels wrong.

This "CartesianProduct" AND "cartesian_product" should be removed. But
that's categories, so you never know when that will happen.

Have fuuuuuuuun !

Nathann
Reply all
Reply to author
Forward
0 new messages