260 lines
7.9 KiB
C
260 lines
7.9 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <math.h>
|
|
#include <stdint.h>
|
|
|
|
void get_PC_bit_pattern(uint16_t Q_N_length, uint16_t n_PC, uint8_t n_PC_wm, uint16_t* Q_N, uint8_t* info_bit_pattern, uint8_t** PC_bit_pattern)
|
|
{
|
|
// GET_PC_BIT_PATTERN Obtain the Parity Check (PC) bit pattern,
|
|
// according to Section 5.3.1.2 of 3GPP TS 38.212
|
|
//
|
|
// info_bit_pattern should be a vector comprising N number of logical
|
|
// elements, each having the value true or false. The number of elements
|
|
// in info_bit_pattern having the value true should be I, where
|
|
// I = A+P+n_PC. These elements having the value true identify the
|
|
// positions of the information, CRC and PC bits within the input to the
|
|
// polar encoder kernal.
|
|
//
|
|
// Q_N should be a row vector comprising N number of unique integers in the
|
|
// range 1 to N. Each successive element of Q_N provides the index of the
|
|
// next most reliable input to the polar encoder kernal, where the first
|
|
// element of Q_N gives the index of the least reliable bit and the last
|
|
// element gives the index of the most reliable bit.
|
|
//
|
|
// n_PC should be an integer scalar. It specifies the number of PC bits to
|
|
// use, where n_PC should be no greater than I.
|
|
//
|
|
// n_PC_wm should be an integer scalar. It specifies the number of PC bits
|
|
// that occupy some of the most reliable positions at the input to the
|
|
// polar encoder kernal. The remaining n_PC-n_PC_wm PC bits occupy some of
|
|
// the least reliable positions at the input to the polar encoder kernal.
|
|
// n_PC_wm should be no greater than n_PC.
|
|
//
|
|
// PC_bit_pattern will be a vector comprising N number of logical
|
|
// elements, each having the value true or false. The number of elements
|
|
// in PC_bit_pattern having the value true will be n_PC.
|
|
// These elements having the value true identify the positions of the
|
|
// PC bits within the input to the polar encoder kernal.
|
|
|
|
//N = length(info_bit_pattern); -> Q_N_length
|
|
//I = sum(info_bit_pattern);
|
|
int totInfoBit =0;
|
|
int j,i;
|
|
for (j=0; j<Q_N_length; j++)
|
|
{
|
|
if(info_bit_pattern[j])
|
|
totInfoBit++;
|
|
}
|
|
|
|
if (n_PC > totInfoBit)
|
|
{
|
|
fprintf(stderr, "n_PC should be no greater than totInfoBit.");
|
|
exit(-1);
|
|
}
|
|
|
|
if (n_PC_wm > n_PC)
|
|
{
|
|
fprintf(stderr, "n_PC_wm should be no greater than n_PC.");
|
|
exit(-1);
|
|
}
|
|
//Q_I = 1:N;
|
|
int* Q_I = (int*) malloc(sizeof(int)*Q_N_length);
|
|
if (Q_I == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
for (j=0; j<Q_N_length; j++)
|
|
{
|
|
Q_I[j]=j+1;
|
|
}
|
|
|
|
//Q_N_I = intersect(Q_N, Q_I(info_bit_pattern), 'stable');
|
|
int Q_N_I_length=0;
|
|
int* Q_N_common = (int*) malloc(sizeof(int)*Q_N_length);
|
|
if (Q_N_common == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
|
|
for (j=0; j<Q_N_length; j++) //init
|
|
{
|
|
Q_N_common[j]=0;
|
|
}
|
|
|
|
for (j=0; j<Q_N_length; j++) //look in Q_I
|
|
{
|
|
if(info_bit_pattern[j])
|
|
{
|
|
//Q_I(info_bit_pattern)
|
|
for (i=0; i<Q_N_length; i++) //look in Q_N
|
|
{
|
|
if(Q_N[i]+1==Q_I[j])
|
|
{
|
|
Q_N_common[i]=1;
|
|
Q_N_I_length++;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
free(Q_I);
|
|
|
|
int* Q_N_I = (int*) malloc(sizeof(int)*Q_N_I_length);
|
|
if (Q_N_I == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
i=0;
|
|
for(j=0; j<Q_N_length; j++)
|
|
{
|
|
if(Q_N_common[j])
|
|
{
|
|
Q_N_I[i]=Q_N[j]+1;
|
|
i++;
|
|
}
|
|
}
|
|
|
|
free(Q_N_common);
|
|
|
|
//int G_N = get_G_N(N);
|
|
//int w_g = sum(G_N,2);
|
|
//useless, I do this
|
|
int* w_g = (int*) malloc(sizeof(int)*Q_N_length);
|
|
if (w_g == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
w_g[0]=1;
|
|
w_g[1]=2;
|
|
int counter=2;
|
|
int n = log2(Q_N_length);
|
|
|
|
for(i=0; i<n-1; i++) //n=log2(N)
|
|
{
|
|
for(j=0; j<counter; j++)
|
|
{
|
|
w_g[counter+j]=w_g[j]*2;
|
|
}
|
|
counter = counter*2;
|
|
}
|
|
|
|
//Q_tilde_N_I = Q_N_I(n_PC+1:end); % This is what it says in TS 38.212
|
|
int* Q_tilde_N_I = (int*) malloc(sizeof(int)*(Q_N_I_length-n_PC));
|
|
if (Q_tilde_N_I == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
int* Q_tilde_N_I_flip = (int*) malloc(sizeof(int)*(Q_N_I_length-n_PC));
|
|
if (Q_tilde_N_I_flip == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
for (i=0; i<Q_N_I_length-n_PC; i++)
|
|
{
|
|
Q_tilde_N_I[i]=Q_N_I[n_PC+i];
|
|
//Q_tilde_N_I_flip = fliplr(Q_tilde_N_I);
|
|
Q_tilde_N_I_flip[Q_N_I_length-n_PC-i-1] = Q_tilde_N_I[i];
|
|
}
|
|
//%Q_tilde_N_I = Q_N_I(n_PC-n_PC_wm+1:end); % I think that this would be slightly more elegant
|
|
|
|
//[w_g_sorted, indices] = sort(w_g(Q_tilde_N_I_flip));
|
|
int* w_g_sorted = (int*) malloc(sizeof(int)*(Q_N_I_length-n_PC));
|
|
if (w_g_sorted == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
int* indices = (int*) malloc(sizeof(int)*(Q_N_I_length-n_PC));
|
|
if (indices == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
for (i=0; i<Q_N_I_length-n_PC; i++)
|
|
{
|
|
w_g_sorted[i]=w_g[Q_tilde_N_I_flip[i]-1]; // w_g(Q_tilde_N_I_flip), yet to sort
|
|
indices[i] = i;
|
|
}
|
|
free(Q_tilde_N_I);
|
|
free(w_g);
|
|
|
|
//bubble sort
|
|
int tempToSwap=0;
|
|
for (i = 0; i < (Q_N_I_length-n_PC)-1; i++)
|
|
{
|
|
for (j = 0; j < (Q_N_I_length-n_PC)-i-1; j++)
|
|
{
|
|
if (w_g_sorted[j] > w_g_sorted[j+1]) //then swap
|
|
{
|
|
tempToSwap = w_g_sorted[j];
|
|
w_g_sorted[j] = w_g_sorted[j+1];
|
|
w_g_sorted[j+1] = tempToSwap;
|
|
|
|
tempToSwap = indices[j];
|
|
indices[j] = indices[j+1];
|
|
indices[j+1] = tempToSwap;
|
|
}
|
|
}
|
|
}
|
|
free(w_g_sorted);
|
|
|
|
//Q_N_PC = [Q_N_I(1:n_PC-n_PC_wm), Q_tilde_N_I_flip(indices(1:n_PC_wm))];
|
|
int* Q_N_PC = (int*) malloc(sizeof(int)*(n_PC));
|
|
if (Q_N_PC == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
|
|
for (i=0; i<n_PC-n_PC_wm; i++)
|
|
{
|
|
Q_N_PC[i]=Q_N_I[i]; //Q_N_PC = [Q_N_I(1:n_PC-n_PC_wm), ...
|
|
}
|
|
free(Q_N_I);
|
|
|
|
for (i=0; i<n_PC_wm; i++)
|
|
{
|
|
Q_N_PC[n_PC-n_PC_wm+i] = Q_tilde_N_I_flip[indices[i]];//... Q_tilde_N_I_flip(indices(1:n_PC_wm))];
|
|
}
|
|
free(Q_tilde_N_I_flip);
|
|
free(indices);
|
|
|
|
//PC_bit_pattern = false(1,N);
|
|
//PC_bit_pattern(Q_N_PC) = true;
|
|
*PC_bit_pattern = (uint8_t*) malloc(sizeof(uint8_t)*(Q_N_length));
|
|
if (*PC_bit_pattern == NULL)
|
|
{
|
|
fprintf(stderr, "malloc failed\n");
|
|
exit(-1);
|
|
}
|
|
|
|
for (i=0; i<Q_N_length; i++)
|
|
{
|
|
(*PC_bit_pattern)[i]=0;
|
|
for (j=0; j<n_PC; j++)
|
|
{
|
|
if (Q_N_PC[j]-1==i)
|
|
{
|
|
(*PC_bit_pattern)[i]=1;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
//free(Q_I);
|
|
//free(Q_N_common);
|
|
//free(Q_N_I);
|
|
//free(w_g);
|
|
//free(Q_tilde_N_I);
|
|
//free(Q_tilde_N_I_flip);
|
|
//free(w_g_sorted);
|
|
//free(indices);
|
|
free(Q_N_PC);
|
|
}
|