samer@0
|
1 % afitgauss - Fit Gaussian to stream of input vectors
|
samer@0
|
2 %
|
samer@0
|
3 % afitgauss ::
|
samer@0
|
4 % nonneg~'adaptation rate',
|
samer@0
|
5 % options {
|
samer@0
|
6 % zeromean :: bool/0 ~'assume input is zero mean?'
|
samer@0
|
7 % }
|
samer@0
|
8 % -> arrow( {[[N]]}, {struct { mu::[[N]]; cov:[[N,N]] }}, stats_struct(N)).
|
samer@0
|
9 %
|
samer@0
|
10 % stats_struct(N) ::= struct {
|
samer@0
|
11 % ag :: nonneg;
|
samer@0
|
12 % amu :: [[N]];
|
samer@0
|
13 % aco ::[[N,N]];
|
samer@0
|
14 % }.
|
samer@0
|
15
|
samer@0
|
16 function o=afitgauss(L,varargin)
|
samer@0
|
17
|
samer@37
|
18 opts=options('zeromean',0,varargin{:});
|
samer@0
|
19
|
samer@0
|
20 GMM=gmm;
|
samer@0
|
21 %K=L/(L+1);
|
samer@0
|
22 kappa=L*(L-1); % precision of diffusion process for effective memory of L
|
samer@0
|
23
|
samer@0
|
24 M0=[];
|
samer@0
|
25 o=loop(ifx(opts.zeromean,@update_z,@update),@init);
|
samer@0
|
26
|
samer@0
|
27 function s0=init(size_in)
|
samer@0
|
28 N=size_in(1);
|
samer@0
|
29 M0=GMM.ss_init(GMM.blank(1,N));
|
samer@0
|
30 s0=foldl( @(s,x)GMM.ss_accum(s,[x,-x],[0.5,0.5]), M0, mat2cell(eye(N),N,ones(1,N)));
|
samer@0
|
31 end
|
samer@0
|
32
|
samer@0
|
33 function [y,s]=update(x,s)
|
samer@0
|
34 % factor to reduce weight of evidence so far
|
samer@0
|
35 % corresponds roughly to *addition* of variance
|
samer@0
|
36 % in the exponential family diffusion scheme of things
|
samer@0
|
37 K=kappa/(kappa+s.ag);
|
samer@0
|
38 s.ag = K*s.ag + size(x,2);
|
samer@0
|
39 s.amu = K*s.amu + sum(x,2);
|
samer@0
|
40 s.aco = K*s.aco + x*x';
|
samer@0
|
41 y=mstep(s,M0);
|
samer@0
|
42 end
|
samer@0
|
43
|
samer@0
|
44 function [y,s]=update_z(x,s)
|
samer@0
|
45 % factor to reduce weight of evidence so far
|
samer@0
|
46 K=kappa/(kappa+s.ag);
|
samer@0
|
47 s.ag = K*s.ag + size(x,2);
|
samer@0
|
48 s.aco = K*s.aco + x*x';
|
samer@0
|
49 y=mstep_z(s,M0);
|
samer@0
|
50 end
|
samer@0
|
51
|
samer@0
|
52 function M=mstep(S,M)
|
samer@0
|
53 M.mu=S.amu/S.ag;
|
samer@0
|
54 M.cov=msym(S.aco/S.ag - M.mu*M.mu');
|
samer@0
|
55 end
|
samer@0
|
56
|
samer@0
|
57 function M=mstep_z(S,M)
|
samer@0
|
58 M.mu=zeros(size(S.aco,1),1);
|
samer@0
|
59 M.cov=S.aco/S.ag;
|
samer@0
|
60 end
|
samer@0
|
61
|
samer@0
|
62 function A=mysm(X), A=(X+X')/2; end
|
samer@0
|
63 end
|