function [m, r] = soft_kmeans(x, m_old, beta)
% soft k-means iteration step
% Lecture: Unsupervised Learning (C.E.Rasmussen & M.O.Franz)
% 
% for a given cloud of data points x (data points are the rows of matrix x), 
% an old set of cluster means m_old (means are the rows of m_old), compute
% new means and the responsibility matrix.
%
% Copyright Matthias Franz and Carl Edward Rasmussen 2006-04-29.

k = size(m_old, 1); % number of means
n = size(x, 1);     % number of data points

% assignment step
r = zeros(n, k);  % alloc responsibility matrix
for i=1:n % for each data point
    
    % compute soft assignments
    row_sum = 0;
    for j=1:k
        d = norm(x(i,:) - m_old(j,:)); % distance of x_i to m_j
        r(i, j) = exp(-beta*d);
        row_sum = row_sum + r(i, j);
    end
    if row_sum > 0
        r(i,:) = r(i,:)/row_sum; % normalise
    end
end

% update step
m = zeros(size(m_old)); % alloc new means
col_sum = sum(r, 1); % get overall cluster assignment as sum over columns in r
m = (r'*x); % sum over all vectors in cluster
for j=1:k % divide by number of cluster members
    if col_sum(j) > 0
        m(j,:) = m(j,:)/col_sum(j);
    end
end