[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