-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathmixGaussRnd.m
80 lines (74 loc) · 2.11 KB
/
mixGaussRnd.m
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
function [X, z, model] = mixGaussRnd(d, k, n)
% Genarate samples form a Gaussian mixture model.
% Input:
% d: dimension of data
% k: number of components
% n: number of data
% Output:
% X: d x n data matrix
% z: 1 x n response variable
% model: model structure
% Written by Mo Chen (sth4nth@gmail.com).
alpha0 = 1; % hyperparameter of Dirichlet prior
W0 = eye(d); % hyperparameter of inverse Wishart prior of covariances
v0 = d+1; % hyperparameter of inverse Wishart prior of covariances
mu0 = zeros(d,1); % hyperparameter of Guassian prior of means
beta0 = nthroot(k,d); % hyperparameter of Guassian prior of means % in volume x^d there is k points: x^d=k
w = dirichletRnd(alpha0,ones(1,k)/k);
z = discreteRnd(w,n);
mu = zeros(d,k);
Sigma = zeros(d,d,k);
X = zeros(d,n);
for i = 1:k
idx = z==i;
Sigma(:,:,i) = iwishrnd(W0,v0); % invpd(wishrnd(W0,v0));
mu(:,i) = gaussRnd(mu0,beta0*Sigma(:,:,i));
X(:,idx) = gaussRnd(mu(:,i),Sigma(:,:,i),sum(idx));
end
model.mu = mu;
model.Sigma = Sigma;
model.w = w;
function x = dirichletRnd(a, m)
% Generate samples from a Dirichlet distribution.
% Input:
% a: k dimensional vector
% m: k dimensional mean vector
% Outpet:
% x: generated sample x~Dir(a,m)
% Written by Mo Chen (sth4nth@gmail.com).
if nargin == 2
a = a*m;
end
x = gamrnd(a,1);
x = x/sum(x);
function x = discreteRnd(p, n)
% Generate samples from a discrete distribution (multinomial).
% Input:
% p: k dimensional probability vector
% n: number of samples
% Ouput:
% x: k x n generated samples x~Mul(p)
% Written by Mo Chen (sth4nth@gmail.com).
if nargin == 1
n = 1;
end
r = rand(1,n);
p = cumsum(p(:));
[~,x] = histc(r,[0;p/p(end)]);
function x = gaussRnd(mu, Sigma, n)
% Generate samples from a Gaussian distribution.
% Input:
% mu: d x 1 mean vector
% Sigma: d x d covariance matrix
% n: number of samples
% Outpet:
% x: d x n generated sample x~Gauss(mu,Sigma)
% Written by Mo Chen (sth4nth@gmail.com).
if nargin == 2
n = 1;
end
[V,err] = chol(Sigma);
if err ~= 0
error('ERROR: sigma must be a symmetric positive definite matrix.');
end
x = V'*randn(size(V,1),n)+repmat(mu,1,n);