`

Viterbi 算法应用实现

阅读更多

算法简介:

Viterbi 算法又叫维特比算法,其是HMM模型中在给出观测序列O,以及状态转移举证M 和 状态-观测矩阵Q之后,求解能够最佳解释序列O的状态序列S的一种动态规划算法。

具体如下图所示:

其中:

 

  •   标记为O的 [0|1] 序列是观测序列, 
  •   标记为S的序列中横向的箭头即状态在根据转移矩阵M进行转移,
  •   其中S序列与O序列之间向下的箭头表示根据状态生成观测的概率,也即Q矩阵。

假设我们已知观测序列O,即图片Bottom位置的0、1序列,则图片Top位置的用红框框起来的0、1序列就是对应的S序列,即我们所说的在给定矩阵M和Q之后,能最佳地解释O的序列。

 

算法实现:

算法的实现也很简单,主要包含两步:

1. 从前到后遍历O序列,根据观测生成的方式,计算每个观测的最大生成概率。

    在计算过程中,当前观测只依赖于上一个观测的结果,即马氏性。

    同时记录当前状态最有可能的上一个状态。

2. 从后向前回溯,得到序列S

    根据1中在每个观测点记录的上一个最佳状态进行回溯。

 

具体实现如下:

/* ========================================================
 *   Copyright (C) 2014 All rights reserved.
 *   
 *   filename : viterbi.c
 *   author   : ***
 *   date     : 2014-12-19
 *   info     : 
 * ======================================================== */

#include <math.h>
#include <string.h>
#include "viterbi.h"

/* ****************************************
 * @param l   : input 0|1 vector 
 * @param o   : output[smoothed] 0|1 vector
 * @param n   : vector length
 * @param r_t : rate for stat <--> stat
 * @param r_o : rate for stat <--> observ
 * ****************************************/
int viterbi(int * l, int * o, int n, int r_t, int r_o){
    // check params 
    if (!l || !o || r_t < 1 || r_o < 1){
        // return fail
        return -1;
    }

    int i = 0;
    double r_t_ = log(r_t);
    double r_o_ = log(r_o);
    double ls0 = 0.0, ls1 = 0.0, cs0 = 0.0, cs1 = 0.0;
    double ps0 = 0.0, ps1 = 0.0;

    // prev_state for trace back
    int (*pre_s)[2] = (int(*)[2])malloc(sizeof(int[2]) * n);

    // init pre_state and output vector
    memset(pre_s, 0, sizeof(int[2]) * n);
    memset(o, 0, sizeof(int) * n);

    // init the begin stat distribute
    ls0 = (l[0] == 0 ? r_o_ : 0.0);
    ls1 = (l[0] == 1 ? r_o_ : 0.0);

    // pass through to calculate max prob
    for (i = 1; i < n ; i++){
        ps0 = ls0 + r_t_ + (l[i] == 0 ? r_o_ : 0.0);
        ps1 = ls1 +        (l[i] == 0 ? r_o_ : 0.0);
        if (ps0 >= ps1){
            cs0 = ps0; pre_s[i][0] = 0;
        }
        else{
            cs0 = ps1; pre_s[i][0] = 1;
        }
        ps0 = ls0 +        (l[i] == 1 ? r_o_ : 0.0);
        ps1 = ls1 + r_t_ + (l[i] == 1 ? r_o_ : 0.0);
        if (ps0 >= ps1){
            cs1 = ps0; pre_s[i][1] = 0;
        }
        else{
            cs1 = ps1; pre_s[i][1] = 1;
        }
        ls0 = cs0; ls1 = cs1;
    }

    // end state with the max prob
    o[n - 1] = cs0 >= cs1 ? 0 : 1;

    // trace back for prev state
    for (i = n - 2; i >= 0; i--){
        o[i] = pre_s[i + 1][o[i + 1]];
    }

    // free the trace pre states
    free(pre_s);
    pre_s = NULL;
    
    // return success
    return 0;
}

 

测试代码如下:

int main(){
    int a[15] = {0,0,1,0,0,1,1,1,0,1,1,0,0,0,0};
    int b[15] = {0,0,1,0,0,1,1,1,0,1,1,0,0,0,0};
    int c = viterbi(a,b,15,10,5);
    int i = 0;
    printf("before smooth:\n");
    for (; i < 15; i++){
        printf("%d ", a[i]);
    }
    printf("\n");
    printf("after smooth:\n");
    for (i = 0; i < 15; i++){
        printf("%d ", b[i]);
    }
    printf("\n");
}

 

结果如下:

before smooth:
0 0 1 0 0 1 1 1 0 1 1 0 0 0 0 
after smooth:
0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 

 

结果中显示原始序列中第3位置的“1”被平滑成“0”,原始序列中第9位置的“0”被平滑成"1"。

 

该算法在处理时序异常检测结果中的异常序列十分有用。

可以将平滑后的连续“1” 看成一个异常事件,而不用针对每个检测到的异常点单独处理。

  • 大小: 14.8 KB
1
0
分享到:
评论
2 楼 liuzhiqiangruc 2015-06-03  
.h 文件里就一行:
就是一个函数申明而已
int viterbi(int * l, int * o, int n, int r_t, int r_o);
1 楼 yifangt 2015-06-03  
Where is your viterbi.h file, please?

相关推荐

    卷积编码及Viterbi 解码的FPGA 实现及应用

    摘要:卷积码在现代无线通信系统中应用十分广泛,Viterbi译码是常用的一种对卷积码的译码算法。介绍了卷积编码及Viterbi串行解码的原理及其FPGA的实现。在保证系统性能的前提下讨论了分帧式编解码在实际系统中的应用...

    数据挖掘18大算法实现以及其他相关经典DM算法

    CART算法的全称是分类回归树算法,他是一个二元分类,采用的是类似于熵的基尼指数作为分类决策,形成决策树后之后还要进行剪枝,我自己在实现整个算法的时候采用的是代价复杂度算法,详细介绍链接 KNN K最近邻算法...

    一种应用于LTE系统的Viterbi译码算法

    LTE(long term evolution,长期演进)系统中采用了咬尾卷积码和Turbo码来实现前向纠错,Viterbi译码是卷积码的一种杰出的译码算法,它是一种最大似然译码方法。本文基于LTE系统中的咬尾卷积码,详细分析了几种较...

    GMSK调制解调器 matlab viterbi解调采用维特比解调性能具有很大优势 GMSK调制解调器是一种使用Gaussian

    在GMSK调制解调器中,Viterbi解调是一种常用的解调方法,它通过使用Viterbi算法来提高解调性能。 GMSK调制是一种数字调制技术,它在调制过程中使用高斯滤波器来实现信号的平滑过渡。这种调制技术常用于无线通信系统...

    基于FPGA的Viterbi译码器设计及实现

    Viterbi算法是一种似然译码算法。在码的约束度较小时,它比其它概率译码算法效率更高、速度更快,译码器的硬件结构比较简单。随着可编程逻辑技术的不断发展,其高密度、低功耗、使用灵活、设计快速、成本低廉、现场...

    一种基于FPGA的Viterbi译码器优化算法

    卷积码有三种译码方法:门限译码、概率译码和Viterbi算法,其中Viterbi算法是一种基于网格图的似然译码算法,是卷积码的译码方式,具有效率高、速度快等优点。从工程应用角度看,对Viterbi译码器的性能*价指标主要有...

    通信与网络中的高速Viterbi译码器的优化和实现

    关键词:卷积码 Viterbi译码 ACS 路径度量存储 FPGA实现Viterbi算法是一种基于最大后验概率的卷积译码算法,应用广泛。CDMA的IS-95标准和WCDMA 3 GPP标准将卷积码作为高速实时数据传输的信道纠错编码,使Viterbi...

    EDA/PLD中的一种基于FPGA的Viterbi译码器优化算法

    卷积码有三种译码方法:门限译码、概率译码和Viterbi算法,其中Viterbi算法是一种基于网格图的最大似然译码算法,是卷积码的最佳译码方式,具有效率高、速度快等优点。从工程应用角度看,对Viterbi译码器的性能*价...

    通信与网络中的卷积编码及Viterbi 解码的FPGA 实现及应用

    摘要:卷积码在现代无线通信系统中应用十分广泛,Viterbi译码是最常用的一种对卷积码的译码算法。介绍了卷积编码及Viterbi串行解码的原理及其FPGA的实现。在保证系统性能的前提下讨论了分帧式编解码在实际系统中的...

    EDA/PLD中的基于FPGA的Viterbi译码器设计及实现

    Viterbi算法是一种最大似然译码算法。在码的约束度较小时,它比其它概率译码算法效率更高、速度更快,译码器的硬件结构比较简单。随着可编程逻辑技术的不断发展,其高密度、低功耗、使用灵活、设计快速、成本低廉、...

    基于DSP的信道译码算法优化

    本文以在数字通信系统中应用广泛的Viterbi算法为例,简述Viterbi算法的基本原理和目标处理器(TMS320C6211)的处理能力;介绍C6000软件编程及优化的步骤,并提出一些具体的优化策略和技巧。 虽然Texas Instrument...

    从FPGA实现的角度对大约束度Viterbi译码器中路径存储单元的设计

    1 引言 Viterbi译码算法是一种最大似然译码算法,目前广泛应用于各种数据传输系统,特别是卫星通信和移动通信系统中。近年来随着FPGA技术的迅速发展,使得基于FPGA实现Viterbi译码的算法成为研究的热点。  由于...

    可编程Viterbi译码器设计与实现

    Viterbi译码是一种最大似然译码算法,不仅译码速度快,而且其硬件实现简单。提出了一种专用指令集处理器架构,能够支持多种约束长度的Viterbi译码,为通信系统在信道编解码方面做出了有益的尝试。设计了专用的处理器...

    单片机与DSP中的基于DSP的信道译码算法优化

    本文以在数字通信系统中应用广泛的Viterbi算法为例,简述Viterbi算法的基本原理和目标处理器(TMS320C6211)的处理能力;介绍C6000软件编程及优化的步骤,并提出一些具体的优化策略和技巧。 关键词:Viterbi算法 TMS...

    卷积码及其维特比译码算法的软件实现 (2003年)

    提出了数字通信系统中在信道受到干扰时信道译码器检测或修正解调器送来错误信息的一种软件实现方案,该方案应用Visual C++6.0软件技术实现了卷积码编码器和维特比译码器功能,它不仅译码算法简单、易实现,而且可以...

    大约束度Viterbi译码器中路径存储单元的设计

     Viterbi译码算法是一种最大似然译码算法,目前广泛应用于各种数据传输系统,特别是卫星通信和移动通信系统中。近年来随着FPGA技术的迅速发展,使得基于FPGA实现Viterbi译码的算法成为研究的热点。  由于Viterbi...

    应用基扩展模型的混合信号单通道盲分离算法 (2015年)

    针对传统最小均方误差逐幸存路径处理( LMS-P SP )单通道盲分离算法...最后采用Viterbi算法对混合信号进行序列估计,从而实现时变信道下混合信号的单通道盲分离。仿真结果表明,对于2路混合QPSK信号,在相同仿真条件下,BEM

    基于多符号差分相关的CPM非相干解调算法 (2007年)

    从理论上分析算法在CPM调制解调系统中的应用、性能和可实现性,并以高进制、低调制指数的CPM信号为例,通过数值仿真验证了理论结果。在CPM非相干解调中考虑多符号差分相关,能够将复杂理论向实际应用简化,以最小的...

    em算法matlab代码-matlab_projects:Matlab代码以及我正在学习/测试的算法示例

    例如,将em.m算法应用于离散的两枚硬币抛硬币问题,其中我们不知道使用哪枚硬币抛硬币,但知道结果。 em_gaussian.m包含用于计算一维2矩高斯分布的均值和方差的代码。 viterbi,Baum-welch和前向后的实现是基于以下...

    RCS信道快速载波同步设计 (2014年)

    为了实现RCS信道快速载波同步,在帧结构中专门设计了惟一字,将基于惟一字的载波同步算法和基于Viterbi-Viterbi算法的二次相位估计相结合,设计了易于实现的载波同步方案。经Matlab仿真,证明了方案的性能。所用设计...

Global site tag (gtag.js) - Google Analytics