[mlpack-svn] r13155 - mlpack/trunk/src/mlpack/core/math

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Wed Jul 4 13:18:26 EDT 2012


Author: rcurtin
Date: 2012-07-04 13:18:26 -0400 (Wed, 04 Jul 2012)
New Revision: 13155

Added:
   mlpack/trunk/src/mlpack/core/math/lin_alg.cpp
Modified:
   mlpack/trunk/src/mlpack/core/math/CMakeLists.txt
   mlpack/trunk/src/mlpack/core/math/lin_alg.hpp
Log:
Move RemoveRows() to the linear algebra utility section since it's used in more
than one place.


Modified: mlpack/trunk/src/mlpack/core/math/CMakeLists.txt
===================================================================
--- mlpack/trunk/src/mlpack/core/math/CMakeLists.txt	2012-07-04 16:07:48 UTC (rev 13154)
+++ mlpack/trunk/src/mlpack/core/math/CMakeLists.txt	2012-07-04 17:18:26 UTC (rev 13155)
@@ -5,6 +5,7 @@
 set(SOURCES
   clamp.hpp
   lin_alg.hpp
+  lin_alg.cpp
   random.hpp
   random.cpp
   range.hpp

Copied: mlpack/trunk/src/mlpack/core/math/lin_alg.cpp (from rev 13083, mlpack/trunk/src/mlpack/core/math/lin_alg.hpp)
===================================================================
--- mlpack/trunk/src/mlpack/core/math/lin_alg.cpp	                        (rev 0)
+++ mlpack/trunk/src/mlpack/core/math/lin_alg.cpp	2012-07-04 17:18:26 UTC (rev 13155)
@@ -0,0 +1,216 @@
+/**
+ * @file lin_alg.cpp
+ * @author Nishant Mehta
+ *
+ * Linear algebra utilities.
+ */
+#include "lin_alg.hpp"
+
+#define max_rand_i 100000
+
+using namespace mlpack;
+using namespace math;
+
+/**
+ * Auxiliary function to raise vector elements to a specific power.  The sign
+ * is ignored in the power operation and then re-added.  Useful for
+ * eigenvalues.
+ */
+void mlpack::math::VectorPower(arma::vec& vec, double power)
+{
+  for (size_t i = 0; i < vec.n_elem; i++)
+  {
+    if (std::abs(vec(i)) > 1e-12)
+      vec(i) = (vec(i) > 0) ? std::pow(vec(i), (double) power) :
+          -std::pow(-vec(i), (double) power);
+    else
+      vec(i) = 0;
+  }
+}
+
+/**
+ * Creates a centered matrix, where centering is done by subtracting
+ * the sum over the columns (a column vector) from each column of the matrix.
+ *
+ * @param x Input matrix
+ * @param xCentered Matrix to write centered output into
+ */
+void mlpack::math::Center(const arma::mat& x, arma::mat& xCentered)
+{
+  // Sum matrix along dimension 0 (that is, sum elements in each row).
+  arma::vec rowVectorSum = arma::sum(x, 1);
+  rowVectorSum /= x.n_cols; // scale
+
+  xCentered.set_size(x.n_rows, x.n_cols);
+  for (size_t i = 0; i < x.n_rows; i++)
+    xCentered.row(i) = x.row(i) - rowVectorSum(i);
+}
+
+/**
+ * Whitens a matrix using the singular value decomposition of the covariance
+ * matrix. Whitening means the covariance matrix of the result is the identity
+ * matrix.
+ */
+void mlpack::math::WhitenUsingSVD(const arma::mat& x,
+                                  arma::mat& xWhitened,
+                                  arma::mat& whiteningMatrix)
+{
+  arma::mat covX, u, v, invSMatrix, temp1;
+  arma::vec sVector;
+
+  covX = ccov(x);
+
+  svd(u, sVector, v, covX);
+
+  size_t d = sVector.n_elem;
+  invSMatrix.zeros(d, d);
+  invSMatrix.diag() = 1 / sqrt(sVector);
+
+  whiteningMatrix = v * invSMatrix * trans(u);
+
+  xWhitened = whiteningMatrix * x;
+}
+
+/**
+ * Whitens a matrix using the eigendecomposition of the covariance matrix.
+ * Whitening means the covariance matrix of the result is the identity matrix.
+ */
+void mlpack::math::WhitenUsingEig(const arma::mat& x,
+                                  arma::mat& xWhitened,
+                                  arma::mat& whiteningMatrix)
+{
+  arma::mat diag, eigenvectors;
+  arma::vec eigenvalues;
+
+  // Get eigenvectors of covariance of input matrix.
+  eig_sym(eigenvalues, eigenvectors, ccov(x));
+
+  // Generate diagonal matrix using 1 / sqrt(eigenvalues) for each value.
+  VectorPower(eigenvalues, -0.5);
+  diag.zeros(eigenvalues.n_elem, eigenvalues.n_elem);
+  diag.diag() = eigenvalues;
+
+  // Our whitening matrix is diag(1 / sqrt(eigenvectors)) * eigenvalues.
+  whiteningMatrix = diag * trans(eigenvectors);
+
+  // Now apply the whitening matrix.
+  xWhitened = whiteningMatrix * x;
+}
+
+/**
+ * Overwrites a dimension-N vector to a random vector on the unit sphere in R^N.
+ */
+void mlpack::math::RandVector(arma::vec& v)
+{
+  v.zeros();
+
+  for (size_t i = 0; i + 1 < v.n_elem; i += 2)
+  {
+    double a = Random();
+    double b = Random();
+    double first_term = sqrt(-2 * log(a));
+    double second_term = 2 * M_PI * b;
+    v[i]     = first_term * cos(second_term);
+    v[i + 1] = first_term * sin(second_term);
+  }
+
+  if ((v.n_elem % 2) == 1)
+  {
+    v[v.n_elem - 1] = sqrt(-2 * log(math::Random())) * cos(2 * M_PI *
+        math::Random());
+  }
+
+  v /= sqrt(dot(v, v));
+}
+
+/**
+ * Orthogonalize x and return the result in W, using eigendecomposition.
+ * We will be using the formula \f$ W = x (x^T x)^{-0.5} \f$.
+ */
+void mlpack::math::Orthogonalize(const arma::mat& x, arma::mat& W)
+{
+  // For a matrix A, A^N = V * D^N * V', where VDV' is the
+  // eigendecomposition of the matrix A.
+  arma::mat eigenvalues, eigenvectors;
+  arma::vec egval;
+  eig_sym(egval, eigenvectors, ccov(x));
+  VectorPower(egval, -0.5);
+
+  eigenvalues.zeros(egval.n_elem, egval.n_elem);
+  eigenvalues.diag() = egval;
+
+  arma::mat at = (eigenvectors * eigenvalues * trans(eigenvectors));
+
+  W = at * x;
+}
+
+/**
+ * Orthogonalize x in-place.  This could be sped up by a custom
+ * implementation.
+ */
+void mlpack::math::Orthogonalize(arma::mat& x)
+{
+  Orthogonalize(x, x);
+}
+
+/**
+ * Remove a certain set of rows in a matrix while copying to a second matrix.
+ *
+ * @param input Input matrix to copy.
+ * @param rowsToRemove Vector containing indices of rows to be removed.
+ * @param output Matrix to copy non-removed rows into.
+ */
+void mlpack::math::RemoveRows(const arma::mat& input,
+                              const std::vector<size_t>& rowsToRemove,
+                              arma::mat& output)
+{
+  const size_t nRemove = rowsToRemove.size();
+  const size_t nKeep = input.n_rows - nRemove;
+
+  if (nRemove == 0)
+  {
+    output = input; // Copy everything.
+  }
+  else
+  {
+    output.set_size(nKeep, input.n_cols);
+
+    size_t curRow = 0;
+    size_t removeInd = 0;
+    // First, check 0 to first row to remove.
+    if (rowsToRemove[0] > 0)
+    {
+      // Note that this implies that n_rows > 1.
+      size_t height = rowsToRemove[0];
+      output(arma::span(curRow, curRow + height - 1), arma::span::all) =
+          input(arma::span(0, rowsToRemove[0] - 1), arma::span::all);
+      curRow += height;
+    }
+
+    // Now, check i'th row to remove to (i + 1)'th row to remove, until i is the
+    // penultimate row.
+    while (removeInd < nRemove - 1)
+    {
+      size_t height = rowsToRemove[removeInd + 1] - rowsToRemove[removeInd] - 1;
+
+      if (height > 0)
+      {
+        output(arma::span(curRow, curRow + height - 1), arma::span::all) =
+            input(arma::span(rowsToRemove[removeInd] + 1,
+            rowsToRemove[removeInd + 1] - 1), arma::span::all);
+        curRow += height;
+      }
+
+      removeInd++;
+    }
+
+    // Now that i is the last row to remove, check last row to remove to last
+    // row.
+    if (rowsToRemove[removeInd] < input.n_rows - 1)
+    {
+      output(arma::span(curRow, nKeep - 1), arma::span::all) =
+          input(arma::span(rowsToRemove[removeInd] + 1, input.n_rows - 1),
+          arma::span::all);
+    }
+  }
+}

Modified: mlpack/trunk/src/mlpack/core/math/lin_alg.hpp
===================================================================
--- mlpack/trunk/src/mlpack/core/math/lin_alg.hpp	2012-07-04 16:07:48 UTC (rev 13154)
+++ mlpack/trunk/src/mlpack/core/math/lin_alg.hpp	2012-07-04 17:18:26 UTC (rev 13155)
@@ -4,24 +4,13 @@
  *
  * Linear algebra utilities.
  */
-
 #ifndef __MLPACK_CORE_MATH_LIN_ALG_HPP
 #define __MLPACK_CORE_MATH_LIN_ALG_HPP
 
 #include <mlpack/core.hpp>
 
-#define max_rand_i 100000
-
 /**
- * Linear algebra utilities.
- *
- * This includes, among other things, Map, Sum, Addition, Subtraction,
- * Multiplication, Hadamard product (entry-wise multiplication), Whitening,
- * Random vectors on the unit sphere, Random uniform matrices, Random
- * normal matrices, creating a Submatrix that is a slice of selected columns of
- * a matrix, Block matrix construction from a base matrix
- * Note that the __private is temporary until this code is merged into a larger
- * namespace of linear algebra utilities
+ * Linear algebra utility functions, generally performed on matrices or vectors.
  */
 namespace mlpack {
 namespace math {
@@ -31,17 +20,7 @@
  * is ignored in the power operation and then re-added.  Useful for
  * eigenvalues.
  */
-void VectorPower(arma::vec& vec, double power)
-{
-  for (size_t i = 0; i < vec.n_elem; i++)
-  {
-    if (std::abs(vec(i)) > 1e-12)
-      vec(i) = (vec(i) > 0) ? std::pow(vec(i), (double) power) :
-          -std::pow(-vec(i), (double) power);
-    else
-      vec(i) = 0;
-  }
-}
+void VectorPower(arma::vec& vec, double power);
 
 /**
  * Creates a centered matrix, where centering is done by subtracting
@@ -50,126 +29,54 @@
  * @param x Input matrix
  * @param xCentered Matrix to write centered output into
  */
-void Center(const arma::mat& x, arma::mat& xCentered)
-{
-  // Sum matrix along dimension 0 (that is, sum elements in each row).
-  arma::vec rowVectorSum = arma::sum(x, 1);
-  rowVectorSum /= x.n_cols; // scale
+void Center(const arma::mat& x, arma::mat& xCentered);
 
-  xCentered.set_size(x.n_rows, x.n_cols);
-  for (size_t i = 0; i < x.n_rows; i++)
-    xCentered.row(i) = x.row(i) - rowVectorSum(i);
-}
-
 /**
  * Whitens a matrix using the singular value decomposition of the covariance
- * matrix. Whitening means the covariance matrix of the result is
- * the identity matrix
+ * matrix. Whitening means the covariance matrix of the result is the identity
+ * matrix.
  */
 void WhitenUsingSVD(const arma::mat& x,
                     arma::mat& xWhitened,
-                    arma::mat& whiteningMatrix)
-{
-  arma::mat covX, u, v, invSMatrix, temp1;
-  arma::vec sVector;
+                    arma::mat& whiteningMatrix);
 
-  covX = ccov(x);
-
-  svd(u, sVector, v, covX);
-
-  size_t d = sVector.n_elem;
-  invSMatrix.zeros(d, d);
-  invSMatrix.diag() = 1 / sqrt(sVector);
-
-  whiteningMatrix = v * invSMatrix * trans(u);
-
-  xWhitened = whiteningMatrix * x;
-}
-
 /**
- * Whitens a matrix using the eigendecomposition of the covariance
- * matrix. Whitening means the covariance matrix of the result is
- * the identity matrix
+ * Whitens a matrix using the eigendecomposition of the covariance matrix.
+ * Whitening means the covariance matrix of the result is the identity matrix.
  */
 void WhitenUsingEig(const arma::mat& x,
                     arma::mat& xWhitened,
-                    arma::mat& whiteningMatrix)
-{
-  arma::mat diag, eigenvectors;
-  arma::vec eigenvalues;
+                    arma::mat& whiteningMatrix);
 
-  // Get eigenvectors of covariance of input matrix.
-  eig_sym(eigenvalues, eigenvectors, ccov(x));
-
-  // Generate diagonal matrix using 1 / sqrt(eigenvalues) for each value.
-  VectorPower(eigenvalues, -0.5);
-  diag.zeros(eigenvalues.n_elem, eigenvalues.n_elem);
-  diag.diag() = eigenvalues;
-
-  // Our whitening matrix is diag(1 / sqrt(eigenvectors)) * eigenvalues.
-  whiteningMatrix = diag * trans(eigenvectors);
-
-  // Now apply the whitening matrix.
-  xWhitened = whiteningMatrix * x;
-}
-
 /**
- * Overwrites a dimension-N vector to a random vector on the unit sphere in R^N
+ * Overwrites a dimension-N vector to a random vector on the unit sphere in R^N.
  */
-void RandVector(arma::vec &v)
-{
-  v.zeros();
+void RandVector(arma::vec& v);
 
-  for (size_t i = 0; i + 1 < v.n_elem; i += 2)
-  {
-    double a = Random();
-    double b = Random();
-    double first_term = sqrt(-2 * log(a));
-    double second_term = 2 * M_PI * b;
-    v[i]     = first_term * cos(second_term);
-    v[i + 1] = first_term * sin(second_term);
-  }
-
-  if ((v.n_elem % 2) == 1)
-  {
-    v[v.n_elem - 1] = sqrt(-2 * log(math::Random())) * cos(2 * M_PI *
-        math::Random());
-  }
-
-  v /= sqrt(dot(v, v));
-}
-
 /**
  * Orthogonalize x and return the result in W, using eigendecomposition.
  * We will be using the formula \f$ W = x (x^T x)^{-0.5} \f$.
  */
-void Orthogonalize(const arma::mat& x, arma::mat& W)
-{
-  // For a matrix A, A^N = V * D^N * V', where VDV' is the
-  // eigendecomposition of the matrix A.
-  arma::mat eigenvalues, eigenvectors;
-  arma::vec egval;
-  eig_sym(egval, eigenvectors, ccov(x));
-  VectorPower(egval, -0.5);
+void Orthogonalize(const arma::mat& x, arma::mat& W);
 
-  eigenvalues.zeros(egval.n_elem, egval.n_elem);
-  eigenvalues.diag() = egval;
-
-  arma::mat at = (eigenvectors * eigenvalues * trans(eigenvectors));
-
-  W = at * x;
-}
-
 /**
  * Orthogonalize x in-place.  This could be sped up by a custom
  * implementation.
  */
-void Orthogonalize(arma::mat& x)
-{
-  Orthogonalize(x, x);
-}
+void Orthogonalize(arma::mat& x);
 
+/**
+ * Remove a certain set of rows in a matrix while copying to a second matrix.
+ *
+ * @param input Input matrix to copy.
+ * @param rowsToRemove Vector containing indices of rows to be removed.
+ * @param output Matrix to copy non-removed rows into.
+ */
+void RemoveRows(const arma::mat& input,
+                const std::vector<size_t>& rowsToRemove,
+                arma::mat& output);
+
 }; // namespace math
 }; // namespace mlpack
 
-#endif // __MLPACK_METHODS_FASTICA_LIN_ALG_HPP
+#endif // __MLPACK_CORE_MATH_LIN_ALG_HPP




More information about the mlpack-svn mailing list