function dist = cond_dist_gaussian(bnode, bnet)
% COND_DIST_GAUSSIAN Compute a Gaussian approx. to Pr(self) for a Gaussian node.
% dist = cond_dist_gaussian(bnode, bnet)
%
% If the discrete parents are hidden, we collapse the Conditional Gaussian to a single Gaussian.
% We assume the values of the continuous parents (if any) are known.

ns = bnet.node_sizes;

if ismember(bnode.self, bnet.observed_nodes)
  dist.mu = bnet.values(bnode.self);
  dist.Sigma = zeros(length(mu));
  return;
end

dps = intersect(bnode.parents, bnet.discrete_nodes);
cps = intersect(bnode.parents, bnet.cts_nodes);
assert(length(dps)<=1); % just for simplicity
assert(length(cps)<=1);

if isempty(dps)
  w = 1;
else
  dp = dps(1);
  if ismember(dp, bnet.observed_nodes) % don't collapse
    v = bnet.values(dp);
    w = zeros(1, ns(dp));
    w(v) = 1;
  else
    w = cond_dist_node(bnet, dp);
  end
end

if isempty(cps)
  mu = bnode.mean;
else
  x = bnet.values(cps);
  if isempty(dps)
    M = 1;
  else
    M = ns(dps(1));
  end
  mu = zeros(ns(bnode.self), M);
  for i=1:M
    mu(:,i) = bnode.mean(:,i) + bnode.weights(:,:,i)*x;
  end
end
[mu, Sigma] = collapse_mog(mu, bnode.cov, w);
dist.mu = mu;
dist.Sigma = Sigma;

