function [a,run] = dirichlet_fit(data,a)
% DIRICHLET_FIT Maximum-likelihood Dirichlet distribution.
%
% DIRICHLET_FIT(data) returns the MLE (a) for the matrix DATA.
% Each row of DATA is a probability vector.
% DIRICHLET_FIT(data,a) provides an initial guess A to speed up the search.
%
% The Dirichlet distribution is parameterized as
% p(p) = (Gamma(sum_k a_k)/prod_k Gamma(a_k)) prod_k p_k^(a_k-1)
%
% The algorithm is an alternating optimization for m and for s, described in
% "Estimating a Dirichlet distribution" by T. Minka.
% Written by Tom Minka
bar_p = mean(log(data));
[N,K] = size(data);
addflops(numel(data)*(flops_exp + 1));
if nargin < 2
a = dirichlet_moment_match(data);
%s = dirichlet_initial_s(a,bar_p);
%a = s*a/sum(a);
end
s = sum(a);
if s <= 0
% bad initial guess; fix it
disp('fixing initial guess')
if s == 0
a = ones(size(a))/length(a);
else
a = a/s;
end
s = 1;
end
for iter = 1:100
old_s = s;
% time for fit_s is negligible compared to fit_m
a = dirichlet_fit_s(data, a, bar_p);
s = sum(a);
a = dirichlet_fit_m(data, a, bar_p, 1);
m = a/s;
addflops(2*K-1);
if nargout > 1
run.e(iter) = N*dirichlet_logProb_fast(a, bar_p);
run.flops(iter) = flops;
end
if abs(s - old_s) < 1e-4
break
end
end
%flops(flops + iter*(2*K-1));