-
Notifications
You must be signed in to change notification settings - Fork 7
/
Copy pathMultivariate-Normal-Dist-Examples-Julia.jl
135 lines (108 loc) · 3.88 KB
/
Multivariate-Normal-Dist-Examples-Julia.jl
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
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
## MIT license (C) 2019 by Andrew Lyasoff
# Julia 1.1.0 code to illustrate the construction of univariate histograms
# and the Monte Carlo simulation technique for multivariate Gaussian samples with a given covariance matrix.
#See (3.67), p.91, in "Stochastic Methods in Asset Pricing."
begin
using LinearAlgebra
using SpecialFunctions
using StatsBase
using Random
using Plots
pyplot()
end
#We write our own histogram function. It takes as an input a single 1-dimensional array of data.
#The number of bins in the histogram is determined automatically by using the Diaconis-Friedman rule.
#The function returns two arrays: the mid-points of the bins and the (unnormalized) heights of the bars.
function hstgram(data_sample::Array{Float64,1})
data_sorted=sort(data_sample)
first=data_sorted[1]
last=data_sorted[end]
nmb=length(data_sorted)
IQR=percentile(data_sorted,75)-percentile(data_sorted,25)
bin_size_loc = 2*IQR*(nmb^(-1.0/3))
num_bins=Int(floor((last-first)/bin_size_loc))
bin_size=(last-first)/(num_bins)
bin_end_points=[first+(i-1)*bin_size for i=1:(num_bins+1)]
ahist_val=[length(data_sorted[data_sorted .< u]) for u in bin_end_points]
hist_val=[ahist_val[i+1]-ahist_val[i] for i=1:num_bins]
mid_bins=[first-bin_size/2+i*bin_size for i=1:num_bins]
return mid_bins, hist_val
end
## First, create data sampled from the standard univariate normal density.
val=(x->((2*π)^(-1/2)*exp(-x^2/2))).(-3.3:0.05:3.3);
Random.seed!(0xabcdef12); # if needed to generate the same samples
#simulate 10,000 standard normals and generate the histogram
begin
nval=randn!(zeros(10000));
U,V=hstgram(nval);
VV=V/(sum(V)*(U[2]-U[1]));
end
#check the length of the bin
length(VV)
begin
plot(U.+(U[2]-U[1])/2,VV,line=(:steppre,1),linewidth=0.05,label="histogram")
xlabel!("samples")
ylabel!("frequency")
plot!(-3.3:0.05:3.3,val,label="normal density")
end
#generate another sample
begin
nval=randn(10000);
U,V=hstgram(nval);
VV=V/(sum(V)*(U[2]-U[1]));
plot(U.+(U[2]-U[1])/2,VV,line=(:steppre,1),linewidth=0.05,label="histogram")
xlabel!("samples")
ylabel!("frequency")
plot!(-3.3:0.05:3.3,val,label="normal density")
end
# standard normals can be generated by sampling from the uniform distribution
begin
uval=rand(10000);
nval=(x->sqrt(2)*erfinv(2*x-1)).(uval);
U,V=hstgram(nval);
VV=V/(sum(V)*(U[2]-U[1]));
plot(U.+(U[2]-U[1])/2,VV,line=(:steppre,1),linewidth=0.05,label="histogram")
xlabel!("samples")
ylabel!("frequency")
plot!(-3.3:0.05:3.3,val,label="normal density")
end
#simulate 10,000 standard bi-variate normals
begin
nval=randn!(zeros(10000));
nnval=randn!(zeros(10000));
end
scatter(nval,nnval,ratio=1,markersize=1,label="")
# to simulate bi-variate normals with a given covariance matrix
# first create a fictitios covariance matrix
begin
A=rand(2,2);
#Cov=A'A; # another alternative that always yields a positive definite matrix
Cov=Symmetric(A) # may not produce a positive definite matrix
end
#check if Cov is positive definite; if not, repeat the last step
eigvals(Cov)
begin
eigdCov=Diagonal(eigvals(Cov).^0.5)
eigCov=eigvecs(Cov); # matrix of eigen vectors
chlCov=cholesky(Cov); # Cholesky "square root" of Cov
MM=eigdCov*eigCov; # Spectral "square root" of Cov
end
# check that the factorizations give what is expected
Cov-MM'*MM
Cov-chlCov.L*chlCov.U
Cov-(chlCov.U)'*chlCov.U
Cov-(chlCov.L)*(chlCov.L)'
#this should be an orthogonal matrix
eigCov'*eigCov
#Transform the randomly generated standard bi-variate sample through the "square root" of the covariance matrix.
#method 1
begin
NN=hcat(nval,nnval)';
data_2_dim=MM'NN;
scatter(data_2_dim[1,:],data_2_dim[2,:],ratio=1,markersize=1,label="")
end
#method 2
begin
data_2_dim=(chlCov.L)*NN;
scatter(data_2_dim[1,:],data_2_dim[2,:],ratio=1,markersize=1,label="")
end