📄 idealchannelestimation.cpp
字号:
/******************************************************************************\ * Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik * Copyright (c) 2001 * * Author(s): * Volker Fischer * * Description: * * ****************************************************************************** * * This program is free software; you can redistribute it and/or modify it under * the terms of the GNU General Public License as published by the Free Software * Foundation; either version 2 of the License, or (at your option) any later * version. * * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more * details. * * You should have received a copy of the GNU General Public License along with * this program; if not, write to the Free Software Foundation, Inc., * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *\******************************************************************************/#include "IdealChannelEstimation.h"/* Implementation *************************************************************/void CIdealChanEst::ProcessDataInternal(CParameter& ReceiverParam){ int i, j; /* Calculation of channel tranfer function ------------------------------ */ /* pvecInputData.cSig equalized signal \hat{s}(t) pvecInputData2.tOut received signal r(t) pvecInputData2.tIn transmitted signal s(t) pvecInputData2.tRef received signal without noise (channel reference signal) */ for (i = 0; i < iNumCarrier; i++) { /* Extract channel estimate from equalized signal */ veccEstChan[i] = (*pvecInputData2)[i].tOut / (*pvecInputData)[i].cSig; /* Calculate reference signal for channel from fading taps. We have to do it this way to avoid errors from ICI (inter-carrier-interfearence). Consider offset from guard-interval removal (additional phase rotation) */ veccRefChan[i] = (_REAL) 0.0; for (j = 0; j < ReceiverParam.iNumTaps; j++) veccRefChan[i] += Rotate((*pvecInputData2)[0].veccTap[j], i, ReceiverParam.iPathDelay[j] + ReceiverParam.iOffUsfExtr); /* Normalize result */ veccRefChan[i] *= ReceiverParam.rGainCorr; } /* Debar DC carriers, set them to zero */ for (i = 0; i < iNumDCCarriers; i++) { veccEstChan[i + iStartDCCar] = _COMPLEX((_REAL) 0.0, (_REAL) 0.0); veccRefChan[i + iStartDCCar] = _COMPLEX((_REAL) 0.0, (_REAL) 0.0); } /* Start evaluation results after exceeding the start count */ if (iStartCnt > 0) iStartCnt--; else { /* MSE for all carriers */ for (i = 0; i < iNumCarrier; i++) vecrMSEAverage[i] += SqMag(veccEstChan[i] - veccRefChan[i]); /* New values have been added, increase counter for final result calculation */ lAvCnt++; } /* Equalize the output vector ------------------------------------------- */ /* Write to output vector. Also, ship the channel state at a certain cell */ for (i = 0; i < iNumCarrier; i++) {#ifdef USE_MAX_LOG_MAP /* In case of MAP we need the squared magnitude for the calculation of the metric */ (*pvecOutputData)[i].rChan = SqMag(veccRefChan[i]);#else /* In case of hard-desicions, we need the magnitude of the channel for the calculation of the metric */ (*pvecOutputData)[i].rChan = abs(veccRefChan[i]);#endif /* If we do not want to get the actual channel estimate but the ideal equalized signal, we should do it this way to be ICI free */ (*pvecOutputData)[i].cSig = (*pvecInputData2)[i].tOut * (*pvecInputData2)[i].tIn / (*pvecInputData2)[i].tRef; } /* Set symbol number for output vector */ (*pvecOutputData).GetExData().iSymbolID = (*pvecInputData).GetExData().iSymbolID;}void CIdealChanEst::InitInternal(CParameter& ReceiverParam){ int m, k; /* Init base class for modifying the pilots (rotation) */ CPilotModiClass::InitRot(ReceiverParam); /* Get local parameters */ iNumCarrier = ReceiverParam.iNumCarrier; iNumSymPerFrame = ReceiverParam.iNumSymPerFrame; iDFTSize = ReceiverParam.iFFTSizeN; /* Parameters for debaring the DC carriers from evaluation. First check if we have only useful part on the right side of the DC carrier */ if (ReceiverParam.iCarrierKmin > 0) { /* In this case, no DC carriers are in the useful spectrum */ iNumDCCarriers = 0; iStartDCCar = 0; } else { if (ReceiverParam.GetWaveMode() == RM_ROBUSTNESS_MODE_A) { iNumDCCarriers = 3; iStartDCCar = abs(ReceiverParam.iCarrierKmin) - 1; } else { iNumDCCarriers = 1; iStartDCCar = abs(ReceiverParam.iCarrierKmin); } } /* Init average counter */ lAvCnt = 0; /* Init start count (debar initialization of channel estimation) */ iStartCnt = 20; /* Additional delay from long interleaving has to be considered */ if (ReceiverParam.GetInterleaverDepth() == CParameter::SI_LONG) iStartCnt += ReceiverParam.iNumSymPerFrame * D_LENGTH_LONG_INTERL; /* Allocate memory for intermedia results */ veccEstChan.Init(iNumCarrier); veccRefChan.Init(iNumCarrier); vecrMSEAverage.Init(iNumCarrier, (_REAL) 0.0); /* Reset average with zeros */ /* Define block-sizes for inputs and output */ iInputBlockSize = iNumCarrier; iInputBlockSize2 = iNumCarrier; iOutputBlockSize = iNumCarrier;}void CIdealChanEst::GetResults(CVector<_REAL>& vecrResults){ vecrResults.Init(iNumCarrier, (_REAL) 0.0); /* Copy data in return vector */ for (int i = 0; i < iNumCarrier; i++) vecrResults[i] = vecrMSEAverage[i] / lAvCnt;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -