Commit f1b44600 authored by Maxim Onciul's avatar Maxim Onciul
Browse files

update error creation to more vanilla gaussian channel

parent 7f16ca4c
......@@ -9,103 +9,163 @@
static size_t NUM_BLOCKS_ASSUMPTION = 128;
static uint8_t *
corruptBlock(uint8_t *block, size_t len, size_t rate, int num_errs)
{
if(!block) return NULL;
static std::random_device rd{};
static std::mt19937 gen{rd()};
static std::normal_distribution<> *dist = NULL;
if(num_errs < 0)
num_errs *= -1;
static size_t num_out_blocks = 0;
static size_t num_blocks = 0;
#ifdef TEST
cerr << "Inserting " << num_errs << " errors." << endl;
#endif
static size_t block_len = 0;
static double bit_err = 0.0;
static size_t block_err = 0;
for(int i=0; i<num_errs; i++)
static uint8_t **blocks = NULL;
static int keep_block()
{
int random_number = rand() % 1001;
return (random_number >= (int) block_err);
}
static void
resize_blocks_if_necessary()
{
if(num_out_blocks>=NUM_BLOCKS_ASSUMPTION)
{
int r = rand() % (len * 8);
block[r/8] ^= 1 << (r % 8);
#ifdef TEST
cerr << dec << r << " ";
#endif
NUM_BLOCKS_ASSUMPTION += 128; // code smell
blocks = (uint8_t**) realloc(blocks, NUM_BLOCKS_ASSUMPTION * sizeof(uint8_t*));
if(!blocks) throw new bad_alloc();
}
#ifdef TEST
cerr << endl << endl;
#endif
return block;
}
int main(int argc, char** argv)
static void
read_and_drop_blocks()
{
cxxopts::Options options("Errors", "Introduces errors for testing your coding scheme");
options.add_options()
("l", "block length in bytes", cxxopts::value<size_t>()->default_value("128"))
("b", "bit error energy [0-inf[", cxxopts::value<size_t>()->default_value("20"))
("B", "block error rate [permil]", cxxopts::value<size_t>()->default_value("1"));
// Parse commandline
auto result = options.parse(argc, argv);
// length
size_t block_len = result["l"].as<size_t>();
// error rates
size_t bit_err = result["b"].as<size_t>();
size_t block_err = result["B"].as<size_t>();
srand (time(NULL));
uint8_t **blocks = (uint8_t**) malloc(NUM_BLOCKS_ASSUMPTION * sizeof(uint8_t*));
if(!blocks) throw new bad_alloc();
size_t num_out_blocks = 0;
size_t num_blocks = 0;
// assignment
while( (blocks[num_out_blocks] = inputToBytes()) )
{
int r = rand() % 1001;
// Introduce missing blocks by just skipping some blocks
if(r >= (int) block_err) num_out_blocks++;
else free(blocks[num_out_blocks]);
if(num_out_blocks>=NUM_BLOCKS_ASSUMPTION)
if (keep_block())
{
num_out_blocks++;
resize_blocks_if_necessary();
} else
{
NUM_BLOCKS_ASSUMPTION += 128;
blocks = (uint8_t**) realloc(blocks, NUM_BLOCKS_ASSUMPTION * sizeof(uint8_t*));
if(!blocks) throw new bad_alloc();
free(blocks[num_out_blocks]);
}
num_blocks++;
}
if(num_out_blocks <= num_blocks/2)
throw new runtime_error("Well.. we deleted too many blocks.");
#ifdef TEST
cerr << endl;
#endif
std::random_device rd{};
std::mt19937 gen{rd()};
if(num_out_blocks <= num_blocks/2)
throw new runtime_error("Well.. we deleted too many blocks.");
}
static void
corrupt_byte(uint8_t *byte)
{
for(int b=0; b<8; b++)
if((*dist)(gen) > 1)
*byte ^= 1 << b;
}
std::normal_distribution<> d{0, (double) bit_err / 10.0};
static void
corrupt_block(uint8_t *block)
{
for(size_t i=0; i<block_len; i++)
corrupt_byte(&block[i]);
}
static void
corrupt_blocks()
{
for(size_t i=1; i<=num_blocks/2; i++)
corruptBlock(blocks[i], block_len, bit_err, std::round( d(gen) ) );
corrupt_block(blocks[i]);
}
static int
upper_four_bytes_are_zero(uint8_t byte)
{
return (byte & 0xf0) == 0;
}
static void
print_byte(uint8_t byte)
{
if(upper_four_bytes_are_zero(byte)) cout << 0;
cout << hex << (unsigned short) byte;
}
static void
print_block(uint8_t *block)
{
for(size_t j = 0; j<block_len; j++)
print_byte(block[j]);
cout << endl;
}
static void
output_blocks()
{
for(size_t i = 0; i<num_blocks/2; i++)
{
for(size_t j = 0; j<block_len; j++)
{
// if upper 4Bit are zeros, print an extra zero
if((blocks[i][j] & 0xf0) == 0) cout << 0;
cout << hex << (unsigned short) blocks[i][j];
}
cout << endl;
}
print_block(blocks[i]);
}
static void
free_blocks()
{
for(size_t i=0; i<num_out_blocks; i++)
free(blocks[i]);
free(blocks);
}
static void
parse_args(int argc, char** argv)
{
cxxopts::Options options("Errors", "Introduces errors for testing your coding scheme");
options.add_options()
("l", "block length in bytes", cxxopts::value<size_t>()->default_value("128"))
("b", "bit error energy real number", cxxopts::value<double>()->default_value("0.2"))
("B", "block error rate [permil]", cxxopts::value<size_t>()->default_value("1"));
auto result = options.parse(argc, argv);
block_len = result["l"].as<size_t>();
block_err = result["B"].as<size_t>();
bit_err = result["b"].as<double>();
}
static void
alloc_blocks()
{
blocks = (uint8_t**) malloc(NUM_BLOCKS_ASSUMPTION * sizeof(uint8_t*));
if(!blocks) throw new bad_alloc();
}
static void
init_random_modules()
{
srand (time(NULL));
dist = new std::normal_distribution<>(0, bit_err);
}
int main(int argc, char** argv)
{
parse_args(argc, argv);
init_random_modules();
alloc_blocks();
read_and_drop_blocks();
corrupt_blocks();
output_blocks();
free_blocks();
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment