⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 metrics.c

📁 这是一个c++编写的WCDMA链路采用RAKE接收的方针源代码
💻 C
字号:
/* | | Copyright disclaimer: |   This software was developed at the National Institute of Standards |   and Technology by employees of the Federal Government in the course |   of their official duties. Pursuant to title 17 Section 105 of the |   United States Code this software is not subject to copyright |   protection and is in the public domain. | |   We would appreciate acknowledgement if the software is used. |*//* | Project:     WCDMA simulation environment | Module:      Viterbi path metric calculation. | Author:      Tommi Makelainen, NIST | Date:        January 11, 1999 | | History: |              January 11, 1999 Tommi Makelainen |                      Initial version. | |              February 16, 1999 Tommi Makelainen |                      Corrected branch metric calculation for soft |			bits. | */#include <stdio.h>#include <stdlib.h>#include <math.h>#include "metrics.h" /* --------------------------------------------------------------- *//* * Function:    MetricTable_R1o3_Init * Desc.:       Metric table initialization for Viterbi algorithm. *		Constrain length K=9 and coding rate 1/3 are fixed. * * Note: *              'no_of_probabilities' can get max value of 8. */void MetricTable_R1o3_Init(          MetricTable* this,          enum metric_type_type metric_type,          double bit_probabilities_0[],          double bit_probabilities_1[],          int no_of_probabilities){    int i, bit;    double temp;    this->Metric_Type = metric_type;    if(metric_type == HAMMING_METRIC) {		this->Metric_Table[0][0] = 0.0;		this->Metric_Table[1][0] = -1.0;		this->Metric_Table[2][0] = -1.0;		this->Metric_Table[3][0] = -2.0;		this->Metric_Table[4][0] = -1.0;		this->Metric_Table[5][0] = -2.0;		this->Metric_Table[6][0] = -2.0;		this->Metric_Table[7][0] = -3.0;		this->Metric_Table[0][1] = -1.0;		this->Metric_Table[1][1] = 0.0;		this->Metric_Table[2][1] = -2.0;		this->Metric_Table[3][1] = -1.0;		this->Metric_Table[4][1] = -2.0;		this->Metric_Table[5][1] = -1.0;		this->Metric_Table[6][1] = -3.0;		this->Metric_Table[7][1] = -2.0;		this->Metric_Table[0][2] = -1.0;		this->Metric_Table[1][2] = -2.0;		this->Metric_Table[2][2] = 0.0;		this->Metric_Table[3][2] = -1.0;		this->Metric_Table[4][2] = -2.0;		this->Metric_Table[5][2] = -3.0;		this->Metric_Table[6][2] = -1.0;		this->Metric_Table[7][2] = -2.0;		this->Metric_Table[0][3] = -2.0;		this->Metric_Table[1][3] = -1.0;		this->Metric_Table[2][3] = -1.0;		this->Metric_Table[3][3] = 0.0;		this->Metric_Table[4][3] = -3.0;		this->Metric_Table[5][3] = -2.0;		this->Metric_Table[6][3] = -2.0;		this->Metric_Table[7][3] = -1.0;		this->Metric_Table[0][4] = -1.0;		this->Metric_Table[1][4] = -2.0;		this->Metric_Table[2][4] = -2.0;		this->Metric_Table[3][4] = -3.0;		this->Metric_Table[4][4] = 0.0;		this->Metric_Table[5][4] = -1.0;		this->Metric_Table[6][4] = -1.0;		this->Metric_Table[7][4] = -2.0;		this->Metric_Table[0][5] = -2.0;		this->Metric_Table[1][5] = -1.0;		this->Metric_Table[2][5] = -3.0;		this->Metric_Table[3][5] = -2.0;		this->Metric_Table[4][5] = -1.0;		this->Metric_Table[5][5] = 0.0;		this->Metric_Table[6][5] = -2.0;		this->Metric_Table[7][5] = -1.0;		this->Metric_Table[0][6] = -2.0;		this->Metric_Table[1][6] = -3.0;		this->Metric_Table[2][6] = -2.0;		this->Metric_Table[3][6] = -2.0;		this->Metric_Table[4][6] = -1.0;		this->Metric_Table[5][6] = -2.0;		this->Metric_Table[6][6] = 0.0;		this->Metric_Table[7][6] = -1.0;		this->Metric_Table[0][7] = -3.0;		this->Metric_Table[1][7] = -2.0;		this->Metric_Table[2][7] = -2.0;		this->Metric_Table[3][7] = -1.0;		this->Metric_Table[4][7] = -2.0;		this->Metric_Table[5][7] = -1.0;		this->Metric_Table[6][7] = -1.0;		this->Metric_Table[7][7] = 0.0;		return;    }    if (metric_type == SOFT_METRIC) {        /*         * Convert bit probabilities for soft metrics to suitable branch         * metric values.         *    branch_metric = 2 * log2( p(rx_symbol|tx_symbol) - 0.05)         * Channel can be also non-symmetric, so the probabilities for 0         * and 1 can be different.         */        for (i=0; i < no_of_probabilities; i++) {            if (bit_probabilities_0[i] < 0.1) {              this->Metric_Table[i][0] = -8.0;            } else {              this->Metric_Table[i][0] = 0 -                  floor(abs(2 * log(bit_probabilities_0[i] - 0.1 + 0.05)));            }        }        for (i=0; i < no_of_probabilities; i++) {            if (bit_probabilities_1[i] < 0.1) {              this->Metric_Table[i][1] = -8.0;            } else {              this->Metric_Table[i][1] = 0 -                  floor(abs(2 * log(bit_probabilities_1[i] - 0.1 + 0.05)));            }        }#ifdef WCDMA_DEBUG_OUTPUT        printf("\nSoft probability branch metrices: \n");        for (i=0; i < no_of_probabilities; i++) {            printf("[%d][0] = %g, [%d][1] = %g \n",                i, this->Metric_Table[i][0], i, this->Metric_Table[i][1]);        } /* for */        printf("\n");#endif /* WCDMA_DEBUG_OUTPUT */        return;    }    printf("invalid metric type passed to metric builder\n");    return;	}/* --------------------------------------------------------------- *//* * Function:    MetricTable_R1o2_Init * Desc.:       Metric table initialization for Viterbi algorithm. *		Constrain length K=9 and coding rate 1/2 are fixed. * * Note: *              'no_of_probabilities' can get max value of 8. */void MetricTable_R1o2_Init(          MetricTable* this,          enum metric_type_type metric_type,          double bit_probabilities_0[],          double bit_probabilities_1[],          int no_of_probabilities){    int i, bit;    double temp;    this->Metric_Type = metric_type;    if(metric_type == HAMMING_METRIC) {		this->Metric_Table[0][0] = 0.0;		this->Metric_Table[1][0] = -1.0;		this->Metric_Table[2][0] = -1.0;		this->Metric_Table[3][0] = -2.0;		this->Metric_Table[0][1] = -1.0;		this->Metric_Table[1][1] = 0.0;		this->Metric_Table[2][1] = -2.0;		this->Metric_Table[3][1] = -1.0;		this->Metric_Table[0][2] = -1.0;		this->Metric_Table[1][2] = -2.0;		this->Metric_Table[2][2] = 0.0;		this->Metric_Table[3][2] = -1.0;		this->Metric_Table[0][3] = -2.0;		this->Metric_Table[1][3] = -1.0;		this->Metric_Table[2][3] = -1.0;		this->Metric_Table[3][3] = 0.0;		return;    }    if (metric_type == SOFT_METRIC) {        /*         * Convert bit probabilities for soft metrics to suitable branch         * metric values.         *    branch_metric = 2 * log2( p(rx_symbol|tx_symbol) - 0.05)         * Channel can be also non-symmetric, so the probabilities for 0         * and 1 can be different.         */        for (i=0; i < no_of_probabilities; i++) {            if (bit_probabilities_0[i] < 0.1) {              this->Metric_Table[i][0] = -8.0;            } else {              this->Metric_Table[i][0] = 0 -                  floor(abs(2 * log(bit_probabilities_0[i] - 0.1 + 0.05)));            }        }        for (i=0; i < no_of_probabilities; i++) {            if (bit_probabilities_1[i] < 0.1) {              this->Metric_Table[i][1] = -8.0;            } else {              this->Metric_Table[i][1] = 0 -                  floor(abs(2 * log(bit_probabilities_1[i] - 0.1 + 0.05)));            }        }#ifdef WCDMA_DEBUG_OUTPUT        printf("\nSoft probability branch metrices: \n");        for (i=0; i < no_of_probabilities; i++) {            printf("[%d][0] = %g, [%d][1] = %g \n",                i, this->Metric_Table[i][0], i, this->Metric_Table[i][1]);        } /* for */        printf("\n");#endif /* WCDMA_DEBUG_OUTPUT */        return;    }    printf("invalid metric type passed to metric builder\n");    return;	}/* --------------------------------------------------------------- *//* * Function:    MetricTable_R1o3_SoftSymbolMetric * Desc.:       Soft metric calculation. The metric is calculated *		as an euclidean distance between tx and rx symbols. * * Note: */double MetricTable_R1o3_SoftSymbolMetric(          MetricTable* this,          int rx_symbol,          int tx_symbol) {  int rx_bit1, rx_bit2, rx_bit3, tx_bit1, tx_bit2, tx_bit3;  double metric_val;                                 /*   * Decompose rx_symbol into bits   */  rx_bit1 = (rx_symbol >> 2) & 0x1;  rx_bit2 = (rx_symbol >> 1) & 0x1;  rx_bit3 = rx_symbol & 0x1;  /*   * Decompose tx_symbol into bits     */  tx_bit1 = (tx_symbol >> 2) & 0x1;  tx_bit2 = (tx_symbol >> 1) & 0x1;  tx_bit3 = tx_symbol & 0x1;  /*   * Look up bit metrics and add them together      */  metric_val = this->Metric_Table[rx_bit1][tx_bit1] 			+ this->Metric_Table[rx_bit2][tx_bit2]                        + this->Metric_Table[rx_bit3][tx_bit3];  return(metric_val);};/* --------------------------------------------------------------- *//* * Function:    MetricTable_R1o2_SoftSymbolMetric * Desc.:       Soft metric calculation. The metric is calculated *		as an euclidean distance between tx and rx symbols. * * Note: */double MetricTable_R1o2_SoftSymbolMetric(          MetricTable* this,          int rx_symbol,          int tx_symbol) {  int rx_bit1, rx_bit2, tx_bit1, tx_bit2;  double metric_val;                                 /*   * Decompose rx_symbol into bits   */  rx_bit1 = (rx_symbol >> 1) & 0x1;  rx_bit2 = rx_symbol & 0x1;  /*   * Decompose tx_symbol into bits     */  tx_bit1 = (tx_symbol >> 1) & 0x1;  tx_bit2 = tx_symbol & 0x1;  /*   * Look up bit metrics and add them together      */  metric_val = this->Metric_Table[rx_bit1][tx_bit1] 			+ this->Metric_Table[rx_bit2][tx_bit2];  return(metric_val);};/* --------------------------------------------------------------- *//* * Function:    MetricTable_R1o2_GetBranchMetric * Desc.:       Returns a branch metric value for a given tx and rx *		symbols. * * Note: */double MetricTable_R1o2_GetBranchMetric(          MetricTable* this,          int rx_symbol,          double soft_metric,          int tx_symbol) {  if(this->Metric_Type == SOFT_METRIC) {        return( /* soft_metric * */            MetricTable_R1o2_SoftSymbolMetric(this, rx_symbol, tx_symbol) );  } else {						return(this->Metric_Table[rx_symbol][tx_symbol]);  }};  /* --------------------------------------------------------------- *//* * Function:    MetricTable_R1o3_GetBranchMetric * Desc.:       Returns a branch metric value for a given tx and rx *		symbols. * * Note: */double MetricTable_R1o3_GetBranchMetric(          MetricTable* this,          int rx_symbol,          double soft_metric,          int tx_symbol) {  if(this->Metric_Type == SOFT_METRIC) {        return( /* soft_metric * */            MetricTable_R1o3_SoftSymbolMetric(this, rx_symbol, tx_symbol) );  } else {						return(this->Metric_Table[rx_symbol][tx_symbol]);  }};  /* --------------------------------------------------------------- */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -