mirror of
https://github.com/aicodix/code.git
synced 2026-04-27 14:30:36 +00:00
experimenting with ordered reliability message bits
wanted to see if this can be exploited for graceful degradation but the effect is minimal. order of reliability does not matter, but order of decoding of message bits gives a very marginal effect. This means that the probability of an errornous decode of a message bit at the beginning is less likely than at the end, as a single error will produce a cascade effect that breaks all later decoded bits.
This commit is contained in:
parent
55ddae0c6f
commit
ed4fe54ee9
1 changed files with 35 additions and 80 deletions
|
|
@ -15,7 +15,6 @@ Copyright 2020 Ahmet Inan <inan@aicodix.de>
|
||||||
#include "polar_helper.hh"
|
#include "polar_helper.hh"
|
||||||
#include "polar_decoder.hh"
|
#include "polar_decoder.hh"
|
||||||
#include "polar_encoder.hh"
|
#include "polar_encoder.hh"
|
||||||
#include "polar_freezer.hh"
|
|
||||||
#include "polar_sequence.hh"
|
#include "polar_sequence.hh"
|
||||||
|
|
||||||
bool get_bit(const uint32_t *bits, int idx)
|
bool get_bit(const uint32_t *bits, int idx)
|
||||||
|
|
@ -27,8 +26,8 @@ int main()
|
||||||
{
|
{
|
||||||
const int M = 20;
|
const int M = 20;
|
||||||
const int N = 1 << M;
|
const int N = 1 << M;
|
||||||
const bool systematic = true;
|
const bool systematic = false;
|
||||||
#if 1
|
#if 0
|
||||||
typedef int8_t code_type;
|
typedef int8_t code_type;
|
||||||
double SCALE = 2;
|
double SCALE = 2;
|
||||||
#else
|
#else
|
||||||
|
|
@ -44,29 +43,35 @@ int main()
|
||||||
auto codeword = new code_type[N];
|
auto codeword = new code_type[N];
|
||||||
auto temp = new code_type[N];
|
auto temp = new code_type[N];
|
||||||
|
|
||||||
double erasure_probability = 1. / 3.;
|
double erasure_probability = 1. / 2.;
|
||||||
int K = (1 - erasure_probability) * N;
|
int K = (1 - erasure_probability) * N;
|
||||||
double design_SNR = 10 * std::log10(-std::log(erasure_probability));
|
double design_SNR = 10 * std::log10(-std::log(erasure_probability));
|
||||||
std::cerr << "design SNR: " << design_SNR << std::endl;
|
std::cerr << "design SNR: " << design_SNR << std::endl;
|
||||||
double better_SNR = design_SNR + 0.5;//1.59175;
|
double better_SNR = design_SNR + 0.5;//1.59175;
|
||||||
std::cerr << "better SNR: " << better_SNR << std::endl;
|
std::cerr << "better SNR: " << better_SNR << std::endl;
|
||||||
double probability = std::exp(-pow(10.0, better_SNR / 10));
|
double probability = std::exp(-pow(10.0, better_SNR / 10));
|
||||||
if (1) {
|
auto sequence = new int[N];
|
||||||
auto freeze = new CODE::PolarCodeConst0<M>;
|
auto construct = new CODE::PolarSeqConst0<M>;
|
||||||
std::cerr << "sizeof(PolarCodeConst0<M>) = " << sizeof(CODE::PolarCodeConst0<M>) << std::endl;
|
std::cerr << "sizeof(PolarSeqConst0<M>) = " << sizeof(CODE::PolarSeqConst0<M>) << std::endl;
|
||||||
(*freeze)(frozen, M, K, probability);
|
(*construct)(sequence, M, probability);
|
||||||
delete freeze;
|
delete construct;
|
||||||
|
for (int i = 0; i < N / 32; ++i)
|
||||||
|
frozen[i] = 0;
|
||||||
|
for (int i = 0; i < N - K; ++i)
|
||||||
|
frozen[sequence[i]/32] |= 1 << (sequence[i]%32);
|
||||||
|
const int segments = 4;
|
||||||
|
auto segment_mapping = new char[N];
|
||||||
|
for (int i = 0; i < N; ++i)
|
||||||
|
segment_mapping[i] = -1;
|
||||||
|
if (0) {
|
||||||
|
for (int i = 0; i < K; ++i)
|
||||||
|
segment_mapping[sequence[N-1-i]] = std::min(i / (K / segments), segments - 1);
|
||||||
|
for (int i = 0, j = 0; i < N; ++i)
|
||||||
|
if (segment_mapping[i] >= 0)
|
||||||
|
segment_mapping[j++] = segment_mapping[i];
|
||||||
} else {
|
} else {
|
||||||
auto sequence = new int[N];
|
for (int i = 0; i < K; ++i)
|
||||||
auto construct = new CODE::PolarSeqConst0<M>;
|
segment_mapping[i] = std::min(i / (K / segments), segments - 1);
|
||||||
std::cerr << "sizeof(PolarSeqConst0<M>) = " << sizeof(CODE::PolarSeqConst0<M>) << std::endl;
|
|
||||||
(*construct)(sequence, M, probability);
|
|
||||||
delete construct;
|
|
||||||
for (int i = 0; i < N / 32; ++i)
|
|
||||||
frozen[i] = 0;
|
|
||||||
for (int i = 0; i < N - K; ++i)
|
|
||||||
frozen[sequence[i]/32] |= 1 << (sequence[i]%32);
|
|
||||||
delete[] sequence;
|
|
||||||
}
|
}
|
||||||
std::cerr << "Polar(" << N << ", " << K << ")" << std::endl;
|
std::cerr << "Polar(" << N << ", " << K << ")" << std::endl;
|
||||||
auto message = new code_type[K];
|
auto message = new code_type[K];
|
||||||
|
|
@ -74,15 +79,10 @@ int main()
|
||||||
std::cerr << "sizeof(PolarDecoder<code_type, M>) = " << sizeof(CODE::PolarDecoder<code_type, M>) << std::endl;
|
std::cerr << "sizeof(PolarDecoder<code_type, M>) = " << sizeof(CODE::PolarDecoder<code_type, M>) << std::endl;
|
||||||
auto decode = new CODE::PolarDecoder<code_type, M>;
|
auto decode = new CODE::PolarDecoder<code_type, M>;
|
||||||
|
|
||||||
auto orig = new code_type[N];
|
|
||||||
auto noisy = new code_type[N];
|
|
||||||
auto symb = new double[N];
|
auto symb = new double[N];
|
||||||
double low_SNR = std::floor(design_SNR-3);
|
double low_SNR = std::floor(design_SNR-3);
|
||||||
double high_SNR = std::ceil(design_SNR+5);
|
double high_SNR = std::ceil(design_SNR+.5);
|
||||||
double min_SNR = high_SNR, max_mbs = 0;
|
for (double SNR = low_SNR; SNR <= high_SNR; SNR += 0.1) {
|
||||||
int count = 0;
|
|
||||||
std::cerr << "SNR BER Mbit/s Eb/N0" << std::endl;
|
|
||||||
for (double SNR = low_SNR; count <= 3 && SNR <= high_SNR; SNR += 0.1, ++count) {
|
|
||||||
//double mean_signal = 0;
|
//double mean_signal = 0;
|
||||||
double sigma_signal = 1;
|
double sigma_signal = 1;
|
||||||
double mean_noise = 0;
|
double mean_noise = 0;
|
||||||
|
|
@ -91,13 +91,9 @@ int main()
|
||||||
typedef std::normal_distribution<double> normal;
|
typedef std::normal_distribution<double> normal;
|
||||||
auto awgn = std::bind(normal(mean_noise, sigma_noise), generator(rd()));
|
auto awgn = std::bind(normal(mean_noise, sigma_noise), generator(rd()));
|
||||||
|
|
||||||
int64_t awgn_errors = 0;
|
int64_t segment_errors[segments] = { 0 };
|
||||||
int64_t quantization_erasures = 0;
|
|
||||||
int64_t uncorrected_errors = 0;
|
|
||||||
int64_t ambiguity_erasures = 0;
|
|
||||||
double avg_mbs = 0;
|
|
||||||
int64_t loops = 0;
|
int64_t loops = 0;
|
||||||
while (uncorrected_errors < 1000 && ++loops < 100) {
|
while (segment_errors[0] < 100000 && ++loops < 10000) {
|
||||||
for (int i = 0; i < K; ++i)
|
for (int i = 0; i < K; ++i)
|
||||||
message[i] = 1 - 2 * data();
|
message[i] = 1 - 2 * data();
|
||||||
|
|
||||||
|
|
@ -112,9 +108,6 @@ int main()
|
||||||
encode(codeword, message, frozen, M);
|
encode(codeword, message, frozen, M);
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
orig[i] = codeword[i];
|
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
symb[i] = codeword[i];
|
symb[i] = codeword[i];
|
||||||
|
|
||||||
|
|
@ -128,15 +121,7 @@ int main()
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
codeword[i] = CODE::PolarHelper<code_type>::quant(fact * symb[i]);
|
codeword[i] = CODE::PolarHelper<code_type>::quant(fact * symb[i]);
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
noisy[i] = codeword[i];
|
|
||||||
|
|
||||||
auto start = std::chrono::system_clock::now();
|
|
||||||
(*decode)(decoded, codeword, frozen, M);
|
(*decode)(decoded, codeword, frozen, M);
|
||||||
auto end = std::chrono::system_clock::now();
|
|
||||||
auto usec = std::chrono::duration_cast<std::chrono::microseconds>(end - start);
|
|
||||||
double mbs = (double)K / usec.count();
|
|
||||||
avg_mbs += mbs;
|
|
||||||
|
|
||||||
if (systematic) {
|
if (systematic) {
|
||||||
CODE::PolarEncoder<code_type> encode;
|
CODE::PolarEncoder<code_type> encode;
|
||||||
|
|
@ -146,46 +131,16 @@ int main()
|
||||||
decoded[j++] = temp[i];
|
decoded[j++] = temp[i];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
awgn_errors += noisy[i] * (orig[i] < 0);
|
|
||||||
for (int i = 0; i < N; ++i)
|
|
||||||
quantization_erasures += !noisy[i];
|
|
||||||
for (int i = 0; i < K; ++i)
|
for (int i = 0; i < K; ++i)
|
||||||
uncorrected_errors += decoded[i] * message[i] <= 0;
|
segment_errors[(int)segment_mapping[i]] += decoded[i] * message[i] <= 0;
|
||||||
for (int i = 0; i < K; ++i)
|
|
||||||
ambiguity_erasures += !decoded[i];
|
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < segments - 1; ++i)
|
||||||
|
segment_errors[i + 1] += segment_errors[i];
|
||||||
|
|
||||||
avg_mbs /= loops;
|
std::cout << SNR;
|
||||||
|
for (int i = 0; i < segments; ++i)
|
||||||
max_mbs = std::max(max_mbs, avg_mbs);
|
std::cout << " " << double(segments * segment_errors[i]) / double(K * loops * (i + 1));
|
||||||
double bit_error_rate = (double)uncorrected_errors / (double)(K * loops);
|
std::cout << std::endl;
|
||||||
if (!uncorrected_errors)
|
|
||||||
min_SNR = std::min(min_SNR, SNR);
|
|
||||||
else
|
|
||||||
count = 0;
|
|
||||||
|
|
||||||
int MOD_BITS = 1; // BPSK
|
|
||||||
double code_rate = (double)K / (double)N;
|
|
||||||
double spectral_efficiency = code_rate * MOD_BITS;
|
|
||||||
double EbN0 = 10 * std::log10(sigma_signal * sigma_signal / (spectral_efficiency * 2 * sigma_noise * sigma_noise));
|
|
||||||
|
|
||||||
if (0) {
|
|
||||||
std::cerr << SNR << " Es/N0 => AWGN with standard deviation of " << sigma_noise << " and mean " << mean_noise << std::endl;
|
|
||||||
std::cerr << EbN0 << " Eb/N0, using spectral efficiency of " << spectral_efficiency << " from " << code_rate << " code rate and " << MOD_BITS << " bits per symbol." << std::endl;
|
|
||||||
std::cerr << awgn_errors << " errors caused by AWGN." << std::endl;
|
|
||||||
std::cerr << quantization_erasures << " erasures caused by quantization." << std::endl;
|
|
||||||
std::cerr << uncorrected_errors << " errors uncorrected." << std::endl;
|
|
||||||
std::cerr << ambiguity_erasures << " ambiguity erasures." << std::endl;
|
|
||||||
std::cerr << bit_error_rate << " bit error rate." << std::endl;
|
|
||||||
std::cerr << avg_mbs << " megabit per second." << std::endl;
|
|
||||||
} else {
|
|
||||||
std::cout << SNR << " " << bit_error_rate << " " << avg_mbs << " " << EbN0 << std::endl;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
std::cerr << "QEF at: " << min_SNR << " SNR, speed: " << max_mbs << " Mb/s." << std::endl;
|
|
||||||
double QEF_SNR = design_SNR + 0.2;
|
|
||||||
assert(min_SNR < QEF_SNR);
|
|
||||||
std::cerr << "Polar regression test passed!" << std::endl;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue