www.pudn.com > gmm_utilities.zip > gmm_reduce_merge.m


function g = gmm_reduce_merge(g, N) 
% Based on Mike West's merge-smallest algorithm 
 
if size(g.x,2) <= N, return, end 
g = gmm_remove_zeros(g); 
 
while size(g.x,2) > N 
 
    % Select min weight kernel 
    wmin = min(g.w); 
    i = find(g.w == wmin); 
    if length(i) > 1 
        idx = ceil(rand(1)*length(i)); 
        i = i(idx); 
    end 
     
    % Find its nearest neighbour (weighted Mahalanobis) 
    w = wmin*g.w ./ (wmin + g.w); 
    v = g.x - repcol(g.x(:,i), size(g.x,2)); 
    M = distance_mahalanobis(v, g.P(:,:,i)) .* w; % ?? using only the covariance of component i (why?) 
    M(i) = NaN; 
    [Mmin, j] = min(M); 
     
    % Merge components into element i 
    idx = [i j]; 
    gtmp.x = g.x(:,idx); 
    gtmp.P = g.P(:,:,idx); 
    gtmp.w = g.w(idx); 
    [g.x(:,i), g.P(:,:,i), g.w(i)] = gmm_to_gaussian(gtmp); 
 
    % Remove element j 
    merge = logical(ones(size(g.w))); 
    merge(j) = 0; 
    g.x = g.x(:,merge); 
    g.P = g.P(:,:,merge); 
    g.w = g.w(merge); 
end