function bnode = mk_softmax_node(bnet, self)
% MK_SOFTMAX_NODE Make a node whose cond. distrib. is a softmax (multinomial logit)
% BNODE = MK_SOFTMAX_NODE(BNET, NODE_NUM)
%
% The params. are called glim.w1 and glim.b1 for the weights and bias respectively.
% w1(:,i) is the normal vector to the i'th decision boundary. If it has a small magnitude.
% the boundary will be soft; if large, it will be hard.
% b1(i) is the offset for the i'th decision boundary.
% e.g., consider the case where the parent values are in R^2 and the child is binary:
%  w1 = [1 -1  , b1 = [0 0]  means class 1 are points with +ve x coord.
%        0  0]                     class 2 "     "     "   -ve x coord.
% If bnet.node_sizes(self) = 2, this will be a logistic function.
%
% The following fields control the behavior of the M step (maximize_params_softmax).
% (Note that the M step calls glmtrain, so netlab must be installed.)
% bnode.max_iter is the maximum number of steps to take (default: 10)
% bnode.verbose controls whether to print (default: 0).
% bnode.wthresh is a measure of the precision required for the value of
%    the weights W at the solution. Default: 1e-2.
% bnode.llthresh is a measure of the precision required of the objective
%     function at the solution.  Both this and the previous condition must
%     be satisfied for termination. Default: 1e-2.
% bnode.approx_hess is set to 1 if an approximation to the Hessian (which
%     assumes that all outputs are independent) is used for softmax
%     outputs. With the default value of 0 the exact Hessian (which is more
%     expensive to compute) is used.
%


bnode.verbose = 0;
bnode.wthresh = 1e-2;
bnode.llthresh = 1e-2;
bnode.approx_hess = 0;
bnode.max_iter = 10;

bnode.self = self;
bnode.parents = parents(bnet.adj_mat, self);

if 0
for i=1:length(bnode.parents)
  p = bnode.parents(i);
  if ~strcmp(bnet.bnodes{p}.type, 'input')
    error(['parent ' num2str(p) ' of softmax node is not an input node']);
  end
end
end

if ~subset(bnode.parents, bnet.cts_nodes)
  error('softmax nodes must have continous parents');
end

if ~ismember(self, bnet.discrete_nodes)
  error('softmax nodes must be discrete');
end

ns = bnet.node_sizes;
bnode.type = 'softmax';
bnode.adjustable = 1;
bnode.parents_size = sum(ns(bnode.parents));
bnode.self_size = sum(ns(self));
bnode.sizes = [ns(bnode.parents) ns(self)];

bnode = randomize_params_softmax(bnode);
bnode = reset_ess_softmax(bnode);



