aff3ct / my_project_with_aff3ct

Small code examples using AFF3CT as a library.
MIT License
15 stars 16 forks source link

Encode/Decode using Polar Code and Turbo Code #11

Closed jdayana closed 3 years ago

jdayana commented 3 years ago

Hi,

I am currently modifying the bootstrap example source code and would like to use the following classes:

  1. Encoder_polar
  2. Decoder_polar_SC_naive
  3. Encoder_turbo
  4. Decoder_turbo However, I am unsure of how to generate the arguments for the methods in those classes. For example, I have tried using the tools::Frozenbits_generator for the Polar FEC type case but was not able to execute the program successfully.

Could I get some help with the above four examples so that I may continue with the rest?

I appreciate your kind reply.

Thanks, Dayana

SubtleMuffin commented 3 years ago

Try check out the development branch's Cython example.

jdayana commented 3 years ago

Nice, thank you @SubtleMuffin. I will take a look.

jdayana commented 3 years ago

Hi,

I am trying to use the turbo encoder module in the bootstrap example. However, I am facing some problems with initializing its constructor. Below is the code used:

#include <iostream>
#include <memory>
#include <vector>
#include <string>

#include "aff3ct.hpp"
using namespace aff3ct;

struct params
{
    int   K = 40;               // number of information bits
    int   N = 132;              // codeword size
    int   fe = 100;             // PRNG seed for the AWGN channel
    int   seed = 0;             // PRNG seed for the AWGN channel
    float ebn0_min = 0.00f;             // minimum SNR value
    float ebn0_max = 5.01f;             // maximum SNR value
    float ebn0_step = 1.00f;            // SNR step
    float R;                    // code rate (R=K/N)
    int numberOfIterations = 6;
};
void init_params(params& p);

struct modules
{
    std::unique_ptr<module::Source_random<>>        source;
    std::unique_ptr<module::Encoder_turbo<>>        encoder;
    std::unique_ptr<module::Modem_BPSK<>>           modem;
    std::unique_ptr<module::Channel_AWGN_LLR<>>     channel;
    std::unique_ptr<module::Decoder_turbo<>>        decoder;
    std::unique_ptr<module::Monitor_BFER<>>         monitor;
};
void init_modules(const params& p, modules& m);

struct buffers
{
    std::vector<int  > ref_bits;
    std::vector<int  > enc_bits;
    std::vector<float> symbols;
    std::vector<float> noisy_symbols;
    std::vector<float> LLRs;
    std::vector<int  > dec_bits;
};
void init_buffers(const params& p, buffers& b);

struct utils
{
    std::unique_ptr<tools::Sigma<>>               noise;     // a sigma noise type
    std::vector<std::unique_ptr<tools::Reporter>> reporters; // list of reporters dispayed in the terminal
    std::unique_ptr<tools::Terminal_std>          terminal;  // manage the output text in the terminal
};
void init_utils(const modules& m, utils& u);

int main(int argc, char** argv)
{
    // get the AFF3CT version
    const std::string v = "v" + std::to_string(tools::version_major()) + "." +
        std::to_string(tools::version_minor()) + "." +
        std::to_string(tools::version_release());

    std::cout << "#----------------------------------------------------------" << std::endl;
    std::cout << "# This is a basic program using the AFF3CT library (" << v << ")" << std::endl;
    std::cout << "# Feel free to improve it as you want to fit your needs." << std::endl;
    std::cout << "#----------------------------------------------------------" << std::endl;
    std::cout << "#" << std::endl;

    params p;  init_params(p); // create and initialize the parameters defined by the user
    modules m; init_modules(p, m); // create and initialize the modules
    buffers b; init_buffers(p, b); // create and initialize the buffers required by the modules
    utils u;   init_utils(m, u); // create and initialize the utils

    // display the legend in the terminal
    u.terminal->legend();

    // loop over the various SNRs
    for (auto ebn0 = p.ebn0_min; ebn0 < p.ebn0_max; ebn0 += p.ebn0_step)
    {
        // compute the current sigma for the channel noise
        const auto esn0 = tools::ebn0_to_esn0(ebn0, p.R);
        const auto sigma = tools::esn0_to_sigma(esn0);

        u.noise->set_noise(sigma, ebn0, esn0);

        // update the sigma of the modem and the channel
        m.modem->set_noise(*u.noise);
        m.channel->set_noise(*u.noise);

        // display the performance (BER and FER) in real time (in a separate thread)
        u.terminal->start_temp_report();

        // run the simulation chain
        while (!m.monitor->fe_limit_achieved() && !u.terminal->is_interrupt())
        {
            m.source->generate(b.ref_bits);
            m.encoder->encode(b.ref_bits, b.enc_bits);
            m.modem->modulate(b.enc_bits, b.symbols);
            m.channel->add_noise(b.symbols, b.noisy_symbols);
            m.modem->demodulate(b.noisy_symbols, b.LLRs);
            m.decoder->decode_siho(b.LLRs, b.dec_bits);
            m.monitor->check_errors(b.dec_bits, b.ref_bits);
        }

        // display the performance (BER and FER) in the terminal
        u.terminal->final_report();

        // reset the monitor for the next SNR
        m.monitor->reset();
        u.terminal->reset();

        // if user pressed Ctrl+c twice, exit the SNRs loop
        if (u.terminal->is_over()) break;
    }

    std::cout << "# End of the simulation" << std::endl;

    system("pause");
    return 0;
}

void init_params(params& p)
{
    p.R = (float)p.K / (float)p.N;
    std::cout << "# * Simulation parameters: " << std::endl;
    std::cout << "#    ** Frame errors   = " << p.fe << std::endl;
    std::cout << "#    ** Noise seed     = " << p.seed << std::endl;
    std::cout << "#    ** Info. bits (K) = " << p.K << std::endl;
    std::cout << "#    ** Frame size (N) = " << p.N << std::endl;
    std::cout << "#    ** Code rate  (R) = " << p.R << std::endl;
    std::cout << "#    ** SNR min   (dB) = " << p.ebn0_min << std::endl;
    std::cout << "#    ** SNR max   (dB) = " << p.ebn0_max << std::endl;
    std::cout << "#    ** SNR step  (dB) = " << p.ebn0_step << std::endl;
    std::cout << "#" << std::endl;
}

void init_modules(const params& p, modules& m)
{
    m.source = std::unique_ptr<module::Source_random          <>>(new module::Source_random         <>(p.K));
    m.modem = std::unique_ptr<module::Modem_BPSK              <>>(new module::Modem_BPSK            <>(p.N));
    m.channel = std::unique_ptr<module::Channel_AWGN_LLR      <>>(new module::Channel_AWGN_LLR      <>(p.N, p.seed));
    m.monitor = std::unique_ptr<module::Monitor_BFER          <>>(new module::Monitor_BFER          <>(p.K, p.fe));

    //Encoder
    const tools::Interleaver_core_LTE<>& interleaverCoreLTE = tools::Interleaver_core_LTE<>(p.K);
    const module::Interleaver<>& interleaver = module::Interleaver<>(interleaverCoreLTE);
    module::Encoder<> enco_n = module::Encoder<>(p.K, p.N);
    module::Encoder<> enco_i = module::Encoder<>(p.K, p.N);
    m.encoder = std::unique_ptr<module::Encoder_turbo<>>(new module::Encoder_turbo<>(p.K, p.N, interleaver, enco_n, enco_i));

    // Decoder
    module::Interleaver<float, uint32_t> interleaver_inv = module::Interleaver<float, uint32_t>(interleaverCoreLTE);
    module::Decoder_SISO<> siso_n = module::Decoder_SISO<>(p.K, p.N);
    module::Decoder_SISO<> siso_i = module::Decoder_SISO<>(p.K, p.N);
    m.decoder = std::unique_ptr<module::Decoder_turbo<>>(new module::Decoder_turbo<>(p.K, p.N, p.numberOfIterations, interleaver_inv, siso_n, siso_i));
};

void init_buffers(const params& p, buffers& b)
{
    b.ref_bits = std::vector<int  >(p.K);
    b.enc_bits = std::vector<int  >(p.N);
    b.symbols = std::vector<float>(p.N);
    b.noisy_symbols = std::vector<float>(p.N);
    b.LLRs = std::vector<float>(p.N);
    b.dec_bits = std::vector<int  >(p.K);
}

void init_utils(const modules& m, utils& u)
{
    // create a sigma noise type
    u.noise = std::unique_ptr<tools::Sigma<>>(new tools::Sigma<>());
    // report the noise values (Es/N0 and Eb/N0)
    u.reporters.push_back(std::unique_ptr<tools::Reporter>(new tools::Reporter_noise<>(*u.noise)));
    // report the bit/frame error rates
    u.reporters.push_back(std::unique_ptr<tools::Reporter>(new tools::Reporter_BFER<>(*m.monitor)));
    // report the simulation throughputs
    u.reporters.push_back(std::unique_ptr<tools::Reporter>(new tools::Reporter_throughput<>(*m.monitor)));
    // create a terminal that will display the collected data from the reporters
    u.terminal = std::unique_ptr<tools::Terminal_std>(new tools::Terminal_std(u.reporters));
}

I hope I can receive some assistance regarding this issue. Thanks!

Regards, Dayana