function [M,I] = softmax(X,temperature) 

% SOFTMAX   Probabilistic temperature-dependent maximum.
%
%   M = SOFTMAX(X,TEMPERATURE)
%   [M,I] = SOFTMAX(X,TEMPERATURE)
%
%   Probabilistic ("soft") maximum governed by the Boltzmann equation.
%   The probability of choosing element i is proportional to 
%     exp(X(i)/temperature)
%
%   For vectors, SOFTMAX(X,T) is the soft maximum of the elements in X.
%   For matrices, SOFTMAX(X,T) is a row vector containing the softmax 
%   element from each column. N-D arrays are not supported. 
%   [M,I] = SOFTMAX(X,T) returns the indices of the softmax values in 
%   vector I.
%   All elements of X must have the same sign.
%
%   The higher the temperature, the "softer" the max.
%   SOFTMAX(X,0) is equivalent to MAX(X).
%   SOFTMAX(X,Inf) draws a random element from each column.
%
%   Note that SOFTMAX(X,Y) for row vectors X and Y is not the "soft" 
%   analog to MAX(X,Y); use SOFTMAX([X;Y],TEMPERATURE) instead.
%
%   See also SOFTMAX1, MAX, ANYRND.

% Original coding by Alex Petrov, Ohio State University
% $Revision: 1.1 $  $Date: 2001/08/01 17:30 $
%
% Part of the utils toolbox version 1.1 for MATLAB version 5 and up.
% http://alexpetrov.com/softw/utils/
% Copyright (c) Alexander Petrov 1999-2006, http://alexpetrov.com
% Please read the LICENSE and NO WARRANTY statement in ../utils_license.m

%-- Handle special cases
if (temperature < eps)   % zero or negative?
  [M,I] = max(X) ;
  return
end
[rows,cols] = size(X) ;
if (rows==1 & cols>1)    % row vector?
  [M,I] = softmax(X',temperature) ;
  return
end

%-- Calculate Boltzmann probabilities
p = exp(X./temperature) ;
p = p ./ repmat(sum(p),rows,1) ;

%-- Draw one random deviate per column -- compare with function ANYRND
cum_p = cumsum(p) ;       % [RxC]
u = rand(1,cols) ;        % [1xC]
hits = (cum_p <= repmat(u,rows,1)) ;  % [RxC] matrix of 1s and 0s
I = sum(hits) + 1 ;       % [1xC] one random choice per column

%-- Convert the indices I into values M
linear_I = sub2ind([rows,cols],I,[1:cols]) ;
M = X(linear_I) ;

%-- Return M and I
%%%%% End of SOFTMAX.M
