32 #define INFINITY std::numeric_limits<double>::infinity()
37 void SISO::gen_chtrellis(
void)
41 int mem_len = impulse_response.cols()-1;
42 int p_order = prec_gen.length()-1;
46 double inputs[] = {1.0,-1.0};
51 int equiv_ch_mem_len =
std::max(mem_len, p_order);
52 chtrellis.stateNb = (1<<equiv_ch_mem_len);
53 chtrellis.output =
new double[2*chtrellis.stateNb];
54 chtrellis.nextState =
new int[2*chtrellis.stateNb];
55 chtrellis.prevState =
new int[2*chtrellis.stateNb];
56 chtrellis.input =
new int[2*chtrellis.stateNb];
59 itpp::ivec enc_mem(equiv_ch_mem_len);
60 #pragma omp parallel for private(n,enc_mem,k,feedback,j)
61 for (n=0; n<chtrellis.stateNb; n++)
67 feedback[k] = inputs[k];
68 for (j=1; j<=p_order; j++)
70 feedback[k] *= enc_mem[j-1];
71 chtrellis.output[n+k*chtrellis.stateNb] = feedback[k]*impulse_response(0,0);
72 for (j=1; j<=mem_len; j++)
73 chtrellis.output[n+k*chtrellis.stateNb] += (enc_mem[j-1]*impulse_response(0,j));
76 for (j=(equiv_ch_mem_len-1); j>0; j--)
77 enc_mem[j] = enc_mem[j-1];
80 enc_mem[0] = int(feedback[k]);
85 #pragma omp parallel for private(j,index,n,k)
86 for (j=0; j<chtrellis.stateNb; j++)
89 for (n=0; n<chtrellis.stateNb; n++)
93 if (chtrellis.nextState[n+k*chtrellis.stateNb]==j)
95 chtrellis.prevState[j+index*chtrellis.stateNb] = n;
96 chtrellis.input[j+index*chtrellis.stateNb] = k;
104 void SISO::equalizer_logMAP(itpp::vec &extrinsic_data,
const itpp::vec &rec_sig,
const itpp::vec &apriori_data)
112 int N = rec_sig.length();
126 double* A =
new double[chtrellis.stateNb*(N+1)];
127 double* B =
new double[chtrellis.stateNb*(N+1)];
129 B[N*chtrellis.stateNb] = 0;
130 sum = (tail?-INFINITY:0);
131 #pragma omp parallel for private(n)
132 for (n=1; n<chtrellis.stateNb; n++)
135 B[n+N*chtrellis.stateNb] =
sum;
138 #pragma omp parallel sections private(n,sum,m,k,C)
144 for (m=0; m<chtrellis.stateNb; m++)
148 pstates[k] = chtrellis.prevState[m+chtrellis.stateNb*k];
149 inputs[k] = chtrellis.input[m+chtrellis.stateNb*k];
150 C[k] = (inputs[k])*apriori_data[n-1]-
itpp::sqr(rec_sig[n-1]-chtrellis.output[pstates[k]+chtrellis.stateNb*inputs[k]])/(2*sigma2);
152 A[m+n*chtrellis.stateNb] =
itpp::log_add(A[pstates[0]+(n-1)*chtrellis.stateNb]+C[0], A[pstates[1]+(n-1)*chtrellis.stateNb]+C[1]);
153 sum +=
std::exp(A[m+n*chtrellis.stateNb]);
157 for (m=0; m<chtrellis.stateNb; m++)
159 A[m+n*chtrellis.stateNb] -=
sum;
165 for (n=N-1; n>=0; n--)
168 for (m=0; m<chtrellis.stateNb; m++)
172 nstates[k] = chtrellis.nextState[m+k*chtrellis.stateNb];
173 C[k] = (k)*apriori_data[n]-
itpp::sqr(rec_sig[n]-chtrellis.output[m+k*chtrellis.stateNb])/(2*sigma2);
175 B[m+n*chtrellis.stateNb] =
itpp::log_add(B[nstates[0]+(n+1)*chtrellis.stateNb]+C[0], B[nstates[1]+(n+1)*chtrellis.stateNb]+C[1]);
176 sum +=
std::exp(B[m+n*chtrellis.stateNb]);
180 for (m=0; m<chtrellis.stateNb; m++)
182 B[m+n*chtrellis.stateNb] -=
sum;
188 extrinsic_data.set_size(N);
189 #pragma omp parallel for private(n,sum,sumbis,m,k,nstates,C,buffer)
194 for (m=0; m<chtrellis.stateNb; m++)
198 nstates[k] = chtrellis.nextState[m+k*chtrellis.stateNb];
199 C[k] = (k)*apriori_data[n-1]-
itpp::sqr(rec_sig[n-1]-chtrellis.output[m+k*chtrellis.stateNb])/(2*sigma2);
200 buffer =
std::exp(A[m+(n-1)*chtrellis.stateNb]+C[k]+B[nstates[k]+n*chtrellis.stateNb]);
207 extrinsic_data[n-1] =
std::log(sum/sumbis)-apriori_data[n-1];
211 delete[] chtrellis.output;
212 delete[] chtrellis.nextState;
213 delete[] chtrellis.prevState;
214 delete[] chtrellis.input;
219 void SISO::equalizer_maxlogMAP(itpp::vec &extrinsic_data,
const itpp::vec &rec_sig,
const itpp::vec &apriori_data)
227 int N = rec_sig.length();
241 double* A =
new double[chtrellis.stateNb*(N+1)];
242 double* B =
new double[chtrellis.stateNb*(N+1)];
244 for (n=1; n<chtrellis.stateNb; n++)
246 B[N*chtrellis.stateNb] = 0;
247 sum = (tail?-INFINITY:0);
248 for (n=1; n<chtrellis.stateNb; n++)
249 B[n+N*chtrellis.stateNb] = sum;
251 #pragma omp parallel sections
private(n,sum,m,k,C)
257 for (m=0; m<chtrellis.stateNb; m++)
261 pstates[k] = chtrellis.prevState[m+chtrellis.stateNb*k];
262 inputs[k] = chtrellis.input[m+chtrellis.stateNb*k];
263 C[k] = (inputs[k])*apriori_data[n-1]-
itpp::sqr(rec_sig[n-1]-chtrellis.output[pstates[k]+chtrellis.stateNb*inputs[k]])/(2*sigma2);
265 A[m+n*chtrellis.stateNb] =
std::max(A[pstates[0]+(n-1)*chtrellis.stateNb]+C[0], A[pstates[1]+(n-1)*chtrellis.stateNb]+C[1]);
266 sum =
std::max(sum, A[m+n*chtrellis.stateNb]);
268 for (m=0; m<chtrellis.stateNb; m++)
269 A[m+n*chtrellis.stateNb] -= sum;
274 for (n=N-1; n>=0; n--)
277 for (m=0; m<chtrellis.stateNb; m++)
281 nstates[k] = chtrellis.nextState[m+k*chtrellis.stateNb];
282 C[k] = (k)*apriori_data[n]-
itpp::sqr(rec_sig[n]-chtrellis.output[m+k*chtrellis.stateNb])/(2*sigma2);
284 B[m+n*chtrellis.stateNb] =
std::max(B[nstates[0]+(n+1)*chtrellis.stateNb]+C[0], B[nstates[1]+(n+1)*chtrellis.stateNb]+C[1]);
285 sum =
std::max(sum, B[m+n*chtrellis.stateNb]);
287 for (m=0; m<chtrellis.stateNb; m++)
288 B[m+n*chtrellis.stateNb] -= sum;
293 extrinsic_data.set_size(N);
298 for (m=0; m<chtrellis.stateNb; m++)
302 nstates[k] = chtrellis.nextState[m+k*chtrellis.stateNb];
303 C[k] = (k)*apriori_data[n-1]-
itpp::sqr(rec_sig[n-1]-chtrellis.output[m+k*chtrellis.stateNb])/(2*sigma2);
304 buffer = A[m+(n-1)*chtrellis.stateNb]+C[k]+B[nstates[k]+n*chtrellis.stateNb];
306 sum = std::
max(sum, buffer);
308 sumbis = std::
max(sumbis, buffer);
311 extrinsic_data[n-1] = (sum-sumbis)-apriori_data[n-1];
315 delete[] chtrellis.
output;
318 delete[] chtrellis.
input;