inline static void Initialize(const MatType& V, const size_t r, arma::mat& W, arma::mat& H) { const size_t n = V.n_rows; const size_t m = V.n_cols; double avgV = 0; size_t count = 0; double min = DBL_MAX; // Iterate over all elements in the matrix (for sparse matrices, this only // iterates over nonzeros). for (typename MatType::const_row_col_iterator it = V.begin(); it != V.end(); ++it) { ++count; avgV += *it; // Track the minimum value. if (*it < min) min = *it; } avgV = sqrt(((avgV / (n * m)) - min) / r); // Initialize to random values. W.randu(n, r); H.randu(r, m); W = W + avgV; H = H + avgV; }
inline static void Initialize(const MatType& V, const size_t r, arma::mat& W, arma::mat& H) { size_t n = V.n_rows; size_t m = V.n_cols; double V_avg = 0; size_t count = 0; double min = DBL_MAX; for(typename MatType::const_row_col_iterator it = V.begin();it != V.end();it++) { if(*it != 0) { count++; V_avg += *it; if(*it < min) min = *it; } } V_avg = sqrt(((V_avg / (n * m)) - min) / r); // Intialize to random values. W.randu(n, r); H.randu(r, m); W = W + V_avg; H = H + V_avg; }
inline static void Initialize(const MatType& V, const size_t r, arma::mat& W, arma::mat& H) { // Simple implementation (left in the header file due to its simplicity). const size_t n = V.n_rows; const size_t m = V.n_cols; // Initialize to random values. W.randu(n, r); H.randu(r, m); }
inline static void Initialize(const MatType& V, const size_t r, arma::mat& W, arma::mat& H) { const size_t n = V.n_rows; const size_t m = V.n_cols; if (columnsToAverage > m) { Log::Warn << "Number of random columns (columnsToAverage) is more than " << "the number of columns available in the V matrix; weird results " << "may ensue!" << std::endl; } W.zeros(n, r); // Initialize W matrix with random columns. for (size_t col = 0; col < r; col++) { for (size_t randCol = 0; randCol < columnsToAverage; randCol++) { // .col() does not work in this case, as of Armadillo 3.920. W.unsafe_col(col) += V.col(math::RandInt(0, m)); } } // Now divide by p. W /= columnsToAverage; // Initialize H to random values. H.randu(r, m); }
inline static void Initialize(arma::mat& weights, arma::vec& biases, const size_t numFeatures, const size_t numClasses) { weights.randu(numFeatures, numClasses); biases.randu(numClasses); }
void MVU::Unfold(const size_t newDim, const size_t numNeighbors, arma::mat& outputData) { // First we have to choose the output point. We'll take a linear projection // of the data for now (this is probably not a good final solution). // outputData = trans(data.rows(0, newDim - 1)); // Following Nick's idea. outputData.randu(data.n_cols, newDim); // The number of constraints is the number of nearest neighbors plus one. LRSDP<arma::sp_mat> mvuSolver(numNeighbors * data.n_cols + 1, outputData); // Set up the objective. Because we are maximizing the trace of (R R^T), // we'll instead state it as min(-I_n * (R R^T)), meaning C() is -I_n. mvuSolver.C().eye(data.n_cols, data.n_cols); mvuSolver.C() *= -1; // Now set up each of the constraints. // The first constraint is trace(ones * R * R^T) = 0. mvuSolver.B()[0] = 0; mvuSolver.A()[0].ones(data.n_cols, data.n_cols); // All of our other constraints will be sparse except the first. So set that // vector of modes accordingly. mvuSolver.AModes().ones(); mvuSolver.AModes()[0] = 0; // Now all of the other constraints. We first have to run AllkNN to get the // list of nearest neighbors. arma::Mat<size_t> neighbors; arma::mat distances; AllkNN allknn(data); allknn.Search(numNeighbors, neighbors, distances); // Add each of the other constraints. They are sparse constraints: // Tr(A_ij K) = d_ij; // A_ij = zeros except for 1 at (i, i), (j, j); -1 at (i, j), (j, i). for (size_t i = 0; i < neighbors.n_cols; ++i) { for (size_t j = 0; j < numNeighbors; ++j) { // This is the index of the constraint. const size_t index = (i * numNeighbors) + j + 1; arma::mat& aRef = mvuSolver.A()[index]; aRef.set_size(3, 4); // A_ij(i, i) = 1. aRef(0, 0) = i; aRef(1, 0) = i; aRef(2, 0) = 1; // A_ij(i, j) = -1. aRef(0, 1) = i; aRef(1, 1) = neighbors(j, i); aRef(2, 1) = -1; // A_ij(j, i) = -1. aRef(0, 2) = neighbors(j, i); aRef(1, 2) = i; aRef(2, 2) = -1; // A_ij(j, j) = 1. aRef(0, 3) = neighbors(j, i); aRef(1, 3) = neighbors(j, i); aRef(2, 3) = 1; // The constraint b_ij is the distance between these two points. mvuSolver.B()[index] = distances(j, i); } } // Now on with the solving. double objective = mvuSolver.Optimize(outputData); Log::Info << "Final objective is " << objective << "." << std::endl; // Revert to original data format. outputData = trans(outputData); }