# Simulating Losses¶

In this example we will expand the previous basic example by simulating some loss of the encoded data. This can be done simply by not “transmitting” encoded symbol to the decoder. The complete example is shown below.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 // Copyright Steinwurf ApS 2013. // Distributed under the "STEINWURF RESEARCH LICENSE 1.0". // See accompanying file LICENSE.rst or // http://www.steinwurf.com/licensing #include #include #include #include #include #include int main() { // Set the number of symbols (i.e. the generation size in RLNC // terminology) and the size of a symbol in bytes uint32_t max_symbols = 16; uint32_t max_symbol_size = 1400; fifi::api::field field = fifi::api::field::binary8; using rlnc_encoder = kodo_rlnc::full_vector_encoder; using rlnc_decoder = kodo_rlnc::full_vector_decoder; // In the following we will make an encoder/decoder factory. // The factories are used to build actual encoders/decoders rlnc_encoder::factory encoder_factory(field, max_symbols, max_symbol_size); auto encoder = encoder_factory.build(); rlnc_decoder::factory decoder_factory(field, max_symbols, max_symbol_size); auto decoder = decoder_factory.build(); std::vector payload(encoder->payload_size()); std::vector block_in(encoder->block_size()); // Just for fun - fill the data with random data std::generate(block_in.begin(), block_in.end(), rand); // Assign the data buffer to the encoder so that we may start // to produce encoded symbols from it encoder->set_const_symbols(storage::storage(block_in)); // Define a data buffer where the symbols should be decoded std::vector block_out(decoder->block_size()); decoder->set_mutable_symbols(storage::storage(block_out)); //! [0] uint32_t encoded_count = 0; uint32_t dropped_count = 0; while (!decoder->is_complete()) { // Encode a packet into the payload buffer uint32_t bytes_used = encoder->write_payload(payload.data()); std::cout << "Bytes used = " << bytes_used << std::endl; ++encoded_count; if (rand() % 2) { ++dropped_count; continue; } // Pass that packet to the decoder decoder->read_payload(payload.data()); } std::cout << "Encoded count = " << encoded_count << std::endl; std::cout << "Dropped count = " << dropped_count << std::endl; //! [1] return 0; } 

As the attentive reader might notice, only the coding loop is changed from the basic example.

  1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23  uint32_t encoded_count = 0; uint32_t dropped_count = 0; while (!decoder->is_complete()) { // Encode a packet into the payload buffer uint32_t bytes_used = encoder->write_payload(payload.data()); std::cout << "Bytes used = " << bytes_used << std::endl; ++encoded_count; if (rand() % 2) { ++dropped_count; continue; } // Pass that packet to the decoder decoder->read_payload(payload.data()); } std::cout << "Encoded count = " << encoded_count << std::endl; std::cout << "Dropped count = " << dropped_count << std::endl; 

The change is fairly simple. We introduce a 50% loss using rand() % 2 and add a variable dropped_count to keep track of the dropped symbols.

The encoder can, in theory, create an infinite number of packages. This is a feature called rate-less which is unique to network coding. This means that as long as the loss is below 100% the decoder will be able to finish the decoding.

A graphical representation of the setup is seen in the figure below.

Running the example will result in the following output (the output will always be the same as the random function is never seeded):

Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1405
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Bytes used = 1417
Encoded count = 27
Dropped count = 11


An interesting thing to notice is the number of bytes used. It increases slightly after the encoder has encoded 16 symbols (the same number as the number of symbols in the generation). This is because the encoder exits the systematic phase where it sends the symbols uncoded. This technique will be explained in following example.