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.

// Copyright Steinwurf ApS 2013.// Distributed under the "STEINWURF EVALUATION LICENSE 1.0".// See accompanying file LICENSE.rst or// http://www.steinwurf.com/licensing#include<algorithm>#include<cassert>#include<cstdint>#include<iostream>#include<vector>#include<kodo_rlnc/full_vector_codes.hpp>#include<storage/storage.hpp>intmain(){// Set the number of symbols (i.e. the generation size in RLNC// terminology) and the size of a symbol in bytesuint32_tsymbols=16;uint32_tsymbol_size=1400;fifi::api::fieldfield=fifi::api::field::binary8;usingrlnc_encoder=kodo_rlnc::full_vector_encoder;usingrlnc_decoder=kodo_rlnc::full_vector_decoder;// In the following we will make an encoder/decoder factory.// The factories are used to build actual encoders/decodersrlnc_encoder::factoryencoder_factory(field,symbols,symbol_size);autoencoder=encoder_factory.build();rlnc_decoder::factorydecoder_factory(field,symbols,symbol_size);autodecoder=decoder_factory.build();std::vector<uint8_t>payload(encoder->payload_size());std::vector<uint8_t>block_in(encoder->block_size());// Just for fun - fill the data with random datastd::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 itencoder->set_const_symbols(storage::storage(block_in));// Define a data buffer where the symbols should be decodedstd::vector<uint8_t>block_out(decoder->block_size());decoder->set_mutable_symbols(storage::storage(block_out));//! [0]uint32_tencoded_count=0;uint32_tdropped_count=0;while(!decoder->is_complete()){// Encode a packet into the payload bufferuint32_tbytes_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 decoderdecoder->read_payload(payload.data());}std::cout<<"Encoded count = "<<encoded_count<<std::endl;std::cout<<"Dropped count = "<<dropped_count<<std::endl;//! [1]return0;}

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_tencoded_count=0;uint32_tdropped_count=0;while(!decoder->is_complete()){// Encode a packet into the payload bufferuint32_tbytes_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 decoderdecoder->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):

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.