# Turn Off Systematic Coding¶

A simple, yet clever technique called systematic encoding can be used to improve the performance of network coding. The way it works is to initially send everything uncoded, and then start the encoding. The benefit of this is that as the receivers initially have no data, all data will be useful for them. So if the symbols are safely received by the decoder, it can get the data “for free” without the need for decoding. The Kodo library has built-in support for this approach.

The following sample code is also based on 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 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 75 76 77 78 79 80 81 // Copyright Steinwurf ApS 2013. // Distributed under the "STEINWURF EVALUATION LICENSE 1.0". // See accompanying file LICENSE.rst or // http://www.steinwurf.com/licensing #include #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 symbols = 16; uint32_t symbol_size = 1400; fifi::api::field field = fifi::api::field::binary8; using rlnc_encoder = kodo_rlnc::encoder; using rlnc_decoder = kodo_rlnc::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, symbols, symbol_size); auto encoder = encoder_factory.build(); rlnc_decoder::factory decoder_factory(field, symbols, 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)); uint32_t encoded_count = 0; uint32_t dropped_count = 0; //! [0] // We switch any systematic operations off so we code // symbols from the beginning if (encoder->is_systematic_on()) encoder->set_systematic_off(); //! [1] 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; return 0; } 

What’s added in this example here is the use of is_systematic_on and set_systematic_off.

 1 2 3 4  // We switch any systematic operations off so we code // symbols from the beginning if (encoder->is_systematic_on()) encoder->set_systematic_off(); 

Initially the RLNC encoder has the systematic phase enabled per default. As seen in the previous example, this is automatically turned off when all symbols have been sent once. In this example we turn off the systematic phase before entering the coding loop. This can easily seen from the output when running the example:

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 = 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
Encoded count = 27
Dropped count = 11


Here the bytes used is always the same as all the symbols are encoded by the encoder. For most use cases, the systematic phase is beneficial. However it should be avoided if

• The state of receivers is unknown. If that’s the case, using the systematic approach might result in sending redundant data, as the receivers might already have some of the data.
• The setup has multiple sources. If this is the case, the sources should not send the same data, as this can be redundant for the receivers.