function g = mixmlpgrad(net, x, t)
%mixmlpgrad Evaluate the error gradient for the gated experts model
%
%         G = MIXGRAD(NET,X,T) takes a gated experts data structure 
%         NET together with a matrix X of input vectors and a matrix 
%         T of target vectors, and evaluates the gradient G of the error
%         function with respect to the network weights. The error 
%         function is based on a mixture of conditional densities
%         (which can be Gaussian/Bernoulli/multinomial and leads
%         to output activation functions that are linear/logistic/softmax
%         respectively).
%
%         See also
%         mixmlperr, netopt, mixmlpfwd, mixpost, mixgrad_em, mixerr_em
%
% Copyright: Perry Moerland 


% Check arguments for consistency
errstring = consist(net, 'mixmlp', x, t);
if ~isempty(errstring)
  error(errstring);
end

nexp = net.nexp;
g = [];

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

post = mixpost(net,y_exp,y_gate,t);

for i=1:nexp
  delout = y_exp(:,:,i) - t;
  deltas_exp = diag(sparse(post(:,i)))*delout; 
  % calculate gradients for expert network i
  temp =  mlpbkp(net.exp(i), x, y_ehidden(:,:,i), deltas_exp);
  g = cat(2,g,temp);
end;

% calculate gradients for the gating network 
deltas_gate = y_gate-post;
temp = mlpbkp(net.gate, x, y_ghidden, deltas_gate);
g = cat(2,g,temp);
