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;