2

for programming the Hamming cod in sage ( a compiler based on python) I need to create a matrix in which each column is a binary representation of a number say Hamming(3) the matrix should look like this

0  0  0  1  1  1  1
0  1  1  0  0  1  1
1  0  1  0  1  0  1

which is the binary represenation of numbers from 1 to 7. so what i did till now is to convert any given number to it's binary representation: i made this little function it take two values n and r and repserent n over r bits

binrep(n,r)
    x=n
    L=[]
    LL=[]
    while (n>0):
        a=int(float(n%2))
        L.append(a)
        n=(n-a)/2
    while (len(L)<r):
        L.append(0)
    #print(L)
    LL=L[::-1]
    return LL

so now i want to collect all the LL i got and make them in one big matrix like the one above

Cœur
  • 37,241
  • 25
  • 195
  • 267
bobyy
  • 21
  • 1
  • 2

3 Answers3

4

In addition to the other ones, an answer using numpy:

import numpy as np

# we're creating the binary representation for all numbers from 0 to N-1
N = 8

# for that, we need a 1xN matrix of all the numbers
a = np.arange(N, dtype=int)[np.newaxis,:]

# we also need a log2(N)x1 matrix, for the powers of 2 on the numbers.
# floor(log(N)) is the largest component that can make up any number up to N
l = int(np.log2(N))
b = np.arange(l, dtype=int)[::-1,np.newaxis]

# This step is a bit complicated, so I'll explain it below.
print np.array(a & 2**b > 0, dtype=int)

This prints:

[[0 0 0 0 1 1 1 1]
 [0 0 1 1 0 0 1 1]
 [0 1 0 1 0 1 0 1]]

The line

print np.array(a & 2**b > 0, dtype=int)

does a few things at once. I'll split it up into simpler steps:

# this takes our matrix b and creates a matrix containing the powers of 2
# up to 2^log2(N) == N
# (if N is a power of 2; otherwise, up to the next one below)
powers = 2**b

# now we calculate the bit-wise and (&) for each combination from a and b.
# because a has one row, and b as one column, numpy will automatically
# broadcast all values, so the resulting array has size log2(N)xN.
u = a & powers

# this is almost what we want, but has 4's in the first row,
# 2's in the second row and 1's in the last one.
# one method of getting 1's everywhere is to divide by powers:
print u / powers

# another way is to check where u > 0, which yields an array of bools,
# which we then convert to numbers by turning it into an array of ints.
print np.array(u > 0, dtype=int)
Carsten
  • 17,991
  • 4
  • 48
  • 53
  • I have absolutely no idea, how this works, but it _does_ work. :-) ... One vector of numbers, one of powers of two, then somehow matrix-multiplying them together. Wow... – tobias_k Jan 23 '15 at 14:11
  • 1
    @tobias_k I've edited my post and added an explanation. – Carsten Jan 23 '15 at 15:27
2

You just have to convert all those binary representations to lists of integers, collect them in a list of lists, and finally transpose that list of lists to get the desired output.

n = 3
binary = []
for i in range(1, 2**n):
    s = binrep(i, n)
    binary.append(map(int, s))
matrix = zip(*binary)

Or in one line: matrix = zip(*(map(int, binrep(i, n)) for i in range(1, 2**n)))

Result is

[(0, 0, 0, 1, 1, 1, 1), 
 (0, 1, 1, 0, 0, 1, 1), 
 (1, 0, 1, 0, 1, 0, 1)]

Also note that there are other ways to convert numbers to binary, e.g. using str.format:

def binrep(n,r):
    return "{0:0{1}b}".format(n, r)
Community
  • 1
  • 1
tobias_k
  • 81,265
  • 12
  • 120
  • 179
1

Like zoosuck mentioned, I would suggest the bin() function in replacement to your code. To print them in a sequence, assuming that the format is similar:

L = ['10101010', '10101010']

for i in L:
    print ' '.join([j for j in i])

In a similar manner, you can append it to a list or a dictionary.

Luis Ramos
  • 11
  • 1