Files
2026-07-13 13:30:25 +08:00

109 lines
2.8 KiB
Matlab
Executable File

% Class for Gaussian-Wishart distribution used by Dirichlet process
classdef GaussWishart
properties
kappa_
m_
nu_
U_
end
methods
function obj = GaussWishart(kappa,m,nu,S)
U = chol(S+kappa*(m*m'));
obj.kappa_ = kappa;
obj.m_ = m;
obj.nu_ = nu;
obj.U_ = U;
end
function obj = clone(obj)
end
function d = dim(obj)
d = numel(obj.m_);
end
function obj = addData(obj, X)
kappa0 = obj.kappa_;
m0 = obj.m_;
nu0 = obj.nu_;
U0 = obj.U_;
n = size(X,2);
kappa = kappa0+n;
m = (kappa0*m0+sum(X,2))/kappa;
nu = nu0+n;
U = chol(U0'*U0+X*X');
obj.kappa_ = kappa;
obj.m_ = m;
obj.nu_ = nu;
obj.U_ = U;
end
function obj = addSample(obj, x)
kappa = obj.kappa_;
m = obj.m_;
nu = obj.nu_;
U = obj.U_;
kappa = kappa+1;
m = m+(x-m)/kappa;
nu = nu+1;
U = cholupdate(U,x,'+');
obj.kappa_ = kappa;
obj.m_ = m;
obj.nu_ = nu;
obj.U_ = U;
end
function obj = delSample(obj, x)
kappa = obj.kappa_;
m = obj.m_;
nu = obj.nu_;
U = obj.U_;
kappa = kappa-1;
m = m-(x-m)/kappa;
nu = nu-1;
U = cholupdate(U,x,'-');
obj.kappa_ = kappa;
obj.m_ = m;
obj.nu_ = nu;
obj.U_ = U;
end
function y = logPredPdf(obj,X)
kappa = obj.kappa_;
m = obj.m_;
nu = obj.nu_;
U = obj.U_;
d = size(X,1);
v = (nu-d+1);
U = sqrt((1+1/kappa)/v)*cholupdate(U,sqrt(kappa)*m,'-');
X = bsxfun(@minus,X,m);
Q = U'\X;
q = dot(Q,Q,1); % quadratic term (M distance)
o = -log(1+q/v)*((v+d)/2);
c = gammaln((v+d)/2)-gammaln(v/2)-(d*log(v*pi)+2*sum(log(diag(U))))/2;
y = c+o;
end
function [mu, Sigma] = sample(obj)
% Sample a Gaussian distribution from GaussianWishart prior
kappa = obj.kappa_;
m = obj.m_;
nu = obj.nu_;
U = obj.U_;
Sigma = iwishrnd(U'*U,nu);
mu = gaussRnd(m,Sigma/kappa);
end
end
end