function ls = logsum(xx,dim) % ls = logsum(x,dim) % % returns the log of sum of logs, summing over dimension dim % computes ls = log(sum(exp(x),dim)) % but in a way that tries to avoid underflow/overflow % % basic idea: shift before exp and reshift back % log(sum(exp(x))) = alpha + log(sum(exp(x-alpha))); % % also deal with summing over vectors which consist only % of -Inf by checking at end and removing NaN's introduced by -Inf -(-Inf) if(size(xx,dim)<=1) ls=xx; return; end xdims=size(xx); if(nargin<2) nonsingletons=find(xdims>1); dim=nonsingletons(1); end alpha = max(xx,[],dim)-log(realmax)/2+2*log(xdims(dim)); repdims=ones(size(xdims)); repdims(dim)=xdims(dim); ls = alpha+log(sum(exp(xx-repmat(alpha,repdims)),dim)); ff=find(max(xx,[],dim)==-Inf); if(~isempty(ff)) ls(ff)=-Inf; end