Daniel@0: function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv) Daniel@0: % UPDATE_ESS Update the Expected Sufficient Statistics of a Gaussian node Daniel@0: % function CPD = update_ess(CPD, fmarginal, evidence, ns, cnodes, hidden_bitv) Daniel@0: Daniel@0: %if nargin < 6 Daniel@0: % hidden_bitv = zeros(1, max(fmarginal.domain)); Daniel@0: % hidden_bitv(find(isempty(evidence)))=1; Daniel@0: %end Daniel@0: Daniel@0: dom = fmarginal.domain; Daniel@0: self = dom(end); Daniel@0: ps = dom(1:end-1); Daniel@0: cps = myintersect(ps, cnodes); Daniel@0: dps = mysetdiff(ps, cps); Daniel@0: Daniel@0: CPD.nsamples = CPD.nsamples + 1; Daniel@0: [ss cpsz dpsz] = size(CPD.weights); % ss = self size Daniel@0: [ss dpsz] = size(CPD.mean); Daniel@0: Daniel@0: % Let X be the cts parent (if any), Y be the cts child (self). Daniel@0: Daniel@0: if ~hidden_bitv(self) & ~any(hidden_bitv(cps)) & all(hidden_bitv(dps)) Daniel@0: % Speedup for the common case that all cts nodes are observed, all discrete nodes are hidden Daniel@0: % Since X and Y are observed, SYY = 0, SXX = 0, SXY = 0 Daniel@0: % Since discrete parents are hidden, we do not need to add evidence to w. Daniel@0: w = fmarginal.T(:); Daniel@0: CPD.Wsum = CPD.Wsum + w; Daniel@0: y = evidence{self}; Daniel@0: Cyy = y*y'; Daniel@0: if ~CPD.useC Daniel@0: WY = repmat(w(:)',ss,1); % WY(y,i) = w(i) Daniel@0: WYY = repmat(reshape(WY, [ss 1 dpsz]), [1 ss 1]); % WYY(y,y',i) = w(i) Daniel@0: %CPD.WYsum = CPD.WYsum + WY .* repmat(y(:), 1, dpsz); Daniel@0: CPD.WYsum = CPD.WYsum + y(:) * w(:)'; Daniel@0: CPD.WYYsum = CPD.WYYsum + WYY .* repmat(reshape(Cyy, [ss ss 1]), [1 1 dpsz]); Daniel@0: else Daniel@0: W = w(:)'; Daniel@0: W2 = reshape(W, [1 1 dpsz]); Daniel@0: CPD.WYsum = CPD.WYsum + rep_mult(W, y(:), size(CPD.WYsum)); Daniel@0: CPD.WYYsum = CPD.WYYsum + rep_mult(W2, Cyy, size(CPD.WYYsum)); Daniel@0: end Daniel@0: if cpsz > 0 % X exists Daniel@0: x = cat(1, evidence{cps}); x = x(:); Daniel@0: Cxx = x*x'; Daniel@0: Cxy = x*y'; Daniel@0: WX = repmat(w(:)',cpsz,1); % WX(x,i) = w(i) Daniel@0: WXX = repmat(reshape(WX, [cpsz 1 dpsz]), [1 cpsz 1]); % WXX(x,x',i) = w(i) Daniel@0: WXY = repmat(reshape(WX, [cpsz 1 dpsz]), [1 ss 1]); % WXY(x,y,i) = w(i) Daniel@0: if ~CPD.useC Daniel@0: CPD.WXsum = CPD.WXsum + WX .* repmat(x(:), 1, dpsz); Daniel@0: CPD.WXXsum = CPD.WXXsum + WXX .* repmat(reshape(Cxx, [cpsz cpsz 1]), [1 1 dpsz]); Daniel@0: CPD.WXYsum = CPD.WXYsum + WXY .* repmat(reshape(Cxy, [cpsz ss 1]), [1 1 dpsz]); Daniel@0: else Daniel@0: CPD.WXsum = CPD.WXsum + rep_mult(W, x(:), size(CPD.WXsum)); Daniel@0: CPD.WXXsum = CPD.WXXsum + rep_mult(W2, Cxx, size(CPD.WXXsum)); Daniel@0: CPD.WXYsum = CPD.WXYsum + rep_mult(W2, Cxy, size(CPD.WXYsum)); Daniel@0: end Daniel@0: end Daniel@0: return; Daniel@0: end Daniel@0: Daniel@0: % general (non-vectorized) case Daniel@0: fullm = add_evidence_to_gmarginal(fmarginal, evidence, ns, cnodes); % slow! Daniel@0: Daniel@0: if dpsz == 1 % no discrete parents Daniel@0: w = 1; Daniel@0: else Daniel@0: w = fullm.T(:); Daniel@0: end Daniel@0: Daniel@0: CPD.Wsum = CPD.Wsum + w; Daniel@0: xi = 1:cpsz; Daniel@0: yi = (cpsz+1):(cpsz+ss); Daniel@0: for i=1:dpsz Daniel@0: muY = fullm.mu(yi, i); Daniel@0: SYY = fullm.Sigma(yi, yi, i); Daniel@0: CPD.WYsum(:,i) = CPD.WYsum(:,i) + w(i)*muY; Daniel@0: CPD.WYYsum(:,:,i) = CPD.WYYsum(:,:,i) + w(i)*(SYY + muY*muY'); % E[X Y] = Cov[X,Y] + E[X] E[Y] Daniel@0: if cpsz > 0 Daniel@0: muX = fullm.mu(xi, i); Daniel@0: SXX = fullm.Sigma(xi, xi, i); Daniel@0: SXY = fullm.Sigma(xi, yi, i); Daniel@0: CPD.WXsum(:,i) = CPD.WXsum(:,i) + w(i)*muX; Daniel@0: CPD.WXXsum(:,:,i) = CPD.WXXsum(:,:,i) + w(i)*(SXX + muX*muX'); Daniel@0: CPD.WXYsum(:,:,i) = CPD.WXYsum(:,:,i) + w(i)*(SXY + muX*muY'); Daniel@0: end Daniel@0: end Daniel@0: