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.
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 sample code is also based on the basic
example.

// Copyright Steinwurf ApS 2016.// Distributed under the "STEINWURF EVALUATION LICENSE 1.0".// See accompanying file LICENSE.rst or// http://www.steinwurf.com/licensing#include<cstdint>#include<cstdlib>#include<ctime>#include<algorithm>#include<iostream>#include<vector>#include<kodocpp/kodocpp.hpp>intmain(){// Seed the random number generator to produce different data every timesrand((uint32_t)time(0));// Set the number of symbols (i.e. the generation size in RLNC// terminology) and the size of a symbol in bytesuint32_tmax_symbols=16;uint32_tmax_symbol_size=1400;// In the following we will make an encoder/decoder factory.// The factories are used to build actual encoders/decoderskodocpp::encoder_factoryencoder_factory(kodocpp::codec::full_vector,kodocpp::field::binary8,max_symbols,max_symbol_size);kodocpp::encoderencoder=encoder_factory.build();kodocpp::decoder_factorydecoder_factory(kodocpp::codec::full_vector,kodocpp::field::binary8,max_symbols,max_symbol_size);kodocpp::decoderdecoder=decoder_factory.build();std::vector<uint8_t>payload(encoder.payload_size());std::vector<uint8_t>data_in(encoder.block_size());// Just for fun - fill the data with random datastd::generate(data_in.begin(),data_in.end(),rand);// Assign the data buffer to the encoder so that we may start// to produce encoded symbols from itencoder.set_const_symbols(data_in.data(),encoder.block_size());// Create a buffer which will contain the decoded data, and we assign// that buffer to the decoderstd::vector<uint8_t>data_out(decoder.block_size());decoder.set_mutable_symbols(data_out.data(),decoder.block_size());uint32_tencoded_count=0;uint32_tdropped_count=0;//! [0]// We switch any systematic operations off, so the encoder produces// coded symbols from the beginning.// Note that some codecs might not have a systematic mode, so it is a// good idea to check this capability with has_systematic_interface()// before calling is_systematic_on() and set_systematic_off()if(encoder.has_systematic_interface()&&encoder.is_systematic_on()){encoder.set_systematic_off();}//! [1]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;// Check if we properly decoded the dataif(data_in==data_out){std::cout<<"Data decoded correctly"<<std::endl;}return0;}

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

1
2
3
4
5
6
7
8
9

// We switch any systematic operations off, so the encoder produces// coded symbols from the beginning.// Note that some codecs might not have a systematic mode, so it is a// good idea to check this capability with has_systematic_interface()// before calling is_systematic_on() and set_systematic_off()if(encoder.has_systematic_interface()&&encoder.is_systematic_on()){encoder.set_systematic_off();}

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