[mlpack-svn] r12377 - mlpack/trunk/src/mlpack/methods/sparse_coding

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Fri Apr 13 18:50:47 EDT 2012


Author: rcurtin
Date: 2012-04-13 18:50:47 -0400 (Fri, 13 Apr 2012)
New Revision: 12377

Modified:
   mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp
   mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp
Log:
Pass two: const-correctness (mostly) and use size_t instead of arma::uword.


Modified: mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp	2012-04-13 22:29:38 UTC (rev 12376)
+++ mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.cpp	2012-04-13 22:50:47 UTC (rev 12377)
@@ -18,11 +18,11 @@
 #define NEWTON_TOL 1e-6 // 1E-9
 
 SparseCoding::SparseCoding(const mat& matX,
-                           uword nAtoms,
-                           double lambda1,
-                           double lambda2) :
+                           const size_t atoms,
+                           const double lambda1,
+                           const double lambda2) :
     nDims(matX.n_rows),
-    nAtoms(nAtoms),
+    nAtoms(atoms),
     nPoints(matX.n_cols),
     matX(matX),
     matZ(mat(nAtoms, nPoints)),
@@ -40,21 +40,11 @@
   this->matD = matD;
 }
 
-void SparseCoding::InitDictionary()
-{
-  DataDependentRandomInitDictionary();
-}
-
-void SparseCoding::LoadDictionary(const char* dictionaryFilename)
-{
-  matD.load(dictionaryFilename);
-}
-
 // Always a not good decision!
 void SparseCoding::RandomInitDictionary() {
   matD = randn(nDims, nAtoms);
 
-  for (uword j = 0; j < nAtoms; ++j)
+  for (size_t j = 0; j < nAtoms; ++j)
     matD.col(j) /= norm(matD.col(j), 2);
 }
 
@@ -62,7 +52,7 @@
 void SparseCoding::DataDependentRandomInitDictionary()
 {
   matD = mat(nDims, nAtoms);
-  for (uword j = 0; j < nAtoms; ++j)
+  for (size_t j = 0; j < nAtoms; ++j)
   {
     vec vecD_j = matD.unsafe_col(j);
     RandomAtom(vecD_j);
@@ -72,16 +62,15 @@
 void SparseCoding::RandomAtom(vec& atom)
 {
   atom.zeros();
-  const uword nSeedAtoms = 3;
-  for(uword i = 0; i < nSeedAtoms; i++)
+  const size_t nSeedAtoms = 3;
+  for (size_t i = 0; i < nSeedAtoms; i++)
     atom += matX.col(rand() % nPoints);
 
   atom /= norm(atom, 2);
 }
 
-void SparseCoding::DoSparseCoding(uword nIterations)
+void SparseCoding::DoSparseCoding(const size_t maxIterations)
 {
-  bool converged = false;
   double lastObjVal = DBL_MAX;
 
   Log::Info << "Initial Coding Step." << endl;
@@ -94,9 +83,9 @@
       << "%" << endl;
   Log::Info << "  Objective value: " << Objective() << "." << endl;
 
-  for (uword t = 1; t <= nIterations && !converged; ++t)
+  for (size_t t = 1; t != maxIterations; ++t)
   {
-    Log::Info << "Iteration " << t << " of " << nIterations << "." << endl;
+    Log::Info << "Iteration " << t << " of " << maxIterations << "." << endl;
 
     Log::Info << "Performing dictionary step... ";
     OptimizeDictionary(adjacencies);
@@ -118,8 +107,8 @@
 
     if (objValImprov < OBJ_TOL)
     {
-      converged = true;
       Log::Info << "Converged within tolerance " << OBJ_TOL << ".\n";
+      break;
     }
 
     lastObjVal = curObjVal;
@@ -138,9 +127,9 @@
   //   matGram = trans(matD) * matD;
   // }
 
-  for (uword i = 0; i < nPoints; i++)
+  for (uword i = 0; i < nPoints; ++i)
   {
-    // report progress
+    // Report progress.
     if ((i % 100) == 0)
       Log::Debug << "Optimization at point " << i << "." << endl;
 
@@ -162,8 +151,7 @@
   }
 }
 
-
-void SparseCoding::OptimizeDictionary(uvec adjacencies)
+void SparseCoding::OptimizeDictionary(const uvec& adjacencies)
 {
   // Count the number of atomic neighbors for each point x^i.
   uvec neighborCounts = zeros<uvec>(nPoints, 1);
@@ -171,19 +159,20 @@
   if (adjacencies.n_elem > 0)
   {
     // This gets the column index.
-    uword curPointInd = (uword)(adjacencies(0) / nAtoms);
-    uword curCount = 1;
+    // TODO: is this integer division intentional?
+    size_t curPointInd = (size_t) (adjacencies(0) / nAtoms);
+    size_t curCount = 1;
 
-    for (uword l = 1; l < adjacencies.n_elem; ++l)
+    for (size_t l = 1; l < adjacencies.n_elem; ++l)
     {
-      if ((uword)(adjacencies(l) / nAtoms) == curPointInd)
+      if ((size_t) (adjacencies(l) / nAtoms) == curPointInd)
       {
-        curCount++;
+        ++curCount;
       }
       else
       {
         neighborCounts(curPointInd) = curCount;
-        curPointInd = (uword)(adjacencies(l) / nAtoms);
+        curPointInd = (size_t) (adjacencies(l) / nAtoms);
         curCount = 1;
       }
     }
@@ -192,11 +181,11 @@
   }
 
   // Handle the case of inactive atoms (atoms not used in the given coding).
-  std::vector<uword> inactiveAtoms;
-  std::vector<uword> activeAtoms;
+  std::vector<size_t> inactiveAtoms;
+  std::vector<size_t> activeAtoms;
   activeAtoms.reserve(nAtoms);
 
-  for (uword j = 0; j < nAtoms; j++)
+  for (uword j = 0; j < nAtoms; ++j)
   {
     if (accu(matZ.row(j) != 0) == 0)
       inactiveAtoms.push_back(j);
@@ -204,8 +193,8 @@
       activeAtoms.push_back(j);
   }
 
-  uword nActiveAtoms = activeAtoms.size();
-  uword nInactiveAtoms = inactiveAtoms.size();
+  const size_t nActiveAtoms = activeAtoms.size();
+  const size_t nInactiveAtoms = inactiveAtoms.size();
 
   // Efficient construction of Z restricted to active atoms.
   mat matActiveZ;
@@ -215,15 +204,13 @@
   }
   else
   {
-    uvec inactiveAtomsVec = conv_to< uvec >::from(inactiveAtoms);
+    uvec inactiveAtomsVec = conv_to<uvec>::from(inactiveAtoms);
     RemoveRows(matZ, inactiveAtomsVec, matActiveZ);
   }
 
   uvec atomReverseLookup = uvec(nAtoms);
-  for(uword i = 0; i < nActiveAtoms; i++)
-  {
+  for (uword i = 0; i < nActiveAtoms; ++i)
     atomReverseLookup(activeAtoms[i]) = i;
-  }
 
   if (nInactiveAtoms > 0)
   {
@@ -256,7 +243,7 @@
   mat matZXT = matActiveZ * trans(matX);
   mat matZZT = matActiveZ * trans(matActiveZ);
 
-  for (uword t = 1; !converged; ++t)
+  for (size_t t = 1; !converged; ++t)
   {
     mat A = matZZT + diagmat(dualVars);
 
@@ -330,10 +317,10 @@
     mat matDActiveEstimate = trans(solve(matZZT + diagmat(dualVars), matZXT));
     matDEstimate = zeros(nDims, nAtoms);
 
-    for (uword i = 0; i < nActiveAtoms; i++)
+    for (size_t i = 0; i < nActiveAtoms; ++i)
       matDEstimate.col(activeAtoms[i]) = matDActiveEstimate.col(i);
 
-    for (uword i = 0; i < nInactiveAtoms; i++)
+    for (size_t i = 0; i < nInactiveAtoms; ++i)
     {
       vec vecmatDi = matDEstimate.unsafe_col(inactiveAtoms[i]);
       RandomAtom(vecmatDi);
@@ -345,7 +332,7 @@
 
 void SparseCoding::ProjectDictionary()
 {
-  for (uword j = 0; j < nAtoms; j++)
+  for (size_t j = 0; j < nAtoms; j++)
   {
     double normD_j = norm(matD.col(j), 2);
     if ((normD_j > 1) && (normD_j - 1.0 > 1e-9))
@@ -389,10 +376,10 @@
                                        uvec rows_to_remove,
                                        mat& X_mod)
 {
-  uword n_cols = X.n_cols;
-  uword n_rows = X.n_rows;
-  uword n_to_remove = rows_to_remove.n_elem;
-  uword n_to_keep = n_rows - n_to_remove;
+  const size_t n_cols = X.n_cols;
+  const size_t n_rows = X.n_rows;
+  const size_t n_to_remove = rows_to_remove.n_elem;
+  const size_t n_to_keep = n_rows - n_to_remove;
 
   if (n_to_remove == 0)
   {
@@ -402,13 +389,13 @@
   {
     X_mod.set_size(n_to_keep, n_cols);
 
-    uword cur_row = 0;
-    uword remove_ind = 0;
+    size_t cur_row = 0;
+    size_t remove_ind = 0;
     // First, check 0 to first row to remove.
     if (rows_to_remove(0) > 0)
     {
       // Note that this implies that n_rows > 1.
-      uword height = rows_to_remove(0);
+      size_t height = rows_to_remove(0);
       X_mod(span(cur_row, cur_row + height - 1), span::all) =
           X(span(0, rows_to_remove(0) - 1), span::all);
       cur_row += height;
@@ -417,8 +404,8 @@
     // penultimate row.
     while (remove_ind < n_to_remove - 1)
     {
-      uword height = rows_to_remove[remove_ind + 1] - rows_to_remove[remove_ind]
-          - 1;
+      size_t height = rows_to_remove[remove_ind + 1] -
+          rows_to_remove[remove_ind] - 1;
 
       if (height > 0)
       {

Modified: mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp	2012-04-13 22:29:38 UTC (rev 12376)
+++ mlpack/trunk/src/mlpack/methods/sparse_coding/sparse_coding.hpp	2012-04-13 22:50:47 UTC (rev 12377)
@@ -80,34 +80,21 @@
  */
 class SparseCoding
 {
-
  public:
   /**
    * Set the parameters to SparseCoding. lambda2 defaults to 0.
    *
    * @param matX Data matrix
-   * @param nAtoms Number of atoms in dictionary
+   * @param atoms Number of atoms in dictionary
    * @param lambda1 Regularization parameter for l1-norm penalty
    * @param lambda2 Regularization parameter for l2-norm penalty
    */
   SparseCoding(const arma::mat& matX,
-               arma::uword nAtoms,
-               double lambda1,
-               double lambda2 = 0);
+               const size_t atoms,
+               const double lambda1,
+               const double lambda2 = 0);
 
   /**
-   * Initialize dictionary.
-   */
-  void InitDictionary();
-
-  /**
-   * Load dictionary from a file
-   *
-   * @param dictionaryFilename Filename containing dictionary
-   */
-  void LoadDictionary(const char* dictionaryFilename);
-
-  /**
    * Initialize dictionary by drawing k vectors uniformly at random from the
    * unit sphere.
    */
@@ -132,9 +119,10 @@
   /**
    * Run Sparse Coding with Dictionary Learning.
    *
-   * @param nIterations Maximum number of iterations to run algorithm.
+   * @param maxIterations Maximum number of iterations to run algorithm.  If 0,
+   *     the algorithm will run until convergence (or forever).
    */
-  void DoSparseCoding(arma::uword nIterations);
+  void DoSparseCoding(const size_t maxIterations = 0);
 
   /**
    * Sparse code each point via LARS.
@@ -148,7 +136,7 @@
    *    the coding matrix Z that are non-zero (the adjacency matrix for the
    *    bipartite graph of points and atoms).
    */
-  void OptimizeDictionary(arma::uvec adjacencies);
+  void OptimizeDictionary(const arma::uvec& adjacencies);
 
   /**
    * Project each atom of the dictionary onto the unit ball.
@@ -182,11 +170,11 @@
 
  private:
   //! Number of dimensions.
-  arma::uword nDims;
+  size_t nDims;
   //! Number of atoms.
-  arma::uword nAtoms;
+  size_t nAtoms;
   //! Number of points.
-  arma::uword nPoints;
+  size_t nPoints;
 
   //! data (columns are points).
   arma::mat matX;




More information about the mlpack-svn mailing list