function [ W, U, G, H ] = mlNMFupd( V, W, U, G, H, E, n )
%MLNMFUPD multi level NMF update, single iteration
%   Given target Nonnegative matrices V, W, U, G, H, and E, update one of
%   W, U, G, H based on the value of n (= 1...4) such that 
%       V approx. = WUGH.*E.   (.* being the Hadamard product)
%   It should be guranteed that after this function is done the product
%   WUGH.*E is closer to V than before using the Itakura-Saito cost 
%   function. E can be omitted, in which case it is assumed to be all ones.
%   This function is based on the NMF update in the FASST Toolbox,
%   http://bass-db.gforge.inria.fr/fasst/ by A. Ozerov, E. Vincent and F.
%   Bimbot, but is completely new code.
%
%   (c) Joachim Thiemann 2013    joachim.thiemann@ieee.org
%   Licensed under the Creative Commons Attribution-ShareAlike Unported
%   3.0 license

if nargin < 7
    n = E;
    E = 1;
end

% setup matrices
switch n
    case 1
        B = eye(size(W,1));
        C = W;
        D = U*G*H;
    case 2
        B = W;
        C = U;
        D = G*H;
    case 3
        B = W*U;
        C = G;
        D = H;
    case 4
        B = W*U*G;
        C = H;
        D = eye(size(H,2));
    otherwise
        error('mlNMFupd:err_n','n is out of range');
end

% prepare update: common term
BCDdinv = 1 ./ (B*C*D);

% update
num = B.' * ( V .* (1./E) .* BCDdinv.^2 ) * D.';
den = B.' * BCDdinv * D.';
C = C .* num ./ den;

% update output only
switch n
    case 1
        W = C;
    case 2
        U = C;
    case 3
        G = C;
    case 4
        H = C;
end

end

