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

📄 viterbi.cpp.txt

📁 OFDM信道编码
💻 TXT
字号:
*
** File:Viterbi.cpp
** 功能:给定HMM和观察序列,求最可能的状态
*/

//#include "StdAfx.h"
#include <math.h>
#include "hmm.h"
#include "nrutil.h"

#define VITHUGE 100000000000.0

/**************************************************************************
** 函数名称:Viterbi
** 功能:Viterbi算法
** 参数:phmm:HMM结构指针
** T:观察值的个数
** O:观察序列
** delta,psi为中间变量
** q:求得的最佳状态序列
** pprob:概率
**/
void Viterbi(HMM *phmm, int T, int *O, double **delta, int **psi, 
int *q, double *pprob)
{
int i, j; /* 状态下标 */
int t; /* 时间下标 */ 

int maxvalind;
double maxval, val;

/* 1. 初始化 */

for (i = 1; i <= phmm->N; i++) 
{
delta[1] = phmm->pi * (phmm->B[O[1]]);
psi[1] = 0;
} 

/* 2. 递归 */

for (t = 2; t <= T; t++) 
{
for (j = 1; j <= phmm->N; j++) 
{
maxval = 0.0;
maxvalind = 1; 
for (i = 1; i <= phmm->N; i++) 
{
val = delta[t-1]*(phmm->A[j]);
if (val > maxval) {
maxval = val; 
maxvalind = i; 
}
}

delta[t][j] = maxval*(phmm->B[j][O[t]]);
psi[t][j] = maxvalind; 

}
}

/* 3. 终止 */

*pprob = 0.0;
q[T] = 1;
for (i = 1; i <= phmm->N; i++) 
{
if (delta[T] > *pprob) 
{
*pprob = delta[T]; 
q[T] = i;
}
}

/* 4. Path (state sequence) backtracking */

for (t = T - 1; t >= 1; t--)
q[t] = psi[t+1][q[t+1]];

}

/**************************************************************************
** 函数名称:ViterbiLog
** 功能:Viterbi算法
** 参数:phmm:HMM结构指针
** T:观察值的个数
** O:观察序列
** delta,psi为中间变量
** q:求得的最佳状态序列
** pprob:概率
**/
void ViterbiLog(HMM *phmm, int T, int *O, double **delta, int **psi,
int *q, double *pprob)
{
int i, j; /* 状态下标 */
int t; /* 时间下标 */

int maxvalind;
double maxval, val;
double **biot;

/* 0. 预处理 */

for (i = 1; i <= phmm->N; i++) 
phmm->pi = log(phmm->pi);
for (i = 1; i <= phmm->N; i++) 
for (j = 1; j <= phmm->N; j++) 
{
phmm->A[j] = log(phmm->A[j]);
}

biot = dmatrix(1, phmm->N, 1, T);
for (i = 1; i <= phmm->N; i++) 
for (t = 1; t <= T; t++) 
{
biot[t] = log(phmm->B[O[t]]);
}

/* 1. 初始化 */

for (i = 1; i <= phmm->N; i++) 
{
delta[1] = phmm->pi + biot[1];
psi[1] = 0;
}

/* 2. 递归 */

for (t = 2; t <= T; t++) 
{
for (j = 1; j <= phmm->N; j++) 
{
maxval = -VITHUGE;
maxvalind = 1;
for (i = 1; i <= phmm->N; i++) 
{
val = delta[t-1] + (phmm->A[j]);
if (val > maxval) 
{
maxval = val;
maxvalind = i;
}
}

delta[t][j] = maxval + biot[j][t]; 
psi[t][j] = maxvalind;

}
}

/* 3. 终止 */

*pprob = -VITHUGE;
q[T] = 1;
for (i = 1; i <= phmm->N; i++) 
{
if (delta[T] > *pprob) 
{
*pprob = delta[T];
q[T] = i;
}
}


/* 4. 回溯 */

for (t = T - 1; t >= 1; t--)
q[t] = psi[t+1][q[t+1]];

}

⌨️ 快捷键说明

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