📄 metric.cpp
字号:
/******************************************************************************\
* Technische Universitaet Darmstadt, Institut fuer Nachrichtentechnik
* Copyright (c) 2001
*
* Author(s):
* Volker Fischer
*
* Description:
*
* The metric is calculated as follows:
* Using ML: M = |r - s * h| = |h| * |r / h - s|
* Using MAP: M = |r - s * h|^2 = |h|^2 * |r / h - s|^2
*
* Subset definition:
* [1 2 3] -> ([vecSubsetDef1 vecSubsetDef2 vecSubsetDef3])
*
******************************************************************************
*
* 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 "Metric.h"
/* Definitions ****************************************************************/
/* Definitions for binary numbers (BI). On the left is most sigificant bit */
#define BI_00 0 /* Two bits */
#define BI_01 1
#define BI_10 2
#define BI_11 3
#define BI_000 0 /* Three bits */
#define BI_001 1
#define BI_010 2
#define BI_011 3
#define BI_100 4
#define BI_101 5
#define BI_110 6
#define BI_111 7
/* Implementation *************************************************************/
void CMLCMetric::CalculateMetric(CVector<CEquSig>* pcInSymb,
CVector<CDistance>& vecMetric,
CVector<_DECISION>& vecSubsetDef1,
CVector<_DECISION>& vecSubsetDef2,
CVector<_DECISION>& vecSubsetDef3,
CVector<_DECISION>& vecSubsetDef4,
CVector<_DECISION>& vecSubsetDef5,
CVector<_DECISION>& vecSubsetDef6,
int iLevel, _BOOLEAN bIteration)
{
int i, k;
int iTabInd0;
switch (eMapType)
{
case CParameter::CS_1_SM:
/**********************************************************************/
/* 4QAM ***************************************************************/
/**********************************************************************/
/* Metric according DRM-standard: (i_0 q_0) = (y_0,0 y_0,1) */
for (i = 0, k = 0; i < iInputBlockSize; i++, k += 2)
{
/* Real part ---------------------------------------------------- */
/* Distance to "0" */
vecMetric[k].rTow0 = Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM4[0][0], (*pcInSymb)[i].rChan);
/* Distance to "1" */
vecMetric[k].rTow1 = Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM4[1][0], (*pcInSymb)[i].rChan);
/* Imaginary part ----------------------------------------------- */
/* Distance to "0" */
vecMetric[k + 1].rTow0 = Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM4[0][1], (*pcInSymb)[i].rChan);
/* Distance to "1" */
vecMetric[k + 1].rTow1 = Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM4[1][1], (*pcInSymb)[i].rChan);
}
break;
case CParameter::CS_2_SM:
/**********************************************************************/
/* 16QAM **************************************************************/
/**********************************************************************/
/* (i_0 i_1 q_0 q_1) = (y_0,0 y_1,0 y_0,1 y_1,1) */
switch (iLevel)
{
case 0:
for (i = 0, k = 0; i < iInputBlockSize; i++, k += 2)
{
if (bIteration == TRUE)
{
/* Real part -------------------------------------------- */
#ifdef USE_MAX_LOG_MAP
vecMetric[k].rTow0 =
Minimum2((*pcInSymb)[i].cSig.real(),
rTableQAM16[BI_00 /* [0 0] */][0],
rTableQAM16[BI_01 /* [0 1] */][0],
(*pcInSymb)[i].rChan, vecSubsetDef2[k]);
vecMetric[k].rTow1 =
Minimum2((*pcInSymb)[i].cSig.real(),
rTableQAM16[BI_10 /* [1 0] */][0],
rTableQAM16[BI_11 /* [1 1] */][0],
(*pcInSymb)[i].rChan, vecSubsetDef2[k]);
#else
/* Lowest bit defined by "vecSubsetDef2" */
iTabInd0 = ExtractBit(vecSubsetDef2[k]) & 1;
/* Distance to "0" */
vecMetric[k].rTow0 =
Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM16[iTabInd0][0], (*pcInSymb)[i].rChan);
/* Distance to "1" */
vecMetric[k].rTow1 =
Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM16[iTabInd0 | (1 << 1)][0],
(*pcInSymb)[i].rChan);
#endif
/* Imaginary part --------------------------------------- */
#ifdef USE_MAX_LOG_MAP
vecMetric[k + 1].rTow0 = Minimum2((*pcInSymb)[i].cSig.imag(),
rTableQAM16[BI_00 /* [0 0] */][1],
rTableQAM16[BI_01 /* [0 1] */][1],
(*pcInSymb)[i].rChan, vecSubsetDef2[k + 1]);
vecMetric[k + 1].rTow1 = Minimum2((*pcInSymb)[i].cSig.imag(),
rTableQAM16[BI_10 /* [1 0] */][1],
rTableQAM16[BI_11 /* [1 1] */][1],
(*pcInSymb)[i].rChan, vecSubsetDef2[k + 1]);
#else
/* Lowest bit defined by "vecSubsetDef2" */
iTabInd0 = ExtractBit(vecSubsetDef2[k + 1]) & 1;
/* Distance to "0" */
vecMetric[k + 1].rTow0 =
Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM16[iTabInd0][1], (*pcInSymb)[i].rChan);
/* Distance to "1" */
vecMetric[k + 1].rTow1 =
Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM16[iTabInd0 | (1 << 1)][1],
(*pcInSymb)[i].rChan);
#endif
}
else
{
/* There are two possible points for each bit. Both have to
be used. In the first step: {i_1}, {q_1} = 0
In the second step: {i_1}, {q_1} = 1 */
/* Calculate distances */
/* Real part */
vecMetric[k].rTow0 =
Minimum2((*pcInSymb)[i].cSig.real(),
rTableQAM16[BI_00 /* [0 0] */][0],
rTableQAM16[BI_01 /* [0 1] */][0],
(*pcInSymb)[i].rChan);
vecMetric[k].rTow1 =
Minimum2((*pcInSymb)[i].cSig.real(),
rTableQAM16[BI_10 /* [1 0] */][0],
rTableQAM16[BI_11 /* [1 1] */][0],
(*pcInSymb)[i].rChan);
/* Imaginary part */
vecMetric[k + 1].rTow0 =
Minimum2((*pcInSymb)[i].cSig.imag(),
rTableQAM16[BI_00 /* [0 0] */][1],
rTableQAM16[BI_01 /* [0 1] */][1],
(*pcInSymb)[i].rChan);
vecMetric[k + 1].rTow1 =
Minimum2((*pcInSymb)[i].cSig.imag(),
rTableQAM16[BI_10 /* [1 0] */][1],
rTableQAM16[BI_11 /* [1 1] */][1],
(*pcInSymb)[i].rChan);
}
}
break;
case 1:
for (i = 0, k = 0; i < iInputBlockSize; i++, k += 2)
{
/* Real part ------------------------------------------------ */
#ifdef USE_MAX_LOG_MAP
vecMetric[k].rTow0 =
Minimum2((*pcInSymb)[i].cSig.real(),
rTableQAM16[BI_00 /* [0 0] */][0],
rTableQAM16[BI_10 /* [1 0] */][0],
(*pcInSymb)[i].rChan, vecSubsetDef1[k]);
vecMetric[k].rTow1 =
Minimum2((*pcInSymb)[i].cSig.real(),
rTableQAM16[BI_01 /* [0 1] */][0],
rTableQAM16[BI_11 /* [1 1] */][0],
(*pcInSymb)[i].rChan, vecSubsetDef1[k]);
#else
/* Higest bit defined by "vecSubsetDef1" */
iTabInd0 = ((ExtractBit(vecSubsetDef1[k]) & 1) << 1);
/* Distance to "0" */
vecMetric[k].rTow0 = Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM16[iTabInd0][0], (*pcInSymb)[i].rChan);
/* Distance to "1" */
vecMetric[k].rTow1 = Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM16[iTabInd0 | 1][0], (*pcInSymb)[i].rChan);
#endif
/* Imaginary part ------------------------------------------- */
#ifdef USE_MAX_LOG_MAP
vecMetric[k + 1].rTow0 =
Minimum2((*pcInSymb)[i].cSig.imag(),
rTableQAM16[BI_00 /* [0 0] */][1],
rTableQAM16[BI_10 /* [1 0] */][1],
(*pcInSymb)[i].rChan, vecSubsetDef1[k + 1]);
vecMetric[k + 1].rTow1 =
Minimum2((*pcInSymb)[i].cSig.imag(),
rTableQAM16[BI_01 /* [0 1] */][1],
rTableQAM16[BI_11 /* [1 1] */][1],
(*pcInSymb)[i].rChan, vecSubsetDef1[k + 1]);
#else
/* Higest bit defined by "vecSubsetDef1" */
iTabInd0 = ((ExtractBit(vecSubsetDef1[k + 1]) & 1) << 1);
/* Distance to "0" */
vecMetric[k + 1].rTow0 = Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM16[iTabInd0][1], (*pcInSymb)[i].rChan);
/* Distance to "1" */
vecMetric[k + 1].rTow1 = Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM16[iTabInd0 | 1][1], (*pcInSymb)[i].rChan);
#endif
}
break;
}
break;
case CParameter::CS_3_SM:
/**********************************************************************/
/* 64QAM SM ***********************************************************/
/**********************************************************************/
/* (i_0 i_1 i_2 q_0 q_1 q_2) =
(y_0,0 y_1,0 y_2,0 y_0,1 y_1,1 y_2,1) */
switch (iLevel)
{
case 0:
for (i = 0, k = 0; i < iInputBlockSize; i++, k += 2)
{
if (bIteration == TRUE)
{
/* Real part -------------------------------------------- */
#ifdef USE_MAX_LOG_MAP
vecMetric[k].rTow0 =
Minimum4((*pcInSymb)[i].cSig.real(),
rTableQAM64SM[BI_000 /* [0 0 0] */][0],
rTableQAM64SM[BI_010 /* [0 1 0] */][0],
rTableQAM64SM[BI_001 /* [0 0 1] */][0],
rTableQAM64SM[BI_011 /* [0 1 1] */][0],
(*pcInSymb)[i].rChan,
vecSubsetDef2[k], vecSubsetDef3[k]);
vecMetric[k].rTow1 =
Minimum4((*pcInSymb)[i].cSig.real(),
rTableQAM64SM[BI_100 /* [1 0 0] */][0],
rTableQAM64SM[BI_110 /* [1 1 0] */][0],
rTableQAM64SM[BI_101 /* [1 0 1] */][0],
rTableQAM64SM[BI_111 /* [1 1 1] */][0],
(*pcInSymb)[i].rChan,
vecSubsetDef2[k], vecSubsetDef3[k]);
#else
/* Lowest bit defined by "vecSubsetDef3" next bit defined
by "vecSubsetDef2" */
iTabInd0 =
(ExtractBit(vecSubsetDef3[k]) & 1) |
((ExtractBit(vecSubsetDef2[k]) & 1) << 1);
vecMetric[k].rTow0 =
Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM64SM[iTabInd0][0], (*pcInSymb)[i].rChan);
vecMetric[k].rTow1 =
Minimum1((*pcInSymb)[i].cSig.real(),
rTableQAM64SM[iTabInd0 | (1 << 2)][0],
(*pcInSymb)[i].rChan);
#endif
/* Imaginary part --------------------------------------- */
#ifdef USE_MAX_LOG_MAP
vecMetric[k + 1].rTow0 =
Minimum4((*pcInSymb)[i].cSig.imag(),
rTableQAM64SM[BI_000 /* [0 0 0] */][1],
rTableQAM64SM[BI_010 /* [0 1 0] */][1],
rTableQAM64SM[BI_001 /* [0 0 1] */][1],
rTableQAM64SM[BI_011 /* [0 1 1] */][1],
(*pcInSymb)[i].rChan,
vecSubsetDef2[k + 1], vecSubsetDef3[k + 1]);
vecMetric[k + 1].rTow1 =
Minimum4((*pcInSymb)[i].cSig.imag(),
rTableQAM64SM[BI_100 /* [1 0 0] */][1],
rTableQAM64SM[BI_110 /* [1 1 0] */][1],
rTableQAM64SM[BI_101 /* [1 0 1] */][1],
rTableQAM64SM[BI_111 /* [1 1 1] */][1],
(*pcInSymb)[i].rChan,
vecSubsetDef2[k + 1], vecSubsetDef3[k + 1]);
#else
/* Lowest bit defined by "vecSubsetDef3" next bit defined
by "vecSubsetDef2" */
iTabInd0 =
(ExtractBit(vecSubsetDef3[k + 1]) & 1) |
((ExtractBit(vecSubsetDef2[k + 1]) & 1) << 1);
/* Calculate distances, imaginary part */
vecMetric[k + 1].rTow0 =
Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM64SM[iTabInd0][1], (*pcInSymb)[i].rChan);
vecMetric[k + 1].rTow1 =
Minimum1((*pcInSymb)[i].cSig.imag(),
rTableQAM64SM[iTabInd0 | (1 << 2)][1],
(*pcInSymb)[i].rChan);
#endif
}
else
{
/* Real part -------------------------------------------- */
vecMetric[k].rTow0 =
Minimum4((*pcInSymb)[i].cSig.real(),
rTableQAM64SM[BI_000 /* [0 0 0] */][0],
rTableQAM64SM[BI_001 /* [0 0 1] */][0],
rTableQAM64SM[BI_010 /* [0 1 0] */][0],
rTableQAM64SM[BI_011 /* [0 1 1] */][0],
(*pcInSymb)[i].rChan);
vecMetric[k].rTow1 =
Minimum4((*pcInSymb)[i].cSig.real(),
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -