1

How can I make an n by 2^n matrix of 0 and 1 values where all the columns are distinct? For example, if n = 2 that would be

0011
0101 .

And I can use itertools to make all possible tuples.

list(itertools.product([0,1],repeat = 2))

But how do I make those the columns of my matrix?

marshall
  • 2,443
  • 7
  • 25
  • 45
  • possibly related: http://stackoverflow.com/questions/1208118/using-numpy-to-build-an-array-of-all-combinations-of-two-arrays – alko Dec 11 '13 at 20:31

4 Answers4

2
X = numpy.array(map(lambda x: list(x), itertools.product([0,1],repeat = 2)))

Takes your itertools result and turns every element into a list and then turns it into a numpy array. If that's not the direction that you want you can then use.

X = X.transpose()
aplassard
  • 759
  • 3
  • 10
2

Simply apply a np.matrix to your result:

>>> np.matrix(list(itertools.product([0,1],repeat = 2)))
matrix([[0, 0],
        [0, 1],
        [1, 0],
        [1, 1]])
jazzpi
  • 1,399
  • 12
  • 18
  • One note, make sure you understand the difference between array and matrix in numpy http://wiki.scipy.org/NumPy_for_Matlab_Users – aplassard Dec 11 '13 at 20:30
  • @aplassard Thanks. I just need to be able to multiply them. But what does "matrix objects always have exactly rank 2. " mean? The rank of the identity matrix should be the number of rows for example. – marshall Dec 11 '13 at 20:31
  • Sounds great. The multiplication functionality is different between the two. In numpy.matrix \'*\' means matrix multiplication and multiply(A,B) is elementwise multiplication. In numpy.array \'*\' means elementwise mutliplication and .dot(A) is matrix multiplication. – aplassard Dec 11 '13 at 20:33
2

For entertainment's sake, here's a pure-numpy way of doing it:

>>> n = 2
>>> (np.arange(2**n) // ((1 << np.arange(n)[::-1,None]))) & 1
array([[0, 0, 1, 1],
       [0, 1, 0, 1]])
>>> n = 4
>>> (np.arange(2**n) // ((1 << np.arange(n)[::-1,None]))) & 1
array([[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1],
       [0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1],
       [0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1],
       [0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]])

Some explanation (note that it's very unlikely I'd ever write anything like the above in production code):

First, we get the numbers we need the bits of:

>>> np.arange(2**n)
array([0, 1, 2, 3])

Then the exponents of the powers of 2 we care about:

>>> np.arange(n)
array([0, 1])

Bitshift 1 by these to get the powers of two:

>>> 1 << np.arange(n)
array([1, 2])

Swap the order for aesthetic purposes:

>>> (1 << np.arange(n))[::-1]
array([2, 1])

Use None to introduce an extra axis, so we can broadcast:

>>> (1 << np.arange(n))[::-1, None]
array([[2],
       [1]])

Divide:

>>> np.arange(2**n) // (1 << np.arange(n))[::-1, None]
array([[0, 0, 1, 1],
       [0, 1, 2, 3]])

Take only the first bit:

>>> (np.arange(2**n) // (1 << np.arange(n))[::-1, None]) & 1
array([[0, 0, 1, 1],
       [0, 1, 0, 1]])
DSM
  • 342,061
  • 65
  • 592
  • 494
  • Brilliant! But it took me quite some time to understand your code. May I ask for some comments? – alko Dec 11 '13 at 20:40
0

Just use list comprehension:

a = list(itertools.product([0,1],repeat = n))
[[p[i] for p in a] for i in xrange(n)]

Demo:

>>> n = 2
>>> a = list(itertools.product([0,1],repeat = n)) 
>>> M = [[p[i] for p in a] for i in xrange(0,n)]
>>> M
[[0, 0, 1, 1], [0, 1, 0, 1]]
>>> n = 4
>>> a = list(itertools.product([0,1],repeat = 4)) 
>>> M = [[p[i] for p in a] for i in xrange(0,4)]
>>> M
[[0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1], 
[0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1], 
[0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 1, 1], 
[0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1]]
Alvaro Fuentes
  • 16,937
  • 4
  • 56
  • 68
  • I need it to be a matrix as I will be multiplying it by another matrix. – marshall Dec 11 '13 at 20:35
  • @xndrme: Numpy matrix. The result of `list(itertools.product([0,1],repeat = 2))` is a matrix as well. – jazzpi Dec 11 '13 at 20:51
  • Well, what I understood from the question is that I should make a matrix from the tuples, not a `Numpy` matrix. A list is always a matrix but from the example you can conclude that you must make it from the tuples. Anyway I understand the point. Thanks – Alvaro Fuentes Dec 11 '13 at 20:58