function [likelihood] = likeNet(parents,cpts,inputs)
%
% function [likelihood] = likeNet(parents,cpts,inputs)
%
% Computes the log-likelihood of the discrete Bayes Net
% on the data in inputs
%
% Parents is an MxM matrix for each node listing
% which nodes are its parents. A one says that the
% corresponding column is a parent of the current row
% and zero means not a parents
% Make sure that parents come first (topological)
% Make sure that this is a valid DAG
% Make sure that nodes are not self-parents
%
% inputs is an NxM matrix where the values at the
% m'th column range from 0..D_m 
%
% cpts is a matrix of rows where each row corresponds
% to a node and contains its conditional probability
% hypercube rasterized as a long vector
%

[N,M] = size(inputs);

% Figure out the conditional probability tables (cpt) sizes
cards = max(inputs);
cards = cards+ones(size(cards));
cptsize = zeros(M,1);
for i=1:M
  cptsize(i) = cards(i);
  for j=1:(i-1)
    if (parents(i,j)>0.5)
      cptsize(i) = cptsize(i)*cards(j);
    end
  end
end

% Verify that the cpts are normalized properly
for i=1:M
  index = 1;
  while (index<cptsize(i))
    tiny = min(cpts(i,index:index+(cards(i)-1)));
    if (tiny<0.0)
      fprintf(1,'BAD: Found negative for cpt for node %d at index [%d,%d].\n',i,tot,index,index+cards(i)-1);
    end
    tot  = sum(cpts(i,index:index+(cards(i)-1)));
    if (abs(tot-1.0)>0.0001)
      fprintf(1,'BAD: The cpt for node %d sums to %f at index %d.\n',i,tot,index);
    end
    index = index+cards(i);
  end
end

% Compute the log-likelihood for each data point for
% each node (sum log probs across all N points and M nodes)
likelihood = 0.0;
for n=1:N
  logp = 0;
  for i=1:M
    index = 0;
    for j=1:(i-1)
      if (parents(i,j)>0.5)
        index = (index + inputs(n,j))*cards(j+1);
      end
    end
    index = index + inputs(n,i);
    if (cpts(i,index+1)<0.0)
      fprintf(1,'BAD: Found Negative in Conditional Probability Table Storage\n');
    else
      logp  = logp + log(cpts(i,index+1));
    end
  end
  likelihood = likelihood + logp;
end
