Math.Net Numerics has capability to conduct Markov Chair Monte Carlo simulations, yet the document is very sparse. The only examples I found are in F# (see below). In this note, I attempt to port these examples into C# and hope others may find it useful in their research. Note that there are some errors in the original F# code, and this note corrected them. The ported code has been published as ASP.NET web services at x.ecoruse.org. Thus, one can easily copied over to any windows or web development projects.

Ported C# Code

using System;
using System.Collections.Generic;
using System.Web;
using System.Web.Services;
using MathNet.Numerics.Distributions;
using MathNet.Numerics.Statistics;
using MathNet.Numerics.Random;
using MathNet.Numerics.Statistics.Mcmc; [WebService(Namespace = "http://x.ecourse.org")]
[WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
[System.Web.Script.Services.ScriptService]
public class MCMC : System.Web.Services.WebService { public MCMC () {} [WebMethod(Description = "Sampling Beta variable via rejection")]
public double[] BetaViaRejection(double a, double b, int N) {
    var rnd = new MersenneTwister();
    var beta = new Beta(a, b);
    var uniform = new ContinuousUniform(0.0, 1.0, rnd);
    var rs = new RejectionSampler(
            (x => Math.Pow(x, beta.A - 1.0) * Math.Pow(1.0 - x, beta.B - 1.0)),
            (x => 0.021), (() => uniform.Sample()));
    var arr= rs.Sample(N);
     return arr;
    //string result = "Theoretical Mean:" + beta.Mean + " vs Sample Mean: "
        + Statistics.Mean(arr) + ";" + "Theoretical StarndardDeviation:"
        + beta.StdDev + " vs Sample StandardDeviation: "
        + Statistics.StandardDeviation(arr) + ";" + " Acceptance Rate:" + rs.AcceptanceRate;
    //return result;
} [WebMethod(Description = "Sampling a normal variable via Metropolis")]
public double[] NormaViaMetropolis(double mean, double stdev, int N)
{
    var rnd = new MersenneTwister();
    var normal = new Normal(mean, stdev);     var ms = new MetropolisHastingsSampler(0.1, x => Math.Log(normal.Density(x)),
                                                (x,y)=>Normal.PDFLn(x,0.3,y),
                                                 x => Normal.Sample(rnd, x, 0.3), 20);     var arr = ms.Sample(N);
     return arr;
    //string result = "Theoretical Mean:" + beta.Mean + " vs Sample Mean: " 
        + Statistics.Mean(arr) + ";" + "Theoretical StarndardDeviation:"
        + beta.StdDev + " vs Sample StandardDeviation: "
        + Statistics.StandardDeviation(arr) + ";" + " Acceptance Rate:" + rs.AcceptanceRate;
     //return result;
} [WebMethod(Description = "Sampling a normal variable via Metropolis symmetric proposal")]
public double[] NormaViaMetropolisSymmetricProposal(double mean, double stdev, int N)
{
    var rnd = new MersenneTwister();
    var normal = new Normal(mean, stdev);     var ms = new MetropolisHastingsSampler(0.1, x => Math.Log(normal.Density(x)),
                                                 (x,y) => npdf(x,y,03),
                                                 x => Normal.Sample(rnd,x,0.3), 10);     var arr = ms.Sample(N);
     return arr;
     //string result = "Theoretical Mean:" + beta.Mean + " vs Sample Mean: " 
        + Statistics.Mean(arr) + ";" + "Theoretical StarndardDeviation:"
        + beta.StdDev + " vs Sample StandardDeviation: "
        + Statistics.StandardDeviation(arr) + ";" + " Acceptance Rate:" + rs.AcceptanceRate;
     //return result;
} [WebMethod(Description = "Sampling a normal variable via Metropolis asymmetric proposal")]
public double[] NormaViaMetropolisAsymmetricProposal(double mean, double stdev, int N)
{
    var rnd = new MersenneTwister();
    var normal = new Normal(mean, stdev);     var ms = new MetropolisHastingsSampler(0.1, x => Math.Log(normal.Density(x)),
         (xnew, x) => Math.Log(0.5 * Math.Exp(npdf(xnew,x, 0.3))
                        + 0.5 * Math.Exp(npdf(xnew, x+0.1, 0.3))),
               x => MixSample(x), 10);     var arr = ms.Sample(N);
     return arr;
     //string result = "Theoretical Mean:" + beta.Mean + " vs Sample Mean: " 
        + Statistics.Mean(arr) + ";" + "Theoretical StarndardDeviation:"
        + beta.StdDev + " vs Sample StandardDeviation: "
        + Statistics.StandardDeviation(arr) + ";" + " Acceptance Rate:" + rs.AcceptanceRate;
     //return result;
} [WebMethod(Description = "Slice sampling a normal distributed random variable")]
public double[] NormaViaSliceSampling(double mean, double stdev, int N)
{
    var rnd = new MersenneTwister();
    var normal = new Normal(mean, stdev);     var ms = new UnivariateSliceSampler(0.1, x => npdfNoNormalized(x, mean, stdev), 5, 1.0);
    var arr = ms.Sample(N);
     return arr;
     //string result = "Theoretical Mean:" + beta.Mean + " vs Sample Mean: " 
        + Statistics.Mean(arr) + ";" + "Theoretical StarndardDeviation:"
        + beta.StdDev + " vs Sample StandardDeviation: "
        + Statistics.StandardDeviation(arr) + ";" + " Acceptance Rate:" + rs.AcceptanceRate;
     //return result;
} public double npdf(double x, double m, double s)
{
    return -0.5 * (x - m) * (x - m) / (s * s) - 0.5 * Math.Log(2.0 * System.Math.PI * s * s);
} public double npdfNoNormalized(double x, double m, double s)
{
    return -0.5 * (x - m) * (x - m) / (s * s);
} public double MixSample(double x)
{
    var rnd = new MersenneTwister();
    if (Bernoulli.Sample(rnd, 0.5) == 1)
        return Normal.Sample(rnd, x, 0.3);
    else
        return Normal.Sample(rnd, x + 0.1, 0.3);
}
}

Original F# Code


// Math.NET Numerics, part of the Math.NET Project
// http://numerics.mathdotnet.com
// http://github.com/mathnet/mathnet-numerics
// http://mathnetnumerics.codeplex.com
//
// Copyright (c) 2009-2013 Math.NET
//
// Permission is hereby granted, free of charge, to any person
// obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without
// restriction, including without limitation the rights to use,
// copy, modify, merge, publish, distribute, sublicense, and/or sell
// copies of the Software, and to permit persons to whom the
// Software is furnished to do so, subject to the following
// conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
// HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
// WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
// OTHER DEALINGS IN THE SOFTWARE.
//

#r "../../out/lib/Net40/MathNet.Numerics.dll"
#r "../../out/lib/Net40/MathNet.Numerics.FSharp.dll"

open MathNet.Numerics
open MathNet.Numerics.Random
open MathNet.Numerics.Statistics
open MathNet.Numerics.Distributions
open MathNet.Numerics.Statistics.Mcmc

/// The number of samples to gather for each sampler.
let N = 10000
/// The random number generator we use for the examples.
let rnd = new MersenneTwister()

//
// Example 1: Sampling a Beta distributed variable through rejection sampling.
//
// Target Distribution: Beta(2.7, 6.3)
//
// -----------------------------------------------------------------------------
do
printfn "Rejection Sampling Example"

/// The target distribution.
let beta = new Beta(2.7, 6.3)

/// Samples uniform distributed variables.
let uniform = new ContinuousUniform(0.0, 1.0, RandomSource = rnd)

/// Implements the rejection sampling procedure.
let rs = new RejectionSampler( ( fun x -> x**(beta.A-1.0) * (1.0 - x)**(beta.B-1.0) ),
( fun x -> 0.021 ),
( fun () -> uniform.Sample()) )

/// An array of samples from the rejection sampler.
let arr = rs.Sample(N)

/// The true distribution.
printfn "\tEmpirical Mean = %f (should be %f)" (Statistics.Mean(arr)) beta.Mean
printfn "\tEmpirical StdDev = %f (should be %f)" (Statistics.StandardDeviation(arr)) beta.StdDev
printfn "\tAcceptance rate = %f" rs.AcceptanceRate
printfn ""

//
// Example 2: Sampling a normal distributed variable through Metropolis sampling.
//
// Target Distribution: Normal(1.0, 3.5)
//
// -----------------------------------------------------------------------------
do
printfn "Metropolis Sampling Example"

let mean, stddev = 1.0, 3.5
let normal = new Normal(mean, stddev)

/// Implements the rejection sampling procedure.
let ms = new MetropolisSampler( 0.1, (fun x -> log(normal.Density(x))),
(fun x -> Normal.Sample(rnd, x, 0.3)), 20,
RandomSource = rnd )

/// An array of samples from the rejection sampler.
let arr = ms.Sample(N)

/// The true distribution.
printfn "\tEmpirical Mean = %f (should be %f)" (Statistics.Mean(arr)) normal.Mean
printfn "\tEmpirical StdDev = %f (should be %f)" (Statistics.StandardDeviation(arr)) normal.StdDev
printfn "\tAcceptance rate = %f" ms.AcceptanceRate
printfn ""

//
// Example 3: Sampling a normal distributed variable through Metropolis-Hastings sampling
// with a symmetric proposal distribution.
//
// Target Distribution: Normal(1.0, 3.5)
//
// -----------------------------------------------------------------------------------------
do
printfn "Metropolis Hastings Sampling Example (Symmetric Proposal)"
let mean, stddev = 1.0, 3.5
let normal = new Normal(mean, stddev)

/// Evaluates the log normal distribution.
let npdf x m s = -0.5*(x-m)*(x-m)/(s*s) - 0.5 * log(Constants.Pi2 * s * s)

/// Implements the rejection sampling procedure.
let ms = new MetropolisHastingsSampler( 0.1, (fun x -> log(normal.Density(x))),
(fun x y -> npdf x y 0.3), (fun x -> Normal.Sample(rnd, x, 0.3)), 10,
RandomSource = rnd )

/// An array of samples from the rejection sampler.
let arr = ms.Sample(N)

/// The true distribution.
printfn "\tEmpirical Mean = %f (should be %f)" (Statistics.Mean(arr)) normal.Mean
printfn "\tEmpirical StdDev = %f (should be %f)" (Statistics.StandardDeviation(arr)) normal.StdDev
printfn "\tAcceptance rate = %f" ms.AcceptanceRate
printfn ""

//
// Example 4: Sampling a normal distributed variable through Metropolis-Hastings sampling
// with a asymmetric proposal distribution.
//
// Target Distribution: Normal(1.0, 3.5)
//
// -----------------------------------------------------------------------------------------
do
printfn "Metropolis Hastings Sampling Example (Assymetric Proposal)"
let mean, stddev = 1.0, 3.5
let normal = new Normal(mean, stddev)

/// Evaluates the logarithm of the normal distribution function.
let npdf x m s = -0.5*(x-m)*(x-m)/(s*s) - 0.5 * log(Constants.Pi2 * s * s)

/// Samples from a mixture that is biased towards samples larger than x.
let mixSample x =
if Bernoulli.Sample(rnd, 0.5) = 1 then
Normal.Sample(rnd, x, 0.3)
else
Normal.Sample(rnd, x + 0.1, 0.3)

/// The transition kernel for the proposal above.
let krnl xnew x = log (0.5 * exp(npdf xnew x 0.3) + 0.5 * exp(npdf xnew (x+0.1) 0.3))

/// Implements the rejection sampling procedure.
let ms = new MetropolisHastingsSampler( 0.1, (fun x -> log(normal.Density(x))),
(fun xnew x -> krnl xnew x), (fun x -> mixSample x), 10,
RandomSource = rnd )

/// An array of samples from the rejection sampler.
let arr = ms.Sample(N)

/// The true distribution.
printfn "\tEmpirical Mean = %f (should be %f)" (Statistics.Mean(arr)) normal.Mean
printfn "\tEmpirical StdDev = %f (should be %f)" (Statistics.StandardDeviation(arr)) normal.StdDev
printfn "\tAcceptance rate = %f" ms.AcceptanceRate
printfn ""

//
// Example 5: Slice sampling a normal distributed random variable.
//
// Target Distribution: Normal(1.0, 3.5)
//
// -----------------------------------------------------------------------------------------
do
printfn "Slice Sampling Example"
let mean, stddev = 1.0, 3.5
let normal = new Normal(mean, stddev)

/// Evaluates the unnormalized logarithm of the normal distribution function.
let npdf x m s = -0.5*(x-m)*(x-m)/(s*s)

/// Implements the rejection sampling procedure.
let ms = new UnivariateSliceSampler( 0.1, (fun x -> npdf x mean stddev), 5, 1.0, RandomSource = rnd )

/// An array of samples from the rejection sampler.
let arr = ms.Sample(N)

/// The true distribution.
printfn "\tEmpirical Mean = %f (should be %f)" (Statistics.Mean(arr)) normal.Mean
printfn "\tEmpirical StdDev = %f (should be %f)" (Statistics.StandardDeviation(arr)) normal.StdDev
printfn ""

Markov Chain Monte Carlo Simulation using C# and MathNet的更多相关文章

  1. PRML读书会第十一章 Sampling Methods(MCMC, Markov Chain Monte Carlo,细致平稳条件,Metropolis-Hastings,Gibbs Sampling,Slice Sampling,Hamiltonian MCMC)

    主讲人 网络上的尼采 (新浪微博: @Nietzsche_复杂网络机器学习) 网络上的尼采(813394698) 9:05:00  今天的主要内容:Markov Chain Monte Carlo,M ...

  2. (转)Markov Chain Monte Carlo

    Nice R Code Punning code better since 2013 RSS Blog Archives Guides Modules About Markov Chain Monte ...

  3. 马尔科夫链蒙特卡洛(Markov chain Monte Carlo)

    (学习这部分内容大约需要1.3小时) 摘要 马尔科夫链蒙特卡洛(Markov chain Monte Carlo, MCMC) 是一类近似采样算法. 它通过一条拥有稳态分布 \(p\) 的马尔科夫链对 ...

  4. [Bayes] MCMC (Markov Chain Monte Carlo)

    不错的文章:LDA-math-MCMC 和 Gibbs Sampling 可作为精进MCMC抽样方法的学习材料. 简单概率分布的模拟 Box-Muller变换原理详解 本质上来说,计算机只能生产符合均 ...

  5. 为什么要用Markov chain Monte Carlo (MCMC)

    马尔科夫链的蒙特卡洛采样的核心思想是构造一个Markov chain,使得从任意一个状态采样开始,按该Markov chain转移,经过一段时间的采样,逼近平稳分布stationary distrib ...

  6. 蒙特卡洛模拟(Monte Carlo simulation)

    1.蒙特卡罗模拟简介 蒙特卡罗模拟,也叫统计模拟,这个术语是二战时期美国物理学家Metropolis执行曼哈顿计划的过程中提出来的,其基本思想很早以前就被人们所发现和利用.早在17世纪,人们就知道用事 ...

  7. History of Monte Carlo Methods - Part 1

    History of Monte Carlo Methods - Part 1 Some time ago in June 2013 I gave a lab tutorial on Monte Ca ...

  8. Monte Carlo Approximations

    准备总结几篇关于 Markov Chain Monte Carlo 的笔记. 本系列笔记主要译自A Gentle Introduction to Markov Chain Monte Carlo (M ...

  9. Introduction To Monte Carlo Methods

    Introduction To Monte Carlo Methods I’m going to keep this tutorial light on math, because the goal ...

随机推荐

  1. selenium+常见操作

    1.多窗口操作 有些页面的链接打开后,会重新打开一个窗口,对于这种情况,想在新页面上操作,就得先切换窗口了.获取窗口的唯一标识用句柄表示,所以只需要切换句柄,我们就能在多个页面上灵活自如的操作了. 句 ...

  2. linux下vsftpd的安装及配置使用详细步骤(推荐)

    vsftpd 是“very secure FTP daemon”的缩写,安全性是它的一个最大的特点. vsftpd 是一个 UNIX 类操作系统上运行的服务器的名字,它可以运行在诸如 Linux.BS ...

  3. Comparable接口与Comparator接口的比较————Comparable接口详解

    Comparable接口位于:java.lang包中. Comparable接口: 1. 实现了这个接口的类,会被强制进行自然排序. 问题又来了:那什么是自然排序呢? 自然排序:就是字典序排序,不分大 ...

  4. vue基于element-ui的三级CheckBox复选框

    最近vue项目需要用到三级CheckBox复选框,需要实现全选反选不确定三种状态.但是element-ui table只支持多选行,并不能支持三级及以上的多选,所以写了这篇技术博文供以后学习使用. 效 ...

  5. linux中 > 、>> 的用法

    linux中>表示覆盖原文件内容(文件的日期也会自动更新),>>表示追加内容(会另起一行,文件的日期也会自动更新). 1 将history命令执行的结果保存到history.log文 ...

  6. leetcode-mid-math-29. Divide Two Integers-NO

    mycode   91.28% class Solution(object): def divide(self, dividend, divisor): """ :typ ...

  7. 五、python中MD5加密

    import hashlib '''用于加密相关的操作,代替了md5模块和sha模块,主要提供 SHA1, SHA224, SHA256, SHA384, SHA512 ,MD5 算法'''##### ...

  8. 2018-5 - 热经 - 北京中地时空数码科技有限公司 - 研发工程师(WEBGIS 方向)

    一面: 登记,填写个人信息 笔试 选择题: HTML,CSS,JS 的选择题,都是基础题.其中有一道问哪个不是 document 的属性或方法,我在 bgColor 和 focus() 上面纠结了一下 ...

  9. Python基本语法_基本数据类型_序列类型详解

    目录 目录 序列 序列的标准操作符 切片操作符 一个例子 字符串的连接 序列的功能函数 enumerate 枚举出序列对象的元素 len 获取序列对象的长度 min 取出sequence中的最小值 m ...

  10. C#SQL小结

    对于c#获取Sql数据目前我采用的是 System.Data.SqlClient.SqlDataReader类. 主要用到如下API: SqlDataReader.Read():每次获取一行的数据,直 ...