-
Notifications
You must be signed in to change notification settings - Fork 17
/
Copy pathGaussian_Gibbs.cpp
67 lines (60 loc) · 1.7 KB
/
Gaussian_Gibbs.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
#include <iostream>
#include <cmath>
#include<fstream>
const int niter=10000;
/******************************************************************/
/*** Gaussian Random Number Generator with Box Muller Algorithm ***/
/******************************************************************/
int BoxMuller(double& p, double& q){
double pi=2e0*asin(1e0);
//uniform random numbers between 0 and 1
double r = (double)rand()/RAND_MAX;
double s = (double)rand()/RAND_MAX;
//Gaussian random numbers,
//with weights proportional to e^{-p^2/2} and e^{-q^2/2}
p=sqrt(-2e0*log(r))*sin(2e0*pi*s);
q=sqrt(-2e0*log(r))*cos(2e0*pi*s);
return 0;
}
int main()
{
double A[3][3];
A[0][0]=1e0;A[1][1]=2e0;A[2][2]=2e0;
A[0][1]=1e0;A[0][2]=1e0;A[1][2]=1e0;
A[1][0]=A[0][1];A[2][0]=A[0][2];A[2][1]=A[1][2];
srand((unsigned)time(NULL));
/*********************************/
/* Set the initial configuration */
/*********************************/
double x=0e0;double y=0e0;double z=0e0;
/*****************/
/*** Main part ***/
/*****************/
for(int iter=0; iter!=niter; iter++){
double sigma,mu;
double r1,r2;
//update x
sigma=1e0/sqrt(A[0][0]);
mu=-A[0][1]/A[0][0]*y-A[0][2]/A[0][0]*z;
BoxMuller(r1,r2);
x=sigma*r1+mu;
//update y
sigma=1e0/sqrt(A[1][1]);
mu=-A[1][0]/A[1][1]*x-A[1][2]/A[1][1]*z;
BoxMuller(r1,r2);
y=sigma*r1+mu;
//update z
sigma=1e0/sqrt(A[2][2]);
mu=-A[2][0]/A[2][2]*x-A[2][1]/A[2][2]*y;
BoxMuller(r1,r2);
z=sigma*r1+mu;
// output x,y,z
if((iter+1)%10==0){
std::cout << std::fixed << std::setprecision(6)
<< x << " "
<< y << " "
<< z << std::endl;
}
}
return 0;
}