C#,数值计算——隐式马尔科夫模型(Hidden Markov Models)的计算方法与源程序

本文主要是介绍C#,数值计算——隐式马尔科夫模型(Hidden Markov Models)的计算方法与源程序,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1 文本格式

using System;

namespace Legalsoft.Truffer
{
    /// <summary>
    /// Hidden Markov Models
    /// </summary>
    public class HMM
    {
        private int fbdone { get; set; }
        private int mstat { get; set; }
        private int nobs { get; set; }
        private int ksym { get; set; }
        private int lrnrm { get; set; }
        private double BIG { get; set; }
        private double BIGI { get; set; }
        private double lhood { get; set; }
        private double[,] a { get; set; }
        private double[,] b { get; set; }
        private int[] obs { get; set; }
        private double[,] alpha { get; set; }
        private double[,] beta { get; set; }
        private double[,] pstate { get; set; }
        private int[] arnrm { get; set; }
        private int[] brnrm { get; set; }

        public HMM(double[,] aa, double[,] bb, int[] obss)
        {
            this.a = aa;
            this.b = bb;
            this.obs = obss;
            this.fbdone = 0;
            this.mstat = a.GetLength(0);
            this.nobs = obs.Length;
            this.ksym = b.GetLength(1);
            this.alpha = new double[nobs, mstat];
            this.beta = new double[nobs, mstat];
            this.pstate = new double[nobs, mstat];
            this.arnrm = new int[nobs];
            this.brnrm = new int[nobs];
            this.BIG = 1.0e20;
            this.BIGI = 1.0 / BIG;

            if (a.GetLength(1) != mstat)
            {
                throw new Exception("transition matrix not square");
            }
            if (b.GetLength(0) != mstat)
            {
                throw new Exception("symbol prob matrix wrong size");
            }
            for (int i = 0; i < nobs; i++)
            {
                if (obs[i] < 0 || obs[i] >= ksym)
                {
                    throw new Exception("bad data in obs");
                }
            }
            for (int i = 0; i < mstat; i++)
            {
                double sum = 0.0;
                for (int j = 0; j < mstat; j++)
                {
                    sum += a[i, j];
                }
                if (Math.Abs(sum - 1.0) > 0.01)
                {
                    throw new Exception("transition matrix not normalized");
                }
                for (int j = 0; j < mstat; j++)
                {
                    a[i, j] /= sum;
                }
            }
            for (int i = 0; i < mstat; i++)
            {
                double sum = 0.0;
                for (int k = 0; k < ksym; k++)
                {
                    sum += b[i, k];
                }
                if (Math.Abs(sum - 1.0) > 0.01)
                {
                    throw new Exception("symbol prob matrix not normalized");
                }
                for (int k = 0; k < ksym; k++)
                {
                    b[i, k] /= sum;
                }
            }
        }

        public double loglikelihood()
        {
            return Math.Log(lhood) + lrnrm * Math.Log(BIGI);
        }

        public void forwardbackward()
        {
            for (int i = 0; i < mstat; i++)
            {
                alpha[0, i] = b[i, obs[0]];
            }
            arnrm[0] = 0;
            for (int t = 1; t < nobs; t++)
            {
                double asum = 0;
                for (int j = 0; j < mstat; j++)
                {
                    double sum = 0.0;
                    for (int i = 0; i < mstat; i++)
                    {
                        sum += alpha[t - 1, i] * a[i, j] * b[j, obs[t]];
                    }
                    alpha[t, j] = sum;
                    asum += sum;
                }
                arnrm[t] = arnrm[t - 1];
                if (asum < BIGI)
                {
                    ++arnrm[t];
                    for (int j = 0; j < mstat; j++)
                    {
                        alpha[t, j] *= BIG;
                    }
                }
            }
            for (int i = 0; i < mstat; i++)
            {
                beta[nobs - 1, i] = 1.0;
            }
            brnrm[nobs - 1] = 0;
            for (int t = nobs - 2; t >= 0; t--)
            {
                double bsum = 0.0;
                for (int i = 0; i < mstat; i++)
                {
                    double sum = 0.0;
                    for (int j = 0; j < mstat; j++)
                    {
                        sum += a[i, j] * b[j, obs[t + 1]] * beta[t + 1, j];
                    }
                    beta[t, i] = sum;
                    bsum += sum;
                }
                brnrm[t] = brnrm[t + 1];
                if (bsum < BIGI)
                {
                    ++brnrm[t];
                    for (int j = 0; j < mstat; j++)
                    {
                        beta[t, j] *= BIG;
                    }
                }
            }
            lhood = 0.0;
            for (int i = 0; i < mstat; i++)
            {
                lhood += alpha[0, i] * beta[0, i];
            }
            lrnrm = arnrm[0] + brnrm[0];
            if (lhood != 0.0)
            {
                while (lhood < BIGI)
                {
                    lhood *= BIG;
                    lrnrm++;
                }
            }
            for (int t = 0; t < nobs; t++)
            {
                double sum = 0.0;
                for (int i = 0; i < mstat; i++)
                {
                    sum += (pstate[t, i] = alpha[t, i] * beta[t, i]);
                }
                // sum = lhood*pow(BIGI, lrnrm - arnrm[t] - brnrm[t]);
                for (int i = 0; i < mstat; i++)
                {
                    pstate[t, i] /= sum;
                }
            }
            fbdone = 1;
        }

        public void baumwelch()
        {
            double[,] bnew = new double[mstat, ksym];
            double[] powtab = new double[10];
            for (int i = 0; i < 10; i++)
            {
                powtab[i] = Math.Pow(BIGI, i - 6);
            }
            if (fbdone != 1)
            {
                throw new Exception("must do forwardbackward first");
            }
            for (int i = 0; i < mstat; i++)
            {
                double denom = 0.0;
                for (int k = 0; k < ksym; k++)
                {
                    bnew[i, k] = 0.0;
                }
                for (int t = 0; t < nobs - 1; t++)
                {
                    double term = (alpha[t, i] * beta[t, i] / lhood) * powtab[arnrm[t] + brnrm[t] - lrnrm + 6];
                    denom += term;
                    bnew[i, obs[t]] += term;
                }
                for (int j = 0; j < mstat; j++)
                {
                    double num = 0.0;
                    for (int t = 0; t < nobs - 1; t++)
                    {
                        num += alpha[t, i] * b[j, obs[t + 1]] * beta[t + 1, j] * powtab[arnrm[t] + brnrm[t + 1] - lrnrm + 6] / lhood;
                    }
                    a[i, j] *= (num / denom);
                }
                for (int k = 0; k < ksym; k++)
                {
                    bnew[i, k] /= denom;
                }
            }
            b = bnew;
            fbdone = 0;
        }

        /// <summary>
        /// Markov Models and Hidden Markov Modeling
        /// </summary>
        /// <param name="atrans"></param>
        /// <param name="xout"></param>
        /// <param name="istart"></param>
        /// <param name="seed"></param>
        /// <exception cref="Exception"></exception>
        public static void markovgen(double[,] atrans, int[] xout, int istart = 0, int seed = 1)
        {
            int m = atrans.GetLength(0);
            int n = xout.Length;
            //double[,] cum = new double[,](atrans);
            double[,] cum = Globals.CopyFrom(atrans);
            Ran ran = new Ran((ulong)seed);
            if (m != atrans.GetLength(1))
            {
                throw new Exception("transition matrix must be square");
            }
            for (int i = 0; i < m; i++)
            {
                for (int ja = 1; ja < m; ja++)
                {
                    cum[i, ja] += cum[i, ja - 1];
                }
                if (Math.Abs(cum[i, m - 1] - 1.0) > 0.01)
                {
                    throw new Exception("transition matrix rows must sum to 1");
                }
            }
            int j = istart;
            xout[0] = j;
            for (int ii = 1; ii < n; ii++)
            {
                double r = ran.doub() * cum[j, m - 1];
                int ilo = 0;
                int ihi = m;
                while (ihi - ilo > 1)
                {
                    int ia = (ihi + ilo) >> 1;
                    if (r > cum[j, ia - 1])
                    {
                        ilo = ia;
                    }
                    else
                    {
                        ihi = ia;
                    }
                }
                xout[ii] = j = ilo;
            }
        }
    }
}
 

2 代码格式

using System;namespace Legalsoft.Truffer
{/// <summary>/// Hidden Markov Models/// </summary>public class HMM{private int fbdone { get; set; }private int mstat { get; set; }private int nobs { get; set; }private int ksym { get; set; }private int lrnrm { get; set; }private double BIG { get; set; }private double BIGI { get; set; }private double lhood { get; set; }private double[,] a { get; set; }private double[,] b { get; set; }private int[] obs { get; set; }private double[,] alpha { get; set; }private double[,] beta { get; set; }private double[,] pstate { get; set; }private int[] arnrm { get; set; }private int[] brnrm { get; set; }public HMM(double[,] aa, double[,] bb, int[] obss){this.a = aa;this.b = bb;this.obs = obss;this.fbdone = 0;this.mstat = a.GetLength(0);this.nobs = obs.Length;this.ksym = b.GetLength(1);this.alpha = new double[nobs, mstat];this.beta = new double[nobs, mstat];this.pstate = new double[nobs, mstat];this.arnrm = new int[nobs];this.brnrm = new int[nobs];this.BIG = 1.0e20;this.BIGI = 1.0 / BIG;if (a.GetLength(1) != mstat){throw new Exception("transition matrix not square");}if (b.GetLength(0) != mstat){throw new Exception("symbol prob matrix wrong size");}for (int i = 0; i < nobs; i++){if (obs[i] < 0 || obs[i] >= ksym){throw new Exception("bad data in obs");}}for (int i = 0; i < mstat; i++){double sum = 0.0;for (int j = 0; j < mstat; j++){sum += a[i, j];}if (Math.Abs(sum - 1.0) > 0.01){throw new Exception("transition matrix not normalized");}for (int j = 0; j < mstat; j++){a[i, j] /= sum;}}for (int i = 0; i < mstat; i++){double sum = 0.0;for (int k = 0; k < ksym; k++){sum += b[i, k];}if (Math.Abs(sum - 1.0) > 0.01){throw new Exception("symbol prob matrix not normalized");}for (int k = 0; k < ksym; k++){b[i, k] /= sum;}}}public double loglikelihood(){return Math.Log(lhood) + lrnrm * Math.Log(BIGI);}public void forwardbackward(){for (int i = 0; i < mstat; i++){alpha[0, i] = b[i, obs[0]];}arnrm[0] = 0;for (int t = 1; t < nobs; t++){double asum = 0;for (int j = 0; j < mstat; j++){double sum = 0.0;for (int i = 0; i < mstat; i++){sum += alpha[t - 1, i] * a[i, j] * b[j, obs[t]];}alpha[t, j] = sum;asum += sum;}arnrm[t] = arnrm[t - 1];if (asum < BIGI){++arnrm[t];for (int j = 0; j < mstat; j++){alpha[t, j] *= BIG;}}}for (int i = 0; i < mstat; i++){beta[nobs - 1, i] = 1.0;}brnrm[nobs - 1] = 0;for (int t = nobs - 2; t >= 0; t--){double bsum = 0.0;for (int i = 0; i < mstat; i++){double sum = 0.0;for (int j = 0; j < mstat; j++){sum += a[i, j] * b[j, obs[t + 1]] * beta[t + 1, j];}beta[t, i] = sum;bsum += sum;}brnrm[t] = brnrm[t + 1];if (bsum < BIGI){++brnrm[t];for (int j = 0; j < mstat; j++){beta[t, j] *= BIG;}}}lhood = 0.0;for (int i = 0; i < mstat; i++){lhood += alpha[0, i] * beta[0, i];}lrnrm = arnrm[0] + brnrm[0];if (lhood != 0.0){while (lhood < BIGI){lhood *= BIG;lrnrm++;}}for (int t = 0; t < nobs; t++){double sum = 0.0;for (int i = 0; i < mstat; i++){sum += (pstate[t, i] = alpha[t, i] * beta[t, i]);}// sum = lhood*pow(BIGI, lrnrm - arnrm[t] - brnrm[t]);for (int i = 0; i < mstat; i++){pstate[t, i] /= sum;}}fbdone = 1;}public void baumwelch(){double[,] bnew = new double[mstat, ksym];double[] powtab = new double[10];for (int i = 0; i < 10; i++){powtab[i] = Math.Pow(BIGI, i - 6);}if (fbdone != 1){throw new Exception("must do forwardbackward first");}for (int i = 0; i < mstat; i++){double denom = 0.0;for (int k = 0; k < ksym; k++){bnew[i, k] = 0.0;}for (int t = 0; t < nobs - 1; t++){double term = (alpha[t, i] * beta[t, i] / lhood) * powtab[arnrm[t] + brnrm[t] - lrnrm + 6];denom += term;bnew[i, obs[t]] += term;}for (int j = 0; j < mstat; j++){double num = 0.0;for (int t = 0; t < nobs - 1; t++){num += alpha[t, i] * b[j, obs[t + 1]] * beta[t + 1, j] * powtab[arnrm[t] + brnrm[t + 1] - lrnrm + 6] / lhood;}a[i, j] *= (num / denom);}for (int k = 0; k < ksym; k++){bnew[i, k] /= denom;}}b = bnew;fbdone = 0;}/// <summary>/// Markov Models and Hidden Markov Modeling/// </summary>/// <param name="atrans"></param>/// <param name="xout"></param>/// <param name="istart"></param>/// <param name="seed"></param>/// <exception cref="Exception"></exception>public static void markovgen(double[,] atrans, int[] xout, int istart = 0, int seed = 1){int m = atrans.GetLength(0);int n = xout.Length;//double[,] cum = new double[,](atrans);double[,] cum = Globals.CopyFrom(atrans);Ran ran = new Ran((ulong)seed);if (m != atrans.GetLength(1)){throw new Exception("transition matrix must be square");}for (int i = 0; i < m; i++){for (int ja = 1; ja < m; ja++){cum[i, ja] += cum[i, ja - 1];}if (Math.Abs(cum[i, m - 1] - 1.0) > 0.01){throw new Exception("transition matrix rows must sum to 1");}}int j = istart;xout[0] = j;for (int ii = 1; ii < n; ii++){double r = ran.doub() * cum[j, m - 1];int ilo = 0;int ihi = m;while (ihi - ilo > 1){int ia = (ihi + ilo) >> 1;if (r > cum[j, ia - 1]){ilo = ia;}else{ihi = ia;}}xout[ii] = j = ilo;}}}
}

这篇关于C#,数值计算——隐式马尔科夫模型(Hidden Markov Models)的计算方法与源程序的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/231534

相关文章

Python并行处理实战之如何使用ProcessPoolExecutor加速计算

《Python并行处理实战之如何使用ProcessPoolExecutor加速计算》Python提供了多种并行处理的方式,其中concurrent.futures模块的ProcessPoolExecu... 目录简介完整代码示例代码解释1. 导入必要的模块2. 定义处理函数3. 主函数4. 生成数字列表5.

C#如何去掉文件夹或文件名非法字符

《C#如何去掉文件夹或文件名非法字符》:本文主要介绍C#如何去掉文件夹或文件名非法字符的问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C#去掉文件夹或文件名非法字符net类库提供了非法字符的数组这里还有个小窍门总结C#去掉文件夹或文件名非法字符实现有输入字

C#之List集合去重复对象的实现方法

《C#之List集合去重复对象的实现方法》:本文主要介绍C#之List集合去重复对象的实现方法,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C# List集合去重复对象方法1、测试数据2、测试数据3、知识点补充总结C# List集合去重复对象方法1、测试数据

C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式

《C#实现将Office文档(Word/Excel/PDF/PPT)转为Markdown格式》Markdown凭借简洁的语法、优良的可读性,以及对版本控制系统的高度兼容性,逐渐成为最受欢迎的文档格式... 目录为什么要将文档转换为 Markdown 格式使用工具将 Word 文档转换为 Markdown(.

Java调用C#动态库的三种方法详解

《Java调用C#动态库的三种方法详解》在这个多语言编程的时代,Java和C#就像两位才华横溢的舞者,各自在不同的舞台上展现着独特的魅力,然而,当它们携手合作时,又会碰撞出怎样绚丽的火花呢?今天,我们... 目录方法1:C++/CLI搭建桥梁——Java ↔ C# 的“翻译官”步骤1:创建C#类库(.NET

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

详解如何使用Python从零开始构建文本统计模型

《详解如何使用Python从零开始构建文本统计模型》在自然语言处理领域,词汇表构建是文本预处理的关键环节,本文通过Python代码实践,演示如何从原始文本中提取多尺度特征,并通过动态调整机制构建更精确... 目录一、项目背景与核心思想二、核心代码解析1. 数据加载与预处理2. 多尺度字符统计3. 统计结果可

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元

SpringBoot整合Sa-Token实现RBAC权限模型的过程解析

《SpringBoot整合Sa-Token实现RBAC权限模型的过程解析》:本文主要介绍SpringBoot整合Sa-Token实现RBAC权限模型的过程解析,本文给大家介绍的非常详细,对大家的学... 目录前言一、基础概念1.1 RBAC模型核心概念1.2 Sa-Token核心功能1.3 环境准备二、表结

C#使用MQTTnet实现服务端与客户端的通讯的示例

《C#使用MQTTnet实现服务端与客户端的通讯的示例》本文主要介绍了C#使用MQTTnet实现服务端与客户端的通讯的示例,包括协议特性、连接管理、QoS机制和安全策略,具有一定的参考价值,感兴趣的可... 目录一、MQTT 协议简介二、MQTT 协议核心特性三、MQTTNET 库的核心功能四、服务端(BR