Esempio n. 1
0
static void impulse_response(int rnk, dim_stuff *d, R impulse_amp,
			     R *A, int N)
{
     if (rnk == 0)
	  A[0] = impulse_amp;
     else {
	  int i;
	  N /= d->n;
	  for (i = 0; i < d->n; ++i) {
	       impulse_response(rnk - 1, d + 1,
				impulse_amp * d->ti(d->i0, d->k0 + i, d->n0),
				A + i * N, N);
	  }
     }
}
Esempio n. 2
0
static double rimpulse(dim_stuff *d, R impulse_amp,
		       int n, int vecn, info *nfo, 
		       R *inA, R *inB, R *inC,
		       R *outA, R *outB, R *outC,
		       R *tmp, int rounds, double tol)
{
     double e = 0.0;
     int N = n * vecn;
     int i;
     int j;

     /* test 2: check that the unit impulse is transformed properly */

     for (i = 0; i < N; ++i) {
	  /* pls */
	  inA[i] = 0.0;
     }
     for (i = 0; i < vecn; ++i) {
	  inA[i * n] = (i+1) / (double)(vecn+1);
     
	  /* transform of the pls */
	  impulse_response(nfo->probsz->rnk, d, impulse_amp * inA[i * n],
			   outA + i * n, n);
     }

     dofft(nfo, inA, tmp);
     e = dmax(e, racmp(tmp, outA, N, "impulse 1", tol));

     for (j = 0; j < rounds; ++j) {
          rarand(inB, N);
          rasub(inC, inA, inB, N);
          dofft(nfo, inB, outB);
          dofft(nfo, inC, outC);
          raadd(tmp, outB, outC, N);
          e = dmax(e, racmp(tmp, outA, N, "impulse", tol));
     }
     return e;
}
Esempio n. 3
0
void SISO::gen_chtrellis(void)
// generate trellis for precoded FIR channels with real coefficients
{
    //get parameters
    int mem_len = impulse_response.cols()-1;//memory length of the channel
    int p_order = prec_gen.length()-1;//order of the precoder polynomial

    //other variables
    register int n,k,j;
    double inputs[] = {1.0,-1.0};//1->-1, 0->+1
    int index;
    double feedback[2];

    //create channel trellis
    int equiv_ch_mem_len = std::max(mem_len, p_order);
    chtrellis.stateNb = (1<<equiv_ch_mem_len);
    chtrellis.output = new double[2*chtrellis.stateNb];
    chtrellis.nextState = new int[2*chtrellis.stateNb];
    chtrellis.prevState = new int[2*chtrellis.stateNb];
    chtrellis.input = new int[2*chtrellis.stateNb];

    //initialize trellis
    itpp::ivec enc_mem(equiv_ch_mem_len);
#pragma omp parallel for private(n,enc_mem,k,feedback,j)
    for (n=0; n<chtrellis.stateNb; n++) //initial state
    {
        enc_mem = 1-2*itpp::to_ivec(itpp::dec2bin(equiv_ch_mem_len, n));//1->-1, 0->+1
        //output
        for (k=0; k<2; k++)
        {
            feedback[k] = inputs[k];
            for (j=1; j<=p_order; j++)
                if (prec_gen[j])
                    feedback[k] *= enc_mem[j-1];//xor truth table must remain the same
            chtrellis.output[n+k*chtrellis.stateNb] = feedback[k]*impulse_response(0,0);
            for (j=1; j<=mem_len; j++)
                chtrellis.output[n+k*chtrellis.stateNb] += (enc_mem[j-1]*impulse_response(0,j));
        }
        //next state
        for (j=(equiv_ch_mem_len-1); j>0; j--)
            enc_mem[j] = enc_mem[j-1];
        for (k=0; k<2; k++)
        {
            enc_mem[0] = int(feedback[k]);
            chtrellis.nextState[n+k*chtrellis.stateNb] = itpp::bin2dec(itpp::to_bvec((1-enc_mem)/2), true);//-1->1, +1->0
        }
    }

#pragma omp parallel for private(j,index,n,k)
    for (j=0; j<chtrellis.stateNb; j++)
    {
        index = 0;
        for (n=0; n<chtrellis.stateNb; n++)
        {
            for (k=0; k<2; k++)
            {
                if (chtrellis.nextState[n+k*chtrellis.stateNb]==j)
                {
                    chtrellis.prevState[j+index*chtrellis.stateNb] = n;
                    chtrellis.input[j+index*chtrellis.stateNb] = k;//this is an index to the channel input
                    index++;
                }
            }
        }
    }
}