function net = mixheuristic(net, x, t, post)
%mixheuristic Specialised training of a GLM expert network with one-pass weighted least squares for the M-step of a ME trained by EM
%
%	NET = MIXHEURISTIC(NET, X, T, POST) uses a one-pass weighted
%	(the posterior probabilities POST) least squares algorithm to set
%	the weights in the generalized linear model structure NET.  This is
%	a more efficient alternative to using MIXERR and MIXGRAD and a
%	non-linear optimisation routine through MIXOPT. Each row of X
%	corresponds to one input vector and each row of T corresponds to one
%	target vector.
%
%       See also
%       mixtrain, glmtrain, mixem, mix
%
%       Copyright: Perry Moerland

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

ndata = size(x, 1);
% Add a column of ones for the bias 
inputs = [x ones(ndata, 1)];

% one step

switch net.actfn
  
  case 'linear'
  % Solve for the weights and biases using left matrix divide
  temp = (sqrt(diag(post))*inputs)\(sqrt(diag(post))*t);
  
case 'logistic'
  % invert the logistic activation function
  i = (1./(t+0.001))-(1-0.001);
  i = max(i,realmin);
  i = min(i,realmax);
  t = -log(i);
  % Solve for the weights and biases using left matrix divide
  temp = (sqrt(diag(post))*inputs)\(sqrt(diag(post))*t); 
    
  case 'softmax'
  % ensure that log(t) is computable
  t(t<eps) = eps;
  % Solve for the weights and biases using left matrix divide
  % using an inversion of the softmax activation function
  temp = (sqrt(diag(post))*inputs)\(sqrt(diag(post))*log(t));
   
end;

net.w1 = temp(1:net.nin, :);
net.b1 = temp(net.nin+1, :);

