function [e, varargout] = mixerr_em(w, net, x, t, post, errstr , gradstr, varargin)
%mixerr_em   Evaluate the error function for an expert or a gating network when training a mixture of epxerts (or gated experts) model with EM
%
%	E = MIXERR_EM(W, NET, X, T, POST, ERRSTR, GRADSTR) 
%       takes a network data structure NET (either one of the expert 
%       networks or the gating network) and its corresponding weight
%       vector, together with the matrix X of input vectors and the matrix 
%       T of target vectors, and returns the value of the error function 
%       evaluated at W. 
%       MIXERR_EM mainly serves as a helper function that passes on its
%       arguments to the function specified in the string ERRSTR which
%       can be:
%          'mixerr_exp'     = calculates the error function for a GLM expert network.
%          'mixerr_gate'    = calculates the error function for a GLM gating network.
%          'mixmlperr_exp'  = calculates the error function for a MLP expert network.
%          'mixmlperr_gate' = calculates the error function for a MLP gating network.
%
%       The posterior probabilities POST are also passed on to ERRSTR. 
%
%       E = MIXERR_EM(W, NET, X, T, POST, ERRSTR, GRADSTR, SIGMA) if the 
%       conditional  density for the experts is an isotropic Gaussian (with 
%       one variance parameter for each expert), SIGMA contains these
%       variances. 
%
%       [E,VARARGOUT] = MIXERR_EM(W, NET, X, T, POST, ERRSTR, GRADSTR,VARARGIN) 
%       also returns any additional return values from the error function. 
%
%       See also
%       mixgrad_em, mixerr_exp, mixmlperr_exp, mixerr_gate, mixmlperr_gate, mixem, mixmlpem, mixopt
%
%       Copyright: Perry Moerland

unpakstr = [net.type, 'unpak'];

net = feval(unpakstr, net, w);

[s{1:nargout}] = feval(errstr, net, x, t , post, varargin{:});
e = s{1};
if nargout > 1
  for i = 2:nargout
    varargout{i-1} = s{i};
  end
end
