Наконец то появилось время подтянуть себя в вопросах реализации кодов с вероятностным декодированием. Первая задача реализация DVB-RCS/WiMAX CTC кодера на ПЛИС, часть проекта будет выложен в опенсорс. Решил создать отдельную тему для обсуждения вопросов по реализации
После штудирования литературы и примеров сорцов в сети возникла часть вопросов, на которые не хватает ума/настойчивости найти ответы:
1. Для DVB-RCS оговорены выкалывания под скорости кодирования 1/3, 2/5, 1/2, 2/3, 3/4, 4/5, 6/7. Почему не определены скорости 5/6 (удивляет "дырка" между скоростями 4/5 и 6/7) и 7/8? При этому матрица выкалывания под эти скорости возможна.
2. Полиномы RCS для Wimax и DVB одинаковые, но перемежители разные. Это сделано по политическим причинам или это результат "улучшения" характеристик декодера в процессе разработки стандарта?
3. В сверточных бинарных кодах, свойство tail-bitting используется при декодировании: В одной доке нашел что дополняют принятую последовательность вначале и в конце, затем декодируют по витерби и выкусывают нужное. В примере матлаба вообще составляют два фрейма, декодируют один за другим, потом из двух декодированных собирают один результат. Никакого намека на похожие операции в доках на турбокоды не нашел. Почему в алгоритмах SOVA/MAP/... для турбокодов это не делается?
4. По tail-bitting нашел в доках только то, что особым образом инициализируются рекурсия прямой и обратной метрики на первой итерации, а на всех остальных значения между итерациями сохраняются. Но
в сорцах от CML цикл по итерациям выглядит так :
Код
for it = 1:max_iterations
inx1 = X + inner_extr;
[outx1, outz1]=DuobinaryCRSCDecode( inx1, inz1, poly, decoder_type);
llrx1 = outx1 - inner_extr;
inx2(1:3*N) = llrx1( code_interleaver_GF4);
[outx2, outz2, out_info]=DuobinaryCRSCDecode( inx2, inz2, poly, decoder_type);
detected_data(code_interleaver.info_intl) = (out_info>0)+0;
errors(it)= sum( sum(abs(detected_data - data)));
if (errors(it) == 0)
break;
else
inner_extr(code_interleaver_GF4) = outx2 - inx2;
end
end
inx1 = X + inner_extr;
[outx1, outz1]=DuobinaryCRSCDecode( inx1, inz1, poly, decoder_type);
llrx1 = outx1 - inner_extr;
inx2(1:3*N) = llrx1( code_interleaver_GF4);
[outx2, outz2, out_info]=DuobinaryCRSCDecode( inx2, inz2, poly, decoder_type);
detected_data(code_interleaver.info_intl) = (out_info>0)+0;
errors(it)= sum( sum(abs(detected_data - data)));
if (errors(it) == 0)
break;
else
inner_extr(code_interleaver_GF4) = outx2 - inx2;
end
end
Т.е. видно что последовательные вызовы функции DuobinaryCRSCDecode между собой не обмениваются этой информацией. А в самих функциях
Код
// initialization for CRSC code
for (i =0; i< max_states; i++)
{
alpha[i][0] = 0;
beta[i][len] = 0;
}
for (i =0; i< max_states; i++)
{
alpha[i][0] = 0;
beta[i][len] = 0;
}
Т.е. не используется даже свойство одинакового начального состояния. Более того, в алгоритмах с оконным расчетом обратной рекурсии тоже забивают на свойство tail-bitting. Так насколько это важно и почему во всех доках настойчиво пишут кодировать данные 2 раза для определения состояния инициализации?
5. В алгоритмах, наследованных от Log-MAP метрика ветки считается как сумма корреляций метрик приемных битов с выходными битами решетки : gamma(Sk-1, S) = Lapri + (ys0*xs0 + ys1*xs1 + yp0*xp0 + yp1*xp1). При этом предполагается что y - надежность принятого символа , x = -1/1 выходной(переданный) бит. В сорцах от CML это место выглядит так :
Код
int m_input = 2; // 2 input bits,
int max_states = 8; // total state numbers
int M_input = 1<<m_input;
int i, j, max_trellis = M_input * max_states;
.......
for (j = 0; j< max_trellis; j++)
{
temp_input = j%M_input;
temp_output = trellis_out[j];
gamma[j] = ( temp_input ==0)? 0: inx[ (temp_input -1)+ i*llr_height ]; //llr for systematic symbol
gamma[j] += ( temp_output ==0)? 0: inz[ (temp_output -1)+ i*llr_height ]; //llr for parity symbol
}
int max_states = 8; // total state numbers
int M_input = 1<<m_input;
int i, j, max_trellis = M_input * max_states;
.......
for (j = 0; j< max_trellis; j++)
{
temp_input = j%M_input;
temp_output = trellis_out[j];
gamma[j] = ( temp_input ==0)? 0: inx[ (temp_input -1)+ i*llr_height ]; //llr for systematic symbol
gamma[j] += ( temp_output ==0)? 0: inz[ (temp_output -1)+ i*llr_height ]; //llr for parity symbol
}
Насколько я понимаю Си gamma[j] = ( temp_input ==0)? 0: inx[ (temp_input -1)+ i*llr_height ] - берет надежности символов кроме нулевого. Диапазон изменения temp_input = 0..3 или в битах 00/01/10/11. Вот этот момент мне совсем не понятен.
Пока всё
