隐马尔可夫模型的forward算法的c实现

隐马尔可夫模型问题有3个,即评估、解码、学习。其中评估问题描述为给定一个隐马尔可夫模型参数和一个观察序列,求该观察序列的概率。我们使用前向算法(forward algorith)来解决这个问题。其c代码如下:

hmm.h文件

#ifndef _HMM_H_
#define _HMM_H_

//宏定义
#define NN 3
#define MM 4
#define length 3

typedef struct {
int N;  /* 隐藏状态数目;Q={0,1,2,…,N-1} */
int M;  /* 观察符号数目; V={0,1,2,…,M-1}*/

/* 状态转移矩阵A[0..NN-1][0..NN-1]. a[i][j] 是从t时刻状态i到t+1时刻状态j的转移概率 */
double(*A)[NN] ;  

/* 混淆矩阵B[0..N-1][0..M-1]. b[j][k]在状态j时观察到符合k的概率。*/
double(*B)[MM];

/* 初始向量pi[0..N-1],pi[i] 是初始状态概率分布 */
double*pi;
} HMM;

double Forward(HMM *phmm,int T,int *O);

#endif

hmm.c文件

#include <stdio.h>
#include <stdlib.h>
#include <malloc.h>
#include <math.h>
#include "hmm.h"/* 函数参数说明:<br> *phmm:已知的HMM模型;T:观察符号序列长度;*O:观察序列;<br>*/<br>
double alpha[length][NN];     //前向算法局部概率变量<br><br>double Forward(HMM *phmm,int T,int *O)<br>{<br>        int     i, j;     /* 状态索引 */<br>        int     t;        /* 时间索引 */<br>     double sum;     /*求局部概率时的中间值 */  <br>        double pprob;//返回的值<br><br>       /* 1. 初始化:计算t=0时刻所有状态的局部概率alpha: */<br>        for (i = 0; i <= (phmm->N)-1; i++)<br>                alpha[0][i] = phmm->pi[i]* phmm->B[i][O[0]];<br><br>          /* 2. 归纳:递归计算每个时间点,t=2,… ,T时的局部概率 */<br><br>        for (t = 0; t < T-1; t++) //这循环里算T-1次,前面初始化算了1次,共T次<br>       {<br>                for (j = 0; j <= (phmm->N)-1; j++) //在给定的时刻,所有状态分别到其他所有状态的转移概率之和<br>             {<br>                        sum = 0.0;<br>                        for (i = 0; i <= (phmm->N)-1; i++)//在给定的时刻和给定状态,其他所有状态到给定状态的转移概率之和<br>                     {<br>                           sum += alpha[t][i]* (phmm->A[i][j]);<br>                     }                                 <br>                        alpha[t+1][j] = sum*(phmm->B[j][O[t+1]]);//计算t+1时刻看到观察序号O[t+1]的所有状态的局部概率alpha<br>                }<br>        }<br><br>         /* 3. 终止:观察序列的概率等于T时刻所有局部概率之和*/<br>        pprob = 0.0;<br>        for (i = 0; i <= (phmm->N)-1; i++)<br>                pprob += alpha[T-1][i];<br>     return pprob;<br>}



main.c文件

#include <stdio.h><br>#include <stdlib.h><br>#include "hmm.h"<br><br>double A[NN][NN]={                 <br>                  {0.500,0.375,0.125},<br>                  {0.250,0.125,0.625},<br>                  {0.250,0.375,0.375}<br>               };<br>double B[NN][MM]={                  <br>                      {0.60,0.20,0.15,0.05},<br>                     {0.25,0.25,0.25,0.25},<br>                     {0.05,0.10,0.35,0.50}<br>                };<br>double pi[NN]={0.63,0.17,0.20};<br><br>HMM hmm1={NN,MM,A,B,pi};<br><br>int Seq[length]={0,2,3};<br><br>int main(int argc, char *argv[])<br>{  <br>    double pprob=0.0;<br>      pprob = Forward(&hmm1, length, Seq); <br>    printf("the probabilty of observing a sequence given a HMM model parameter:\n");<br>   printf("%.12f\n",pprob);<br>}

运行结果如下:

the probabilty of observing a sequence given a HMM model parameter:

0.026901406250



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值