[mlpack-svn] r15911 - mlpack/trunk/src/mlpack/methods/gmm

fastlab-svn at coffeetalk-1.cc.gatech.edu fastlab-svn at coffeetalk-1.cc.gatech.edu
Thu Oct 3 11:07:15 EDT 2013


Author: rcurtin
Date: Thu Oct  3 11:07:15 2013
New Revision: 15911

Log:
Add EigenvalueRatioConstraint class for EMFit.


Added:
   mlpack/trunk/src/mlpack/methods/gmm/eigenvalue_ratio_constraint.hpp
Modified:
   mlpack/trunk/src/mlpack/methods/gmm/CMakeLists.txt

Modified: mlpack/trunk/src/mlpack/methods/gmm/CMakeLists.txt
==============================================================================
--- mlpack/trunk/src/mlpack/methods/gmm/CMakeLists.txt	(original)
+++ mlpack/trunk/src/mlpack/methods/gmm/CMakeLists.txt	Thu Oct  3 11:07:15 2013
@@ -9,6 +9,7 @@
   no_constraint.hpp
   positive_definite_constraint.hpp
   diagonal_constraint.hpp
+  eigenvalue_ratio_constraint.hpp
 )
 
 # Add directory name to sources.

Added: mlpack/trunk/src/mlpack/methods/gmm/eigenvalue_ratio_constraint.hpp
==============================================================================
--- (empty file)
+++ mlpack/trunk/src/mlpack/methods/gmm/eigenvalue_ratio_constraint.hpp	Thu Oct  3 11:07:15 2013
@@ -0,0 +1,79 @@
+/**
+ * @file eigenvalue_ratio_constraint.hpp
+ * @author Ryan Curtin
+ *
+ * Constrain a covariance matrix to have a certain ratio of eigenvalues.
+ */
+#ifndef __MLPACK_METHODS_GMM_EIGENVALUE_RATIO_CONSTRAINT_HPP
+#define __MLPACK_METHODS_GMM_EIGENVALUE_RATIO_CONSTRAINT_HPP
+
+#include <mlpack/core.hpp>
+
+namespace mlpack {
+namespace gmm {
+
+/**
+ * Given a vector of eigenvalue ratios, ensure that the covariance matrix always
+ * has those eigenvalue ratios.  When you create this object, make sure that the
+ * vector of ratios that you pass does not go out of scope, because this object
+ * holds a reference to that vector instead of copying it.
+ */
+class EigenvalueRatioConstraint
+{
+ public:
+  /**
+   * Create the EigenvalueRatioConstraint object with the given vector of
+   * eigenvalue ratios.  These ratios are with respect to the first eigenvalue,
+   * which is the largest eigenvalue, so the first element of the vector should
+   * be 1.  In addition, all other elements should be less than or equal to 1.
+   */
+  EigenvalueRatioConstraint(const arma::vec& ratios) :
+    ratios(ratios)
+  {
+    // Check validity of ratios.
+    if (std::abs(ratios[0] - 1.0) > 1e-20)
+      Log::Fatal << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
+          << "first element of ratio vector is not 1.0!" << std::endl;
+
+    for (size_t i = 1; i < ratios.n_elem; ++i)
+    {
+      if (ratios[i] > 1.0)
+        Log::Fatal << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
+            << "element " << i << " of ratio vector is greater than 1.0!"
+            << std::endl;
+      if (ratios[i] < 0.0)
+        Log::Warn << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
+            << "element " << i << " of ratio vectors is negative and will "
+            << "probably cause the covariance to be non-invertible..."
+            << std::endl;
+  }
+
+  /**
+   * Apply the eigenvalue ratio constraint to the given covariance matrix.
+   */
+  void ApplyConstraint(arma::mat& covariance) const
+  {
+    // Eigendecompose the matrix.
+    arma::vec eigenvalues;
+    arma::mat eigenvectors;
+    arma::eig_sym(eigenvalues, eigenvectors, covariance);
+
+    // Change the eigenvalues to what we are forcing them to be.  There
+    // shouldn't be any negative eigenvalues anyway, so it doesn't matter if we
+    // are suddenly forcing them to be positive.  If the first eigenvalue is
+    // negative, well, there are going to be some problems later...
+    eigenvalues = (eigenvalues[0] * ratios);
+
+    // Reassemble the matrix.
+    covariance = eigenvectors * arma::diagmat(eigenvalues) * eigenvectors.t();
+  }
+
+ private:
+  //! Ratios for eigenvalues.
+  const arma::vec& ratios;
+};
+
+}; // namespace gmm
+}; // namespace mlpack
+
+#endif



More information about the mlpack-svn mailing list