Binary bit flip generator in python

1.7k Views Asked by At

I am currently using the commpy.channels.bsc function to flip the binary bots in a binary list with a given bit flip probability, The problem i am having is that I want to keep the a constant number of 1s in both my original and noisy vector.

Thanks in advance.

2

There are 2 best solutions below

0
On BEST ANSWER
import random

def applyNoise(bytes, bitFlipProbability):

  def applyByteNoise(byte):
    noisedByte = byte
    for bitPos in range(8):
      if random.random() < bitFlipProbability:
        noisedByte ^= 1 << bitPos
    return noisedByte

  return (applyByteNoise(byte) for byte in bytes)

print(list(applyNoise([ 1,2,3,4,5 ], 0.03)))

This returned for me e. g.:

[35, 2, 3, 12, 5]
2
On

A bit flip operation is basically an exclusive or (xor) operator. Thus, given a number, and a mask (the mask is just a number with 1s at the bit locations you want to flip and 0s elsewhere, e.g. 0b00000011 would flip the two less significant bits) is simply:

x = 8  # '0b00001000'
mask = 7  # '0b00000111'
flipped = x ^ y  # '0b00001111 --> 15'

If the bit flipping probability is uniform (50%), the you can generate the random mask as follows:

import random

mask = random.randint(0, 2**8)  # assuming you are working with 8 bit numbers

Note in the given examples, I'm assuming 8 bit long numbers, but it should be trivial to extend to longer binary representations. Also, this assuming unsigned integers (no sign bit). To handle signed integers you will need to implement that logic as well.

Edit

If you want to handle the general case, i.e. each bit position can be flipped with a different probability, you can do the following to generate the flipping mask:

def helper(cum, p):
    cum <<= 1
    return cum + int(random.random() <= p)

mask = reduce(helper, [0.25, 0, 1], 0)

In the previous example, the less significant bit (LSB) will be flipped always, the second LSB won't be flipped (0% prob) and the third LSB will be flipped with 25% prob.