function e = mixmlperr(net, x, t)
%mixmlperr  Evaluate error function for a gated experts model
%
%       E = MIXMLPERR(NET, X, T) takes a gated experts data structure
%       NET, a matrix X of input vectors and a matrix T of target vectors,
%       and evaluates the error function E. The error function is the
%       negative log likelihood of the target data under the mixture of
%       conditional densities (which can be Gaussian/Bernoulli/multinomial 
%       and leads to output activation functions that are linear/logistic/softmax respectively). 
%
%       See also
%       mixmlpgrad, netopt, mixmlpfwd, mixgrad_em, mixerr_em
%
%       Copyright: Perry Moerland
	

errstring = consist(net, 'mixmlp', x, t);
if ~isempty(errstring)
  error(errstring);
end

[y, y_exp, y_ehidden, y_gate] =  mixmlpfwd(net,x);

ndata = size(t, 1);
nexp  = net.nexp;

prob = zeros(ndata,nexp);
e = 0;

switch net.actfn
  
  case 'linear'         % Linear outputs  
    
        for i=1:nexp
         % Calculate squared norm matrix, of dimension (ndata, 1) 
         n1 = t-y_exp(:,:,i);
         n2 = sum(n1.^2,2);
         normal = (2*pi) .^ (net.nout/2);
         % Now compute the activations
         a = exp(-(n2/2))./ normal;
       
         prob(:,i) = y_gate(:,i).*a;
        end;
	e = sum(-log(max(eps,sum(prob,2))));
 
  case 'logistic'       % Logistic outputs
   
    for i=1:nexp
     % Calculate cross-entropy norm matrix, of dimension (ndata, 1) 
     n1 = (y_exp(:,:,i).^t).*((1-y_exp(:,:,i)).^(1-t));
     
     prob(:,i) = y_gate(:,i).*n1;
    end;
    e = sum(-log(max(eps,sum(prob,2))));
  
  case 'softmax'        % Softmax outputs   
    
    for i=1:nexp
     % Calculate multinomial norm matrix, of dimension (ndata, 1) 
     n1 = y_exp(:,:,i).^t;
     n2 = prod(n1,2);
   
     prob(:,i) = y_gate(:,i).*n2;
    end;
    e = sum(-log(max(eps,sum(prob,2))));
end;


