cvec fir_x::process(bvec ce, cvec x) { cvec y; int N; #if (DEBUG_LEVEL==3) cout << "***** fir_x::proc *****" << endl; cout << "ce=" << ce << endl; cout << "x=" << x << endl; sleep(1000); #endif N=ce.length(); if (x.length()!=N) { throw sci_exception("fir_x::process - ce.size <> x.size", x.length() ); } y.set_size(N); for (int i=0; i<N; i++) { if (bool(ce[i])) y0=update(x[i]); y[i]=y0; } #if (DEBUG_LEVEL==3) cout << "y=" << y << endl; cout << "+++++ fir_x::proc +++++" << endl; sleep(1000); #endif return (y); }
static void assert_cvec_p(const cvec &ref, const cvec &act, int line) { ASSERT_EQ(ref.length(), act.length()) << line; for (int n = 0; n < ref.length(); ++n) { ASSERT_NEAR(ref(n).real(), act(n).real(), tol) << line; ASSERT_NEAR(ref(n).imag(), act(n).imag(), tol) << line; } }
static void assert_cvec(const cvec &ref, const cvec &act) { ASSERT_EQ(ref.length(), act.length()); for (int n = 0; n < ref.length(); ++n) { ASSERT_NEAR(ref[n].real(), act[n].real(), tol); ASSERT_NEAR(ref[n].imag(), act[n].imag(), tol); } }
cvec descrambling(cvec data,cvec code) { cvec result; result.set_length(data.length()); result.zeros(); for(int i=0;i<data.length();i++) { result[i]=data(i)*code(i); } return result; }
void zero_pad_back(cvec& vec_in, int m_in) { int quotient = vec_in.length() / m_in; if (quotient*m_in == vec_in.length()) { return; } else { int n_remainder = (quotient + 1) * m_in - vec_in.length(); vec_in = concat(vec_in, zeros_c(n_remainder)); } }
void fir_x::set_state(cvec cv) { int k,N; N=get_size(); if (cv.length()!=N ) { throw sci_exception("fir::set_state v.lenght <> fir_size", cv.length() ); } for (k=0; k < N; k++) { z[k]=cv[k]; } }
void Plot::Plot_data(cvec ydata, int plot_number){ double x[ydata.length()]; double y[ydata.length()]; if(plot_number==2){ curve2.setStyle(QwtPlotCurve::CurveStyle(4)); for (int i=0;i<ydata.length();i++){ x[i]=real(ydata.get(i)); y[i]=imag(ydata.get(i)); } curve2.setData(x,y,ydata.length()); gui->qwtPlot_2->replot(); } }
/** Return the channel FIR estimation based on trainSeq and fill phiHat, Ahat, delay, sigmaSqrNoise * * @pre: * - dataC: cvec of the received data * - trainC: pointer to array of the training sequence * !!! length assume to be < than dataC.length()!!! * - delay: pointer to a int with synchornization point * * @post: * - Estimators are now filled! * - returned the channel FIR estimation */ void synchCatchChannel(cvec dataC, cvec trainCUp , int *delay ){ if(dataC.length()<trainCUp.length()){ cerr << "The training sequence is too big compare to datas!\n"; exit(1); } //std::cout<<"Data="<<dataC<<"\n"; //std::cout<<"Train="<<trainCUp<<"\n"; //Computes crosscorrelation: int timeLag=1000; cvec dataCSmall=dataC(1,timeLag); cvec crossCorr=itpp::xcorr(dataCSmall, trainCUp, timeLag); //std::cout<<"Cross="<<crossCorr<<"\n"; //Search for the maximum double max=0.0; int index=0, count=0; double tmp[crossCorr.length()-timeLag+1]; for(int i=timeLag-1;i<crossCorr.length();i++){ tmp[count]=abs(crossCorr[i]); //DispVal(tmp[count]); //DispVal(count); if (tmp[count]> max ){ max=tmp[count]; index=i; } count++; } index=index-timeLag+1; *delay=index; // Save data to file std::ofstream ofs( "xcorr.dat" , std::ifstream::out ); ofs.write((char * ) tmp, (crossCorr.length()-timeLag+1)*sizeof(double)); ofs.close(); }
cvec prePost (cvec data_time, int pre, int post){ data_time.ins(0, data_time.right(pre)); data_time.ins(data_time.length(), data_time.mid(pre,post)); return(data_time); }
cvec xcorr(const cvec &x, const cvec &y, const int max_lag, const std::string scaleopt) { cvec out(2*x.length() - 1); //Initial size does ont matter, it will get adjusted xcorr(x, y, out, max_lag, scaleopt, false); return out; }
void FDE(cvec& signal_in, cvec& signal_out, vec& imp_response, int ifftSize, bool verbose) { cvec para = fft(to_cvec(concat(imp_response, zeros(ifftSize-imp_response.length())))); if (verbose) {cout << "para: \n" << para << endl;} int nSymbols = signal_in.length() / ifftSize; it_assert(nSymbols * ifftSize == signal_in.length(), "warning"); signal_out = zeros_c(signal_in.length()); int IdxSig = 0; for (int i = 0; i < nSymbols; i++) { for (int j = 0; j < ifftSize; j++) { signal_out[IdxSig] = signal_in[IdxSig] / para[j]; IdxSig++; } } }
//Evaluate average power of given vector of symbols #M00 double eval_avg_power(const cvec& symbol_vec) { //Overflow check is not implemented in this function bool verbose = true; double average_power = 0.0; double acculmulate_power = 0.0; for (size_t i = 0; i < symbol_vec.length(); ++i) { acculmulate_power += pow(std::abs(symbol_vec(i)), 2.0); } average_power = acculmulate_power / symbol_vec.length(); //Result [verbose] if (verbose) { cout << "[M00] " << "Average power = " << average_power << endl; } return average_power; }
void cofdm_sel::set_output(cvec y_0) { if( y_0.length()== NFFT ) { y0=y_0; } else { throw sci_exception("cofdm_sel::set_output - bad y_0.size() <> NFFT=", NFFT); } }
cvec operator/(const double &s, const cvec &v) { it_assert_debug(v.size() > 0, "operator/(): Vector of zero length"); cvec temp(v.length()); for (int i = 0;i < v.size();i++) { temp(i) = s / v(i); } return temp; }
cvec TestEseNonGrayFixture::conv(const cmat &a, const cvec &b) { // check a.rows()==b.length() int len = a.cols()+b.length()-1; cvec ret = zeros_c(len); for(int i=0; i<a.cols(); i++) { cvec tmp = zeros_c(len); tmp.set_subvector(i, elem_mult(a.get_col(i), b)); ret += tmp; } return ret; }
void cofdm_dem::set_output(cvec x) { if (x.length() == (NFFT+CP)) { try { y0 = scale* OFDM::demodulate(x); } catch (...) { throw sci_exception("cofdm_dem::demodulate - error"); } } else { throw sci_exception("cofdm_dem::demodulate -x.lenght<>(NFFT+CP)=", NFFT+CP); } }
void Matlab_Engine::put(const cvec &v, const char *name){ const int N = v.length(); mxArray *T; if((T = mxCreateDoubleMatrix(N, 1, mxCOMPLEX)) == NULL) cout << "Unable to allocate Matlab vector. Out of memory?\n"; mxSetName(T, name); double *pt_r = (double*) mxGetPr(T); double *pt_i = (double*) mxGetPi(T); for(int k=0; k<N; k++){ *pt_r++ = real(v(k)); *pt_i++ = imag(v(k)); } if(engPutArray(e, T)) cout << "Unable to put it++ vector to Matlab workspace!\n"; }
// ceio [cei|ceo] // cmat [xi+%i*xq|t+%i*0] // cvec [yi+%i*yq] cvec tedg_x::process(bmat ceio, cvec x) { cvec y; int K,i; double y0i, y0q; #if (DEBUG_LEVEL==3) cout << "***** tedg_x::process *****" << endl; cout << "ceio=" << ceio << endl; cout << "x=" << x << endl; sleep(1000); #endif if (ceio.cols() != 2) { throw sci_exception("tedg_x::process - ceio.cols() <> 2 ", ceio.cols() ); } if (x.length() != ceio.rows() ) { throw sci_exception("tedg_x::process - x.lenght() <> ceio.rows() ", x.length() ); } K=ceio.rows(); y.set_length(K); for ( i=0; i<K; i++) { // cei - input sample to x_cb if ( bool(ceio(i,0))) { x2=x1; x1=x0; x0=x(i); } // ceo if ( bool(ceio(i,1))) { switch (MODE) { case TEDG_MODE_STD: y0i = (x0.real()-x2.real())*(x1.real()); y0q = (x0.imag()-x2.imag())*(x1.imag()); y0 = complex<double>(y0i,y0q); break; case TEDG_MODE_EDGE: if ((x0.real() > 0.0) && (x2.real() < 0.0)) { y0i = x1.real(); } else if ((x0.real() < 0.0) && (x2.real() > 0.0)) { y0i = - x1.real(); } else { y0i =0.0; }; if ( (x0.imag() > 0.0) && (x2.imag() < 0.0 ) ) { y0q = x1.imag(); } else if ( ( x0.imag() < 0.0 ) && (x2.imag()> 0.0 ) ) { y0q = - x1.imag(); } else { y0q =0.0; }; y0 = complex<double>(y0i,y0q); break; case TEDG_MODE_PUMP: if ((x0.real() > 0.0) && (x2.real() < 0.0)) { y0i = sgn(x1.real()); } else if ((x0.real() < 0.0) && (x2.real() > 0.0)) { y0i = - sgn(x1.real()); } else { y0i =0.0; }; if ( (x0.imag() > 0.0) && (x2.imag() < 0.0 ) ) { y0q = sgn(x1.imag()); } else if ( ( x0.imag() < 0.0 ) && (x2.imag()> 0.0 ) ) { y0q = - sgn(x1.imag()); } else { y0q =0.0; }; y0 = complex<double>(y0i,y0q) * TED_PUMP; break; default: throw sci_exception("tedg_x::process - bad mode", MODE ); break; } } y(i)= y0; } #if (DEBUG_LEVEL==3) cout << "y=" << y << endl; cout << "+++++ tedg_x::process +++++" << endl; sleep(1000); #endif return (y); }
/** Return the channel FIR estimation based on trainSeq and fill phiHat, Ahat, delay, sigmaSqrNoise * * @pre: * - dataC: cvec of the received data * - trainC: pointer to array of the training sequence * !!! length assume to be < than dataC.length()!!! * - Post and Pre: FIR filter channel number of past and future elements * - phiHat: pointer to a double with phase estimation * - delay: pointer to a int with synchornization point * - sigmaSqrNoise: pointer to a double with FIR estimator variance * * @post: * - Estimators are now filled! * - returned the channel FIR estimation */ cvec synchCatchChannel(cvec dataC, cvec trainCUp, int Post, int Pre , double *phiHat, double *AHat, int *delay, double *sigmaSqrNoise ){ if(dataC.length()<trainCUp.length()){ cerr << "The training sequence is too big compare to datas!\n"; exit(1); } if(Pre<0||Post<0){ cerr << "Not possible to compute filter!\n"; exit(1); } //std::cout<<"Data="<<dataC<<"\n"; //std::cout<<"Train="<<trainCUp<<"\n"; //Computes crosscorrelation: cvec crossCorr=itpp::xcorr(dataC, trainCUp); //std::cout<<"Cross="<<crossCorr<<"\n"; //Search for the maximum double max=0.0; int index=0, count=0; double tmp[crossCorr.length()-dataC.length()+1]; DispVal(crossCorr.length()-dataC.length()+1); for(int i=dataC.length()-1;i<crossCorr.length();i++){ tmp[count]=abs(crossCorr[i]); //DispVal(tmp[count]); //DispVal(count); if (tmp[count]> max && count<(crossCorr.length()-dataC.length()+1)/2 ){ max=tmp[count]; index=i; DispVal(index-dataC.length()+1); } count++; } index=index-dataC.length()+1; DispVal(index); *delay=index; //Computes Estimate of phase at the peak: *phiHat=arg(dataC(index)); // Save data to file std::ofstream ofs( "xcorr.dat" , std::ifstream::out ); ofs.write((char * ) tmp, (crossCorr.length()-dataC.length()+1)*sizeof(double)); ofs.close(); //std::cout<<"tsamp="<<index<<"\n"; //Removes received train from data cvec trainRecC(trainCUp.length()); int i=index; for(int count=0;count<trainCUp.length();count++){ trainRecC.set(count,dataC[i+count]); //DispVal(dataC[i]); //DispVal(count); } //std::complex< double > meanTrain=itpp::mean(trainRecC); //DispVal(meanTrain); //trainRecC=trainRecC-meanTrain; //std::cout<<"TrainRec"<<trainRecC<<"\n"; //Channel estimator using training sequence: //autoCorr of known training sequence: cvec autoCorr=itpp::xcorr(trainCUp); //DispVal(autoCorr.length()); //DispVal(autoCorr(trainCUp.length()-1)); //std::cout<<"Auto="<<autoCorr<<"\n"; *AHat=abs(crossCorr(index+dataC.length()-1))/abs(autoCorr(trainCUp.length()-1)); //SigmaYY: cvec aux(Pre+Post+1); int start=trainCUp.length()-1; for(int count=0; count<Pre+Post+1; count++){ if(count<=2*trainCUp.length()-1){ aux.set(count,autoCorr[start+count]); }else{ aux.set(count,complex<double>(0.0,0.0)); } } cmat SigmaYY=toeplitz(aux); //std::cout<<"SigmaYY=\n"<<SigmaYY<<"\n"; cvec aux2 =itpp::xcorr(trainRecC,trainCUp); //SigmaYx: int ini=trainCUp.length()-Pre-1; cvec SigmaYx(Pre+Post+1); for(int count=0; count<SigmaYx.length(); count++){ SigmaYx.set(count, aux2[ini+count]); //std::cout<<"xcorr=\n"<<crossCorr[i]<<"\n"; } //std::cout<<"SigmaYx=\n"<<SigmaYx<<"\n"; //Estimate of the channel: cmat invSigmaYY=itpp::inv(SigmaYY); cvec theta_est=itpp::operator*(invSigmaYY,SigmaYx); //std::cout<<"invSigmaYY=\n"<<invSigmaYY<<"\n"; // std::cout<<"Channel="<<theta_est<<"\n"; //Compute the variance of the estimation: trainCUp.ins(trainCUp.length(),complex<double>(0,0)); cvec trainCEst=filter( theta_est, 1, trainCUp); //std::cout<<"trainCEst="<<trainCEst<<"\n"; trainCEst.del(0); cvec crossEst=itpp::xcorr(trainRecC-trainCEst); //std::cout<<"crossEst="<<crossEst<<"\n"; *sigmaSqrNoise=abs(crossEst(trainRecC.length()-1)); return theta_est; }
//Correlation void xcorr(const cvec &x, const cvec &y, cvec &out, const int max_lag, const std::string scaleopt, bool autoflag) { int N = std::max(x.length(), y.length()); //Compute the FFT size as the "next power of 2" of the input vector's length (max) int b = ceil_i(::log2(2.0 * N - 1)); int fftsize = pow2i(b); int end = fftsize - 1; cvec temp2; if (autoflag == true) { //Take FFT of input vector cvec X = fft(zero_pad(x, fftsize)); //Compute the abs(X).^2 and take the inverse FFT. temp2 = ifft(elem_mult(X, conj(X))); } else { //Take FFT of input vectors cvec X = fft(zero_pad(x, fftsize)); cvec Y = fft(zero_pad(y, fftsize)); //Compute the crosscorrelation temp2 = ifft(elem_mult(X, conj(Y))); } // Compute the total number of lags to keep. We truncate the maximum number of lags to N-1. int maxlag; if ((max_lag == -1) || (max_lag >= N)) maxlag = N - 1; else maxlag = max_lag; //Move negative lags to the beginning of the vector. Drop extra values from the FFT/IFFt if (maxlag == 0) { out.set_size(1, false); out = temp2(0); } else out = concat(temp2(end - maxlag + 1, end), temp2(0, maxlag)); //Scale data if (scaleopt == "biased") //out = out / static_cast<double_complex>(N); out = out / static_cast<std::complex<double> >(N); else if (scaleopt == "unbiased") { //Total lag vector vec lags = linspace(-maxlag, maxlag, 2 * maxlag + 1); cvec scale = to_cvec(static_cast<double>(N) - abs(lags)); out /= scale; } else if (scaleopt == "coeff") { if (autoflag == true) // Normalize by Rxx(0) out /= out(maxlag); else { //Normalize by sqrt(Rxx(0)*Ryy(0)) double rxx0 = sum(abs(elem_mult(x, x))); double ryy0 = sum(abs(elem_mult(y, y))); out /= std::sqrt(rxx0 * ryy0); } } else if (scaleopt == "none") {} else it_warning("Unknow scaling option in XCORR, defaulting to <none> "); }
/* Return the mean value of the elements in the vector */ complex<double> mean(const cvec& v) { return sum(v)/static_cast<double>(v.length()); }