[mlpack-svn] r10814 - mlpack/trunk/src/mlpack/methods/radical

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Wed Dec 14 18:12:08 EST 2011


Author: rcurtin
Date: 2011-12-14 18:12:08 -0500 (Wed, 14 Dec 2011)
New Revision: 10814

Modified:
   mlpack/trunk/src/mlpack/methods/radical/radical.cpp
   mlpack/trunk/src/mlpack/methods/radical/radical.hpp
   mlpack/trunk/src/mlpack/methods/radical/radical_main.cpp
Log:
Change formatting of RADICAL code and redo the documentation a little bit to
make it more consistent with other programs.


Modified: mlpack/trunk/src/mlpack/methods/radical/radical.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/radical/radical.cpp	2011-12-14 22:59:30 UTC (rev 10813)
+++ mlpack/trunk/src/mlpack/methods/radical/radical.cpp	2011-12-14 23:12:08 UTC (rev 10814)
@@ -14,8 +14,8 @@
 namespace radical {
 
 
-Radical::Radical(double noiseStdDev, size_t nReplicates, size_t nAngles, 
-		 size_t nSweeps) :
+Radical::Radical(double noiseStdDev, size_t nReplicates, size_t nAngles,
+     size_t nSweeps) :
   noiseStdDev(noiseStdDev),
   nReplicates(nReplicates),
   nAngles(nAngles),
@@ -26,7 +26,7 @@
 }
 
 Radical::Radical(double noiseStdDev, size_t nReplicates, size_t nAngles, size_t nSweeps,
-		 size_t m) :
+     size_t m) :
   noiseStdDev(noiseStdDev),
   nReplicates(nReplicates),
   nAngles(nAngles),
@@ -35,8 +35,8 @@
 {
   // nothing to do here
 }
-  
 
+
 void Radical::CopyAndPerturb(mat& matXNew, const mat& matX) {
   matXNew = repmat(matX, nReplicates, 1) + noiseStdDev * randn(nReplicates * matX.n_rows, matX.n_cols);
 }
@@ -44,7 +44,7 @@
 
 double Radical::Vasicek(vec& z) {
   z = sort(z);
-  
+
   // Apparently slower
   /*
   vec logs = log(z.subvec(m, nPoints - 1) - z.subvec(0, nPoints - 1 - m));
@@ -66,13 +66,13 @@
   mat matXMod;
 
   CopyAndPerturb(matXMod, matX);
-  
+
   mat matJacobi(2,2);
   mat candidateY;
 
   vec thetas = linspace<vec>(0, nAngles - 1, nAngles) / ((double) nAngles) * math::pi() / 2;
   vec values(nAngles);
-  
+
   for(size_t i = 0; i < nAngles; i++) {
     double cosTheta = cos(thetas(i));
     double sinTheta = sin(thetas(i));
@@ -80,14 +80,14 @@
     matJacobi(1,0) = -sinTheta;
     matJacobi(0,1) = sinTheta;
     matJacobi(1,1) = cosTheta;
-    
+
     candidateY = matXMod * matJacobi;
     vec candidateY1 = candidateY.unsafe_col(0);
     vec candidateY2 = candidateY.unsafe_col(1);
-    
+
     values(i) = Vasicek(candidateY1) + Vasicek(candidateY2);
   }
-  
+
   u32 indOpt;
   values.min(indOpt); // we ignore the return value; we don't care about it
   return thetas(indOpt);
@@ -95,36 +95,36 @@
 
 
 void Radical::DoRadical(const mat& matXT, mat& matY, mat& matW) {
-  
-  // matX is nPoints by nDims (although less intuitive than columns being 
+
+  // matX is nPoints by nDims (although less intuitive than columns being
   // points, and although this is the transpose of the ICA literature, this
-  // choice is for computational efficiency when repeatedly generating 
+  // choice is for computational efficiency when repeatedly generating
   // two-dimensional coordinate projections for Radical2D
   mat matX = trans(matXT);
-  
-  
-  // if m was not specified, initialize m as recommended in 
+
+
+  // if m was not specified, initialize m as recommended in
   // (Learned-Miller and Fisher, 2003)
   if(m < 1) {
     m = floor(sqrt(matX.n_rows));
   }
-  
+
   const size_t nDims = matX.n_cols;
   const size_t nPoints = matX.n_rows;
-  
+
   mat matXWhitened;
   mat matWhitening;
   WhitenFeatureMajorMatrix(matX, matY, matWhitening);
   // matY is now the whitened form of matX
-    
+
   // in the RADICAL code, they do not copy and perturb initially, although the
   // paper does. we follow the code as it should match their reported results
   // and likely does a better job bouncing out of local optima
   //GeneratePerturbedX(X, X);
-  
+
   // initialize the unmixing matrix to the whitening matrix
   matW = matWhitening;
-  
+
   mat matYSubspace(nPoints, 2);
 
   mat matEye = eye(nDims, nDims);
@@ -132,24 +132,24 @@
   for(size_t sweepNum = 0; sweepNum < nSweeps; sweepNum++) {
     for(size_t i = 0; i < nDims - 1; i++) {
       for(size_t j = i + 1; j < nDims; j++) {
-	matYSubspace.col(0) = matY.col(i);
-	matYSubspace.col(1) = matY.col(j);
-	double thetaOpt = DoRadical2D(matYSubspace);
-	mat matJ = matEye;
-	double cosThetaOpt = cos(thetaOpt);
-	double sinThetaOpt = sin(thetaOpt);
-	matJ(i,i) = cosThetaOpt;
-	matJ(j,i) = -sinThetaOpt;
-	matJ(i,j) = sinThetaOpt;
-	matJ(j,j) = cosThetaOpt;
-	matW = matW * matJ;
-	matY = matX * matW; // to avoid any issues of mismatch between matW
-	                    // and matY, do not use matY = matY * matJ,
-	                    // even though it may be much more efficient
+  matYSubspace.col(0) = matY.col(i);
+  matYSubspace.col(1) = matY.col(j);
+  double thetaOpt = DoRadical2D(matYSubspace);
+  mat matJ = matEye;
+  double cosThetaOpt = cos(thetaOpt);
+  double sinThetaOpt = sin(thetaOpt);
+  matJ(i,i) = cosThetaOpt;
+  matJ(j,i) = -sinThetaOpt;
+  matJ(i,j) = sinThetaOpt;
+  matJ(j,j) = cosThetaOpt;
+  matW = matW * matJ;
+  matY = matX * matW; // to avoid any issues of mismatch between matW
+                      // and matY, do not use matY = matY * matJ,
+                      // even though it may be much more efficient
       }
     }
   }
-  
+
   // the final transposes provide W and Y in the typical form from the ICA literature
   //matW = trans(matWhitening * matW);
   //matY = trans(matY);
@@ -159,8 +159,8 @@
 
 
 void WhitenFeatureMajorMatrix(const mat& matX,
-			      mat& matXWhitened,
-			      mat& matWhitening) {
+            mat& matXWhitened,
+            mat& matWhitening) {
   mat matU, matV;
   vec s;
   svd(matU, s, matV, cov(matX));

Modified: mlpack/trunk/src/mlpack/methods/radical/radical.hpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/radical/radical.hpp	2011-12-14 22:59:30 UTC (rev 10813)
+++ mlpack/trunk/src/mlpack/methods/radical/radical.hpp	2011-12-14 23:12:08 UTC (rev 10814)
@@ -3,7 +3,7 @@
  * @author Nishant Mehta
  *
  * Declaration of Radical class (RADICAL is Robust, Accurate, Direct ICA aLgorithm)
- * Note: upper case variables correspond to matrices. do not convert them to 
+ * Note: upper case variables correspond to matrices. do not convert them to
  *   camelCase because that would make them appear to be vectors (which is bad!)
  */
 
@@ -36,15 +36,13 @@
  * }
  */
 class Radical {
-
-public:
-  
+ public:
   /**
-   * Set the parameters to RADICAL
+   * Set the parameters to RADICAL.
    *
    * @param noiseStdDev Standard deviation of the Gaussian noise added to the
    *    replicates of the data points during Radical2D
-   * @param nReplicates Number of Gaussian-perturbed replicates to use 
+   * @param nReplicates Number of Gaussian-perturbed replicates to use
    *    (per point) in Radical2D
    * @param nAngles Number of angles to consider in brute-force search during
    *    Radical2D
@@ -52,14 +50,14 @@
    *    Each sweep calls Radical2D once for each pair of dimensions
    */
   Radical(double noiseStdDev, size_t nReplicates, size_t nAngles,
-	  size_t nSweeps);
+      size_t nSweeps);
 
   /**
-   * Set the parameters to RADICAL
+   * Set the parameters to RADICAL.
    *
    * @param noiseStdDev Standard deviation of the Gaussian noise added to the
    *    replicates of the data points during Radical2D
-   * @param nReplicates Number of Gaussian-perturbed replicates to use 
+   * @param nReplicates Number of Gaussian-perturbed replicates to use
    *    (per point) in Radical2D
    * @param nAngles Number of angles to consider in brute-force search during
    *    Radical2D
@@ -68,73 +66,70 @@
    * @param m The variable m from Vasicek's m-spacing estimator of entropy
    */
   Radical(double noiseStdDev, size_t nReplicates, size_t nAngles,
-	  size_t nSweeps, size_t m);
-  
+      size_t nSweeps, size_t m);
 
   /**
+   * Run RADICAL.
+   *
+   * @param matX Input data into the algorithm - a matrix where each column is
+   *    a point and each row is a dimension
+   * @param matY Estimated independent components - a matrix where each column
+   *    is a point and each row is an estimated independent component
+   * @param matW Estimated unmixing matrix, where matY = matW * matX
+   */
+  void DoRadical(const arma::mat& matX, arma::mat& matY, arma::mat& matW);
+
+  /**
    * Vasicek's m-spacing estimator of entropy, with overlap modification from
    *    (Learned-Miller and Fisher, 2003)
-   * 
+   *
    * @param x Empirical sample (one-dimensional) over which to estimate entropy
    *
    */
   double Vasicek(arma::vec& x);
-  
-  /** Make nReplicates copies of each data point and perturb data with Gaussian
-   *     noise with standard deviation noiseStdDev
+
+  /**
+   * Make nReplicates copies of each data point and perturb data with Gaussian
+   * noise with standard deviation noiseStdDev.
    */
   void CopyAndPerturb(arma::mat& matXNew, const arma::mat& matX);
-  
-  /** Two-dimensional version of RADICAL */
+
+  //! Two-dimensional version of RADICAL.
   double DoRadical2D(const arma::mat& matX);
-  
-  /** Run RADICAL
-   *
-   * @param matX Input data into the algorithm - a matrix where each column is
-   *    a point and each row is a dimension
-   * @param matY Estimated independent components - a matrix where each column
-   *    is a point and each row is an estimated independent component
-   * @param matW Estimated unmixing matrix, where matY = matW * matX
-   */
-  void DoRadical(const arma::mat& matX, arma::mat& matY, arma::mat& matW);
-  
-  
-private:
 
+ private:
   /**
    * standard deviation of the Gaussian noise added to the replicates of
    * the data points during Radical2D
    */
   double noiseStdDev;
-  
+
   /**
    * Number of Gaussian-perturbed replicates to use (per point) in Radical2D
    */
   size_t nReplicates;
-  
+
   /**
    * Number of angles to consider in brute-force search during Radical2D
    */
   size_t nAngles;
-  
+
   /**
    * Number of sweeps
    *  - Each sweep calls Radical2D once for each pair of dimensions
    */
   size_t nSweeps;
-  
+
   /**
    * m to use for Vasicek's m-spacing estimator of entropy
    */
   size_t m;
-  
+
 };
 
-
-
 void WhitenFeatureMajorMatrix(const arma::mat& matX,
-			      arma::mat& matXWhitened,
-			      arma::mat& matWhitening);
+                              arma::mat& matXWhitened,
+                              arma::mat& matWhitening);
 
 }; // namespace radical
 }; // namespace mlpack

Modified: mlpack/trunk/src/mlpack/methods/radical/radical_main.cpp
===================================================================
--- mlpack/trunk/src/mlpack/methods/radical/radical_main.cpp	2011-12-14 22:59:30 UTC (rev 10813)
+++ mlpack/trunk/src/mlpack/methods/radical/radical_main.cpp	2011-12-14 23:12:08 UTC (rev 10814)
@@ -2,81 +2,92 @@
  * @file radical_main.cpp
  * @author Nishant Mehta
  *
- * Executable for RADICAL
+ * Executable for RADICAL.
  */
 
 #include <mlpack/core.hpp>
 #include <armadillo>
 #include "radical.hpp"
 
-using namespace std;
-using namespace arma;
+PROGRAM_INFO("RADICAL", "An implementation of RADICAL, a method for independent"
+    "component analysis (ICA).  Assuming that we have an input matrix X, the"
+    "goal is to find a square unmixing matrix W such that Y = W * X and the "
+    "dimensions of Y are independent components.\n"
+    "\n"
+    "For more details, see the following paper:\n"
+    "\n"
+    "@article{\n"
+    "  title = {ICA Using Spacings Estimates of Entropy},\n"
+    "  author = {Learned-Miller, E.G. and Fisher III, J.W.},\n"
+    "  journal = {Journal of Machine Learning Research},\n"
+    "  volume = {4},\n"
+    "  pages = {1271--1295},\n"
+    "  year = {2003}\n"
+    "}");
 
-PROGRAM_INFO("RADICAL", "An implementation of RADICAL, a method for independent "
-	     "component analysis (ICA)");
+PARAM_STRING_REQ("input_file", "Input dataset filename for ICA.", "");
 
-PARAM_STRING_REQ("X", "Input dataset filename for ICA", "");
-PARAM_STRING_REQ("Y", "Independent components filename", "");
-PARAM_STRING_REQ("W", "Unmixing matrix filename", "");
+PARAM_STRING("output_ic", "File to save independent components to.", "o",
+    "output_ic.csv");
+PARAM_STRING("output_unmixing", "File to save unmixing matrix to.", "u",
+    "output_unmixing.csv");
 
 PARAM_DOUBLE("noise_std_dev", "Standard deviation of Gaussian noise", "",
-	     0.175);
-PARAM_INT("n_replicates", "Number of Gaussian-perturbed replicates to use "
-	  "(per point) in Radical2D", "",
-	  30);
-PARAM_INT("n_angles", "Number of angles to consider in brute-force search "
-	  "during Radical2D", "",
-	  150);
-PARAM_INT("n_sweeps", "Number of sweeps (each sweep calls Radical2D once for "
-	  "each pair of dimensions", "",
-	  0);
+    0.175);
+PARAM_INT("replicates", "Number of Gaussian-perturbed replicates to use "
+    "(per point) in Radical2D.", "", 30);
+PARAM_INT("angles", "Number of angles to consider in brute-force search "
+    "during Radical2D.", "", 150);
+PARAM_INT("sweeps", "Number of sweeps (each sweep calls Radical2D once for "
+    "each pair of dimensions", "", 0);
 
+using namespace mlpack;
+using namespace mlpack::radical;
+using namespace std;
+using namespace arma;
 
 int main(int argc, char* argv[]) {
+  // Handle parameters.
+  CLI::ParseCommandLine(argc, argv);
 
-  // Handle parameters
-  CLI::ParseCommandLine(argc, argv);
-  
-  // load the data
-  const std::string matXFilename = CLI::GetParam<std::string>("X");
+  // Load the data.
+  const string matXFilename = CLI::GetParam<string>("input_file");
   mat matX;
   data::Load(matXFilename, matX);
-  
-  
-  // load parameters
+
+  // Load parameters.
   double noiseStdDev = CLI::GetParam<double>("noise_std_dev");
-  u32 nReplicates = CLI::GetParam<int>("n_replicates");
-  u32 nAngles = CLI::GetParam<int>("n_angles");
-  u32 nSweeps = CLI::GetParam<int>("n_sweeps");
-  if(nSweeps == 0) {
+  size_t nReplicates = CLI::GetParam<int>("replicates");
+  size_t nAngles = CLI::GetParam<int>("angles");
+  size_t nSweeps = CLI::GetParam<int>("sweeps");
+
+  if(nSweeps == 0)
+  {
     nSweeps = matX.n_rows - 1;
   }
-  
-  // run RADICAL
-  mlpack::radical::Radical rad(noiseStdDev, nReplicates, nAngles, nSweeps);
+
+  // Run RADICAL.
+  Radical rad(noiseStdDev, nReplicates, nAngles, nSweeps);
   mat matY;
   mat matW;
   rad.DoRadical(matX, matY, matW);
-  
+
   // save results
-  const std::string matYFilename = CLI::GetParam<std::string>("Y");
+  const string matYFilename = CLI::GetParam<string>("output_ic");
   data::Save(matYFilename, matY);
-  
-  const std::string matWFilename = CLI::GetParam<std::string>("W");
+
+  const string matWFilename = CLI::GetParam<string>("output_unmixing");
   data::Save(matWFilename, matW);
-  
-  
+
   /*
-  // compute and print objective  
+  // compute and print objective
   mat matYT = trans(matY);
   double valEst = 0;
-  for(u32 i = 0; i < matYT.n_cols; i++) {
+  for(size_t i = 0; i < matYT.n_cols; i++)
+  {
     vec Yi = vec(matYT.col(i));
     valEst += rad.Vasicek(Yi);
   }
-  printf("objective(estimate) = %f\n", valEst);
+  Log::Info << "Objective (estimate): " << valEst << "." << endl;
   */
-  
-  
-  
 }




More information about the mlpack-svn mailing list