Some bit manipulations


#1

I’m trying to port to julia some python code that produces this:
ind0: [[0 2 4 6]
[0 1 4 5]
[0 1 2 3]]
ind1: [[1 3 5 7]
[2 3 6 7]
[4 5 6 7]]

For a range of 0:7, the code produces 2 2d arrays. For any value j in that range, that value is in ind[i,:] if j has a 1 in bit position i. So the 1st row of ind1 is all values that have a 1 in bit0, the second row of ind1 is all values that have a 1 in bit1…

I tried this code:

    function gen_ind(_size, bits)
        all_syms = Array(0:_size-1)
        all_bits = Array(0:bits-1)
        bit_mask = (reshape(all_syms, (size(all_syms)[1],1)) .>> reshape(all_bits, (1, size(all_bits)[1]))) .& 1
        ind1 = [find(bit_mask[:,i]) for i in 1:bits]
    end
    gen_ind(8,3)

It sort of works, but it returns

[find(bit_mask[:,i]) for i in 1:3]
3-element Array{Array{Int64,1},1}:
 [2, 4, 6, 8]
 [3, 4, 7, 8]
 [5, 6, 7, 8]

an Array{Array…}, where I wanted Array{Int64,2}.
Any suggestions? Doesn’t need to be efficient - only used once at program start.


#2

You can do hcat([find(bit_mask[:,i]) for i in 1:bits]...)

to get:

gen_ind(8,3)
4×3 Array{Int64,2}:
 2  3  5
 4  4  6
 6  7  7
 8  8  8

#3

I suppose I’m better off learning to leave the vectorized functions, and just do:

function ind(bits, value)
    syms = 2^bits
    rows = []
    for bit in 0:bits-1
        row = []
        for sym in 0:syms-1
            if((sym >> bit) & 1 == value)
                push!(row, sym)
            end
        end
        push!(rows, row)
    end
    return hcat(rows...)'
end