Accord.Math.Decompositions.NonnegativeMatrixFactorization.compute C# (CSharp) Method

compute() private method

Performs NMF using the multiplicative method
At the end of the computation H contains the projected data and W contains the weights. The multiplicative method is the simplest factorization method.
private compute ( int maxiter ) : void
maxiter int The maximum number of iterations
return void
        private void compute(int maxiter)
        {
            // chose W and H randomly, W with unit norm
            W = Accord.Math.Matrix.Random(m, r);
            H = Accord.Math.Matrix.Random(r, n);

            var Z = new double[r, r];

            // a small epsilon is added to the
            //  denominator to avoid overflow.
            double eps = 10e-9;


            for (int t = 0; t < maxiter; t++)
            {
                var newW = new double[m, r];
                var newH = new double[r, n];


                // Update H using the multiplicative
                // H = H .* (W'*A) ./ (W'*W*H + eps) 
                for (int i = 0; i < r; i++)
                {
                    for (int j = i; j < r; j++)
                    {
                        double s = 0.0;
                        for (int l = 0; l < m; l++)
                            s += W[l, i] * W[l, j];
                        Z[i, j] = Z[j, i] = s;
                    }

                    for (int j = 0; j < n; j++)
                    {
                        double d = 0.0;
                        for (int l = 0; l < r; l++)
                            d += Z[i, l] * H[l, j];

                        double s = 0.0;
                        for (int l = 0; l < m; l++)
                            s += W[l, i] * X[j, l];

                        newH[i, j] = H[i, j] * s / (d + eps);
                    }
                }

                // Update W using the multiplicative
                //   W = W .* (A*H') ./ (W*H*H' + eps)
                for (int j = 0; j < r; j++)
                {
                    for (int i = j; i < r; i++)
                    {
                        double s = 0.0;
                        for (int l = 0; l < m; l++)
                            s += newH[i, l] * newH[j, l];
                        Z[i, j] = Z[j, i] = s;
                    }

                    for (int i = 0; i < m; i++)
                    {
                        double d = 0.0;
                        for (int l = 0; l < r; l++)
                            d += W[i, l] * Z[j, l];

                        double s = 0.0;
                        for (int l = 0; l < n; l++)
                            s += X[l, i] * newH[j, l];

                        newW[i, j] = W[i, j] * s / (d + eps);
                    }
                }

                W = newW;
                H = newH;
            }

           
        }
    }
NonnegativeMatrixFactorization