1. 程式人生 > >metropolis演算法的簡單c++實現以及matlab實現

metropolis演算法的簡單c++實現以及matlab實現

metropolis是一種取樣方法,一般用於獲取某些擁有某些比較複雜的概率分佈的樣本。
1.取樣最基本的是隨機數的生成,一般是生成具有均勻分佈的隨機數,比如C++裡面的rand函式,可以直接採用。
2.取樣複雜一點是轉化發,用於生成普通常見的分佈,如高斯分佈,它的一般是通過對均勻分佈或者現有分佈的轉化形成,如高斯分佈就可以通過如下方法生成:
令:U,V為均勻分佈的隨即變數;
那麼:Gauss=sqrt(-2lnU)cos(2*pi*V)。
(詳細參照Box-Muller)
像這種高斯分佈matelab可以直接用randN生成。


3. 最後一種方法是類MCMC方法,其實MCMC是一種架構,這裡我們說一種最簡單的Metropolis方法,它的核心思想是構建馬爾剋夫鏈,該鏈上每一個節點都成為一個樣本,利用馬爾剋夫鏈的轉移和接受概率,以一定的方式對樣本進行生成,這個方法簡單有效,具體可以參考《LDA數學八卦》的,裡面都已經進行了詳細的介紹。本文給一個小demo,是利用C++寫的。例外程式碼的matlab版本也有,但不是我寫的,一併貼出來,matlab的畫圖功能可以視覺化的驗證取樣有效性,(好像matlab有個小bug),


待生成樣本的概率分佈為:pow(t,-3.5)*exp(-1/(2*t)) (csdn有沒有想latex那種編輯方式啊??),這裡在metropolis中假設馬爾剋夫鏈是symmetric,就是p(x|y)=p(y|x),整個程式碼如下:
#include <iostream>
#include <time.h>
#include <stdlib.h>
#include <cmath>
using namespace std;


#define debug(A) std::cout<<#A<<": "<<A<<std::endl;


class MCMCSimulation{

	public:
		int N;
		int nn;
		float* sample;

		MCMCSimulation(){

			this->N=1000;
			this->nn=0.1*N;
			this->sample=new float[N];
			this->sample[0]=0.3;

		}

		void run(){

			for (int i=1;i<this->N;i++){

				float p_sample=this->PDF_proposal(3);	

				float alpha=PDF(p_sample)/PDF(this->sample[i-1]);

				if(PDF_proposal(1) < this->min(alpha,1)){
				
					this->sample[i]=p_sample;

				}else{

					this->sample[i]=this->sample[i-1];
				
				} 
				//debug(p_sample);
				//debug(PDF_proposal(1));
				//debug(sample[i]);
				cout<<sample[i]<<endl;
			}

		}
	private:

		//the probability desity function
		float PDF(float t){

			return pow(t,-3.5)*exp(-1/(2*t));	

		} 

		//generate a rand number from 0-MAX, with a specified precision
		float PDF_proposal(int MAX){

			//srand
			return (float)(MAX)*(float)(rand())/(float)(RAND_MAX);

		}

		float min(float x, float y){
		
			if(x<y){
				
				return x; 

			}else{
			
				return y;
			}
		
		}

};

int main(){

	MCMCSimulation* sim =new MCMCSimulation();
	sim->run();
	delete sim;
	return 1;
}

matlab版本

%% Simple Metropolis algorithm example
%{
---------------------------------------------------------------------------
*Created by:                  Date:            Comment:
 Felipe Uribe-Castillo        July 2011        Final project algorithm  
*Mail: 
 [email protected]
*University:
 National university of Colombia at Manizales. Civil Engineering Dept.
---------------------------------------------------------------------------
The Metropolis algorithm:
First MCMC to obtain samples from some complex probability distribution
and to integrate very complex functions by random sampling. 
It considers only symmetric proposals (proposal pdf). 

Original contribution: 
-"The Monte Carlo method"
  Metropolis & Ulam (1949).
-"Equations of State Calculations by Fast Computing Machines"
  Metropolis, Rosenbluth, Rosenbluth, Teller & Teller (1953).
---------------------------------------------------------------------------
Based on:
1."Markov chain Monte Carlo and Gibbs sampling"
   B.Walsh ----- Lecture notes for EEB 581, version april 2004.
   http://web.mit.edu/~wingated/www/introductions/mcmc-gibbs-intro.pdf
%}
clear; close all; home; format long g;

%% Initial data
% Distributions 
nu           = 5;                                       % Target PDF parameter
p            = @(t) (t.^(-nu/2-1)).*(exp(-1./(2*t)));   % Target "PDF", Ref. 1 - Ex. 2
proposal_PDF = @(mu) unifrnd(0,3);                      % Proposal PDF
% Parameters
N        = 1000;              % Number of samples (iterations)
nn       = 0.1*(N);           % Number of samples for examine the AutoCorr
theta    = zeros(1,N);        % Samples drawn form the target "PDF"
theta(1) = 0.3;               % Initial state of the chain

%% Procedure
for i = 1:N
   theta_ast = proposal_PDF([]);          % Sampling from the proposal PDF
   alpha     = p(theta_ast)/p(theta(i));  % Ratio of the density at theta_ast and theta points
   if rand <= min(alpha,1)
      % Accept the sample with prob = min(alpha,1)
      theta(i+1) = theta_ast;
   else
      % Reject the sample with prob = 1 - min(alpha,1)
      theta(i+1) = theta(i);
   end
end

% Autocorrelation (AC)
pp = theta(1:nn);   pp2 = theta(end-nn:end);   % First ans Last nn samples
[r lags]   = xcorr(pp-mean(pp), 'coeff');
[r2 lags2] = xcorr(pp2-mean(pp2), 'coeff');

%% Plots
% Autocorrelation
figure;
subplot(2,1,1);   stem(lags,r);
title('Autocorrelation', 'FontSize', 14);
ylabel('AC (first samples)', 'FontSize', 12);
subplot(2,1,2);   stem(lags2,r2);
ylabel('AC (last samples)', 'FontSize', 12);

% Samples and distributions
xx = eps:0.01:10;   % x-axis (Graphs)
figure;
% Histogram and target dist
subplot(2,1,1); 
[n1 x1] = hist(theta, ceil(sqrt(N)));
bar(x1,n1/(N*(x1(2)-x1(1))));   colormap summer;   hold on;   % Normalized histogram
plot(xx, p(xx)/trapz(xx,p(xx)), 'r-', 'LineWidth', 3);        % Normalized function
grid on;   xlim([0 max(theta)]);   
title('Distribution of samples', 'FontSize', 14);
ylabel('Probability density function', 'FontSize', 12);
% Samples
subplot(2,1,2);     
plot(theta, 1:N+1, 'b-');   xlim([0 max(theta)]);   ylim([0 N]);   grid on;
xlabel('Location', 'FontSize', 12);
ylabel('Iterations, N', 'FontSize', 12); 

%%End
下面是樣本的分佈圖


相關推薦

metropolis演算法簡單c++實現以及matlab實現

metropolis是一種取樣方法,一般用於獲取某些擁有某些比較複雜的概率分佈的樣本。 1.取樣最基本的是隨機數的生成,一般是生成具有均勻分佈的隨機數,比如C++裡面的rand函式,可以直接採用。 2.取樣複雜一點是轉化發,用於生成普通常見的分佈,如高斯分佈,它的一般是通過

樸素貝葉斯演算法實現分類以及Matlab實現

開始 其實在學習機器學習的一些演算法,最近也一直在看這方面的東西,並且嘗試著使用Matlab進行一些演算法的實現。這幾天一直在看得就是貝葉斯演算法實現一個分類問題。大概經過了一下這個過程: 看書→演算法公式推演→網上查詢資料→進一步理解→蒐集資料集開始嘗

簡單橢圓曲線加密演算法(ECC)示例(MATLAB實現

摘要 本文主要是使用MATLAB演示橢圓曲線加密演算法(ECC)的加密/解密過程,內容包括金鑰、公鑰生成,以及通過加密並解密一個簡單數字的過程來描述其使用方法。 本文實際是對以下兩篇文章的一個MATLAB實現,並且提供了兩個實用的MATLAB工具函式以便在閱

2018-4-8蟻群演算法---包子陽《智慧優化演算法以及Matlab實現》第五章

資料來源:《智慧優化演算法以及matlab實現》包子陽  餘繼周 編著第五章-----蟻群演算法是一種元啟發式優化演算法(自己理解:就是作為群體的單位個體也就是元,在裡面充當著隨機的選擇搜尋的方向,有助於全域性勘探)啟發:自然界的螞蟻有能力在沒有然和提示的情況下找到從巢穴矩離

演算法C++連結串列的實現以及常見的連結串列操作和測試

自己實現連結串列常見的操作,用作記錄,以備以後檢視#include <iostream> #include <string.h> using namespace std; //定義節點 class Node { public: int m_data

PCA降維演算法總結以及matlab實現PCA(個人的一點理解)

轉載請宣告出處。by watkins song 兩篇文章各有側重, 對照看效果更加 o(∩∩)o.. PCA的一些基本資料 最近因為最人臉表情識別,提取的gabor特徵太多了,所以需要用PCA進行對提取的特徵進行降維。 本來最早的時候我沒有打算對提取的gabor特徵

量子遺傳演算法以及matlab實現

1、基本概念 (1)量子遺傳演算法是量子計算與遺傳演算法相結合的智慧優化演算法,由K.H.Han等人提出,其將量子態、量子門、量子狀態特性、概率幅等量子概念引入到遺傳演算法當中。量子遺傳演算法也是一種概率搜素演算法,它採用量子位來表示基因。遺傳演算法的基因所表達的是某一確定

線性規劃中的單純形法與內點法(原理、步驟以及matlab實現)(三)

應用 最大化 round 並不是 兩個 生產 陰影 3.3 ima 在本系列的第三篇博客中,筆者討論對偶單純形法的相關理論和應用 2.3 Dual Simplex Method(對偶單純形法) Contents   2.3.1 對偶問題產生的原因   2.3.2 對偶問題的

演算法C++用連結串列實現一個箱子排序附原始碼詳解

01 箱子排序 1.1 什麼是分配排序? 分配排序的基本思想:排序過程無須比較關鍵字,而是通過"分配"和"收集"過程來實現排序.它們的時間複雜度可達到線性階:O(n)。 1.2 什麼是箱子排序? 箱子排序是分配排序的一種,箱子排序也稱桶排序(Bucket Sort),其基本思想是:設定若干個箱子,依次掃描待

PCA演算法的數學原理以及Python實現

部落格中的筆記: 降維當然意味著資訊的丟失,不過鑑於實際資料本身常常存在的相關性,我們可以想辦法在降維的同時將資訊的損失儘量降低。 根據相關性來講資訊的損失量降到最低 更正式的說,向量(x,y)實際上表示線性組合: x(1,0)?+y(0,1)? 不難證明所有二

演算法導論—插入排序及Matlab實現

插入排序是《演算法導論》中的第一個演算法, 插入排序:Insertion-sort 輸入:待排序陣列A[1,···,n],長度為n 輸出:按從小到大順序排序好的陣列 演算法思想:插入排序是最簡單直觀的排序方法,原理就是通過構建有序序列,隨後將待排序元素插

聚類演算法KMeans和KMedoid 的Matlab實現

說明:fea為訓練樣本資料,gnd為樣本標號。演算法中的思想和上面寫的一模一樣,在最後的判斷accuracy方面,由於聚類和分類不同,只是得到一些 cluster ,而並不知道這些 cluster 應該被打上什麼標籤,或者說。由於我們的目的是衡量聚類演算法的 performance ,因此直接假定這一步能實現

基本粒子群優化演算法(PSO)的matlab實現

粒子群優化演算法是一種模擬鳥群社會行為的群體搜素演算法。它分為全域性最佳粒子優化和區域性最佳粒子優化,對於全域性最佳PSO,或者叫做gbest PSO,每個粒子的鄰域都是整個群,其演算法虛擬碼如下: 建立並初始化一個n維的粒子群 repeat for 每個粒子i=

機器學習演算法 之邏輯迴歸以及python實現

下面分為兩個部分: 1. 邏輯迴歸的相關原理說明 2. 通過python程式碼來實現一個梯度下降求解邏輯迴歸過程 邏輯迴歸(Logistic Regression) 首先需要說明,邏輯迴歸屬於分類演算法。分類問題和迴歸問題的區別在於,分類問題的輸出是離散

【無監督學習】DBSCAN聚類演算法原理介紹,以及程式碼實現

前言:無監督學習想快一點複習完,就轉入有監督學習 聚類演算法主要包括哪些演算法?主要包括:K-m

基於使用者(user-based)的協同過濾推薦演算法的初步理解以及程式碼實現

總論 協同過濾是目前最經典的推薦演算法。 分而理之,協同,指通過線上資料找到使用者可能喜歡的物品;過濾,濾掉一些不值得推薦的資料。 協同過濾推薦分為三種類型。第一種是基於使用者(user-based)的協同過濾,第二種是基於專案(ite

一個簡單C順序棧的實現

僅用於記錄,加深理解的練習。 水平有限,不規範之處還請包涵指正。 只實現了初始化棧,進棧,出棧,列印資料功能。 #include<stdio.h> #include<stdlib.h> #define ADDSIZE 10 #

Ajax原理以及實現(js實現以及jquery實現

1.Ajax簡介 Ajax:非同步js,xml 非同步重新整理:如果網頁中某一個地方需要修改,非同步重新整理可以使只重新整理的地方修改,而不是全域性修改,比如,你看視訊點贊不可能你點一個贊就重新整理整個視訊頁面吧 2.js實現Ajax js: XMLHttpReques

springboot下載檔案功能實現以及vue實現下載

後端: // 檔案下載功能 @RequestMapping("/excel/download") public void downexcel(HttpServletResponse res){ System.out.println("檔案下載功能==");

MongoDB表結構設計程式碼實現以及連線實現

1、以備檢視表結構設計程式碼:package cn.uestc.warningTest.warningTest; import org.bson.Document; public class TableDesign { private String time;//時間