This tutorial explains how to use the nonnegative matrix factorization (NMF) functionality in ViennaCL.
The first step is to include the necessary headers and define the floating point type used for the computations:
The following routine fills a matrix with uniformly distributed random values from the interval [0,1]. This is used to initialize the matrices to be factored
template<typename MajorT>
{
for (std::size_t i = 0; i < A.
size1(); i++)
for (std::size_t j = 0; j < A.
size2(); ++j)
}
In the main routine we set up a matrix V and compute approximate factors W and H such that , where all three matrices carry nonnegative entries only. Since W and H are usually chosen to represent a rank-k-approximation of V, we use a similar low-rank approximation here.
{
std::cout << std::endl;
std::cout << "------- Tutorial NMF --------" << std::endl;
std::cout << std::endl;
Approximate the 7-by-6-matrix V by a 7-by-3-matrix W and a 3-by-6-matrix H
unsigned int m = 7;
unsigned int n = 6;
unsigned int k = 3;
Fill the matrices randomly. Initial guesses for W and H consisting of only zeros won't work.
std::cout << "Input matrices:" << std::endl;
std::cout << "V" << V << std::endl;
std::cout << "W" << W << std::endl;
std::cout << "H" << H << "\n" << std::endl;
Create configuration object to hold (and adjust) the respective parameters.
Call the NMF routine and print the results
std::cout << "Computing NMF" << std::endl;
std::cout << "RESULT:" << std::endl;
std::cout << "V" << V << std::endl;
std::cout << "W" << W << std::endl;
std::cout << "H" << H << "\n" << std::endl;
Print the product W*H approximating V for comparison and exit:
std::cout << "W*H:" << std::endl;
std::cout << resultCorrect << std::endl;
std::cout << std::endl;
std::cout << "------- Tutorial completed --------" << std::endl;
std::cout << std::endl;
}
Full Example Code
template<typename MajorT>
{
for (std::size_t i = 0; i < A.
size1(); i++)
for (std::size_t j = 0; j < A.
size2(); ++j)
A(i, j) =
static_cast<ScalarType
>(rand()) /
ScalarType(RAND_MAX);
}
{
std::cout << std::endl;
std::cout << "------- Tutorial NMF --------" << std::endl;
std::cout << std::endl;
unsigned int m = 7;
unsigned int n = 6;
unsigned int k = 3;
std::cout << "Input matrices:" << std::endl;
std::cout << "V" << V << std::endl;
std::cout << "W" << W << std::endl;
std::cout << "H" << H << "\n" << std::endl;
std::cout << "Computing NMF" << std::endl;
std::cout << "RESULT:" << std::endl;
std::cout << "V" << V << std::endl;
std::cout << "W" << W << std::endl;
std::cout << "H" << H << "\n" << std::endl;
std::cout << "W*H:" << std::endl;
std::cout << resultCorrect << std::endl;
std::cout << std::endl;
std::cout << "------- Tutorial completed --------" << std::endl;
std::cout << std::endl;
}