wolffd@0: % Verify that my code gives the same results as the 1D example at wolffd@0: % http://www.media.mit.edu/physics/publications/books/nmm/files/cwm.m wolffd@0: wolffd@0: seed = 0; wolffd@0: rand('state', seed); wolffd@0: randn('state', seed); wolffd@0: x = (-10:10)'; wolffd@0: y = double(x > 0); wolffd@0: npts = length(x); wolffd@0: plot(x,y,'+') wolffd@0: wolffd@0: nclusters = 4; wolffd@0: nplot = 100; wolffd@0: xplot = 24*(1:nplot)'/nplot - 12; wolffd@0: wolffd@0: mux = 20*rand(1,nclusters) - 10; wolffd@0: muy = zeros(1,nclusters); wolffd@0: varx = ones(1,nclusters); wolffd@0: vary = ones(1,nclusters); wolffd@0: pc = 1/nclusters * ones(1,nclusters); wolffd@0: wolffd@0: wolffd@0: I = repmat(eye(1,1), [1 1 nclusters]); wolffd@0: O = repmat(zeros(1,1), [1 1 nclusters]); wolffd@0: X = x(:)'; wolffd@0: Y = y(:)'; wolffd@0: wolffd@0: % Do 1 iteration of EM wolffd@0: wolffd@0: %cwr = cwr_em(X, Y, nclusters, 'muX', mux, 'muY', muy, 'SigmaX', I, 'cov_typeX', 'spherical', 'SigmaY', I, 'cov_typeY', 'spherical', 'priorC', pc, 'weightsY', O, 'init_params', 0, 'clamp_weights', 1, 'max_iter', 1, 'cov_priorX', zeros(1,1,nclusters), 'cov_priorY', zeros(1,1,nclusters)); wolffd@0: wolffd@0: cwr = cwr_em(X, Y, nclusters, 'muX', mux, 'muY', muy, 'SigmaX', I, 'cov_typeX', 'spherical', 'SigmaY', I, 'cov_typeY', 'spherical', 'priorC', pc, 'weightsY', O, 'create_init_params', 0, 'clamp_weights', 1, 'max_iter', 1); wolffd@0: wolffd@0: wolffd@0: % Check this matches Gershenfeld's code wolffd@0: wolffd@0: % E step wolffd@0: % px(t,c) = prob(x(t) | c) wolffd@0: px = exp(-(kron(x,ones(1,nclusters)) ... wolffd@0: - kron(ones(npts,1),mux)).^2 ... wolffd@0: ./ (2*kron(ones(npts,1),varx))) ... wolffd@0: ./ sqrt(2*pi*kron(ones(npts,1),varx)); wolffd@0: py = exp(-(kron(y,ones(1,nclusters)) ... wolffd@0: - kron(ones(npts,1),muy)).^2 ... wolffd@0: ./ (2*kron(ones(npts,1),vary))) ... wolffd@0: ./ sqrt(2*pi*kron(ones(npts,1),vary)); wolffd@0: p = px .* py .* kron(ones(npts,1),pc); wolffd@0: pp = p ./ kron(sum(p,2),ones(1,nclusters)); wolffd@0: wolffd@0: % M step wolffd@0: eps = 0.01; wolffd@0: pc2 = sum(pp)/npts; wolffd@0: wolffd@0: mux2 = sum(kron(x,ones(1,nclusters)) .* pp) ... wolffd@0: ./ (npts*pc2); wolffd@0: varx2 = eps + sum((kron(x,ones(1,nclusters)) ... wolffd@0: - kron(ones(npts,1),mux2)).^2 .* pp) ... wolffd@0: ./ (npts*pc2); wolffd@0: muy2 = sum(kron(y,ones(1,nclusters)) .* pp) ... wolffd@0: ./ (npts*pc2); wolffd@0: vary2 = eps + sum((kron(y,ones(1,nclusters)) ... wolffd@0: - kron(ones(npts,1),muy2)).^2 .* pp) ... wolffd@0: ./ (npts*pc2); wolffd@0: wolffd@0: wolffd@0: denom = (npts*pc2); wolffd@0: % denom(c) = N*pc(c) = w(c) = sum_t pp(c,t) wolffd@0: % since pc(c) = sum_t pp(c,t) / N wolffd@0: wolffd@0: cwr_mux = cwr.muX; wolffd@0: assert(approxeq(mux2, cwr_mux)) wolffd@0: cwr_SigmaX = squeeze(cwr.SigmaX)'; wolffd@0: assert(approxeq(varx2, cwr_SigmaX)) wolffd@0: wolffd@0: cwr_muy = cwr.muY; wolffd@0: assert(approxeq(muy2, cwr_muy)) wolffd@0: cwr_SigmaY = squeeze(cwr.SigmaY)'; wolffd@0: assert(approxeq(vary2, cwr_SigmaY)) wolffd@0: wolffd@0: