33 #define INFINITY std::numeric_limits<double>::infinity()
38 void SISO::gen_nsctrellis(
void)
47 int mem_len = gen.cols()-1;
53 nsctrellis.stateNb = (1<<mem_len);
54 nsctrellis.output =
new double[nsctrellis.stateNb*2*r];
55 nsctrellis.nextState =
new int[nsctrellis.stateNb*2];
56 nsctrellis.prevState =
new int[nsctrellis.stateNb*2];
57 nsctrellis.input =
new int[nsctrellis.stateNb*2];
59 itpp::bvec enc_mem(mem_len);
61 #pragma omp parallel for private(n,k,j,p,enc_mem,out)
62 for (n=0; n<nsctrellis.stateNb; n++)
70 out = inputs[k]*gen(j,0);
71 for (p=1; p<=mem_len; p++)
73 out ^= (enc_mem[p-1]*gen(j,p));
75 nsctrellis.output[n+k*nsctrellis.stateNb+j*nsctrellis.stateNb*2] = double(out);
79 for (j=(mem_len-1); j>0; j--)
81 enc_mem[j] = enc_mem[j-1];
85 enc_mem[0] = inputs[k];
86 nsctrellis.nextState[n+k*nsctrellis.stateNb] =
itpp::bin2dec(enc_mem,
true);
90 #pragma omp parallel for private(n,k,j,index)
91 for (j=0; j<nsctrellis.stateNb; j++)
94 for (n=0; n<nsctrellis.stateNb; n++)
98 if (nsctrellis.nextState[n+k*nsctrellis.stateNb]==j)
100 nsctrellis.prevState[j+index*nsctrellis.stateNb] = n;
101 nsctrellis.input[j+index*nsctrellis.stateNb] = k;
109 void SISO::nsc_logMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
const itpp::vec &intrinsic_coded,
const itpp::vec &apriori_data)
119 int N = apriori_data.length();
120 int Nc = scrambler_pattern.length();
123 register int n,k,m,mp,j,i;
135 double* A =
new double[nsctrellis.stateNb*(N+1)];
136 double* B =
new double[nsctrellis.stateNb*(N+1)];
138 B[N*nsctrellis.stateNb] = 0;
139 sum = (tail?-INFINITY:0);
140 #pragma omp parallel for private(n)
141 for (n=1; n<nsctrellis.stateNb; n++)
144 B[n+N*nsctrellis.stateNb] =
sum;
147 #pragma omp parallel sections private(n,sum,m,k,i,j,C)
150 for (n=1; n<(N+1); n++)
153 for (m=0; m<nsctrellis.stateNb; m++)
157 pstates[k] = nsctrellis.prevState[m+nsctrellis.stateNb*k];
158 inputs[k] = nsctrellis.input[m+nsctrellis.stateNb*k];
159 C[k] = (inputs[k]?apriori_data[n-1]:0);
167 C[i] += nsctrellis.output[pstates[i]+inputs[i]*nsctrellis.stateNb+k*nsctrellis.stateNb*2]*(1-2*double(scrambler_pattern[j]))*intrinsic_coded[j+k*Nc+(n-1)*Nc*r];
171 A[m+n*nsctrellis.stateNb] =
itpp::log_add(A[pstates[0]+(n-1)*nsctrellis.stateNb]+C[0], A[pstates[1]+(n-1)*nsctrellis.stateNb]+C[1]);
172 sum +=
std::exp(A[m+n*nsctrellis.stateNb]);
180 for (m=0; m<nsctrellis.stateNb; m++)
182 A[m+n*nsctrellis.stateNb] -=
sum;
188 for (n=N-1; n>=0; n--)
191 for (m=0; m<nsctrellis.stateNb; m++)
195 nstates[k] = nsctrellis.nextState[m+k*nsctrellis.stateNb];
196 C[k] = (k?apriori_data[n]:0);
204 C[i] += nsctrellis.output[m+i*nsctrellis.stateNb+k*nsctrellis.stateNb*2]*(1-2*double(scrambler_pattern[j]))*intrinsic_coded[j+k*Nc+n*Nc*r];
208 B[m+n*nsctrellis.stateNb] =
itpp::log_add(B[nstates[0]+(n+1)*nsctrellis.stateNb]+C[0], B[nstates[1]+(n+1)*nsctrellis.stateNb]+C[1]);
209 sum +=
std::exp(B[m+n*nsctrellis.stateNb]);
217 for (m=0; m<nsctrellis.stateNb; m++)
219 B[m+n*nsctrellis.stateNb] -=
sum;
225 extrinsic_data.set_size(N);
226 #pragma omp parallel for private(n,k,sum,sumbis)
227 for (n=1; n<(N+1); n++)
231 for (k=0; k<(nsctrellis.stateNb/2); k++)
233 sum +=
std::exp(A[k+(nsctrellis.stateNb/2)+n*nsctrellis.stateNb]+B[k+(nsctrellis.stateNb/2)+n*nsctrellis.stateNb]);
234 sumbis +=
std::exp(A[k+n*nsctrellis.stateNb]+B[k+n*nsctrellis.stateNb]);
236 extrinsic_data[n-1] =
std::log(sum/sumbis)-apriori_data[n-1];
240 double *sum0 =
new double[r];
241 double *sum1 =
new double[r];
242 extrinsic_coded.set_size(N*Nc*r);
250 for (mp=0; mp<nsctrellis.stateNb; mp++)
254 m = nsctrellis.nextState[mp+i*nsctrellis.stateNb];
256 index = (m>=(nsctrellis.stateNb/2));
257 C[0] = (index?apriori_data[n]:0);
262 C[0] += nsctrellis.output[mp+index*nsctrellis.stateNb+k*nsctrellis.stateNb*2]*(1-2*double(scrambler_pattern[j]))*intrinsic_coded[j+k*Nc+n*Nc*r];
265 C[1] = A[mp+n*nsctrellis.stateNb]+C[0]+B[m+(n+1)*nsctrellis.stateNb];
269 if (nsctrellis.output[mp+index*nsctrellis.stateNb+k*nsctrellis.stateNb*2])
284 index = j+k*Nc+n*r*Nc;
285 extrinsic_coded[index] = (1-2*double(scrambler_pattern[j]))*
std::log(sum1[k]/sum0[k])-intrinsic_coded[index];
291 delete[] nsctrellis.output;
292 delete[] nsctrellis.nextState;
293 delete[] nsctrellis.prevState;
294 delete[] nsctrellis.input;
301 void SISO::nsc_maxlogMAP(itpp::vec &extrinsic_coded, itpp::vec &extrinsic_data,
const itpp::vec &intrinsic_coded,
const itpp::vec &apriori_data)
311 int N = apriori_data.length();
312 int Nc = scrambler_pattern.length();
315 register int n,k,m,mp,j,i;
327 double* A =
new double[nsctrellis.stateNb*(N+1)];
328 double* B =
new double[nsctrellis.stateNb*(N+1)];
330 B[N*nsctrellis.stateNb] = 0;
331 sum = (tail?-INFINITY:0);
332 #pragma omp parallel for private(n)
333 for (n=1; n<nsctrellis.stateNb; n++)
336 B[n+N*nsctrellis.stateNb] =
sum;
340 #pragma omp parallel sections private(n,sum,m,k,i,j,C)
342 for (n=1; n<(N+1); n++)
345 for (m=0; m<nsctrellis.stateNb; m++)
349 pstates[k] = nsctrellis.prevState[m+nsctrellis.stateNb*k];
350 inputs[k] = nsctrellis.input[m+nsctrellis.stateNb*k];
351 C[k] = (inputs[k]?apriori_data[n-1]:0);
359 C[i] += nsctrellis.output[pstates[i]+inputs[i]*nsctrellis.stateNb+k*nsctrellis.stateNb*2]*(1-2*double(scrambler_pattern[j]))*intrinsic_coded[j+k*Nc+(n-1)*Nc*r];
363 A[m+n*nsctrellis.stateNb] =
std::max(A[pstates[0]+(n-1)*nsctrellis.stateNb]+C[0], A[pstates[1]+(n-1)*nsctrellis.stateNb]+C[1]);
364 sum =
std::max(sum, A[m+n*nsctrellis.stateNb]);
371 for (m=0; m<nsctrellis.stateNb; m++)
373 A[m+n*nsctrellis.stateNb] -=
sum;
379 for (n=N-1; n>=0; n--)
382 for (m=0; m<nsctrellis.stateNb; m++)
386 nstates[k] = nsctrellis.nextState[m+k*nsctrellis.stateNb];
387 C[k] = (k?apriori_data[n]:0);
395 C[i] += nsctrellis.output[m+i*nsctrellis.stateNb+k*nsctrellis.stateNb*2]*(1-2*double(scrambler_pattern[j]))*intrinsic_coded[j+k*Nc+n*Nc*r];
399 B[m+n*nsctrellis.stateNb] =
std::max(B[nstates[0]+(n+1)*nsctrellis.stateNb]+C[0], B[nstates[1]+(n+1)*nsctrellis.stateNb]+C[1]);
400 sum =
std::max(sum, B[m+n*nsctrellis.stateNb]);
407 for (m=0; m<nsctrellis.stateNb; m++)
409 B[m+n*nsctrellis.stateNb] -=
sum;
415 extrinsic_data.set_size(N);
416 #pragma omp parallel for private(n,k,sum,sumbis)
417 for (n=1; n<(N+1); n++)
421 for (k=0; k<(nsctrellis.stateNb/2); k++)
423 sum =
std::max(sum, A[k+(nsctrellis.stateNb/2)+n*nsctrellis.stateNb]+B[k+(nsctrellis.stateNb/2)+n*nsctrellis.stateNb]);
424 sumbis =
std::max(sumbis, A[k+n*nsctrellis.stateNb]+B[k+n*nsctrellis.stateNb]);
426 extrinsic_data[n-1] = (sum-sumbis)-apriori_data[n-1];
430 double *sum0 =
new double[r];
431 double *sum1 =
new double[r];
432 extrinsic_coded.set_size(N*Nc*r);
440 for (mp=0; mp<nsctrellis.stateNb; mp++)
444 m = nsctrellis.nextState[mp+i*nsctrellis.stateNb];
446 index = (m>=(nsctrellis.stateNb/2));
447 C[0] = (index?apriori_data[n]:0);
452 C[0] += nsctrellis.output[mp+index*nsctrellis.stateNb+k*nsctrellis.stateNb*2]*(1-2*double(scrambler_pattern[j]))*intrinsic_coded[j+k*Nc+n*Nc*r];
455 C[1] = A[mp+n*nsctrellis.stateNb]+C[0]+B[m+(n+1)*nsctrellis.stateNb];
459 if (nsctrellis.output[mp+index*nsctrellis.stateNb+k*nsctrellis.stateNb*2])
474 index = j+k*Nc+n*r*Nc;
475 extrinsic_coded[index] = (1-2*double(scrambler_pattern[j]))*(sum1[k]-sum0[k])-intrinsic_coded[index];
481 delete[] nsctrellis.output;
482 delete[] nsctrellis.nextState;
483 delete[] nsctrellis.prevState;
484 delete[] nsctrellis.input;