MLPACK  1.0.8
eigenvalue_ratio_constraint.hpp
Go to the documentation of this file.
1 
22 #ifndef __MLPACK_METHODS_GMM_EIGENVALUE_RATIO_CONSTRAINT_HPP
23 #define __MLPACK_METHODS_GMM_EIGENVALUE_RATIO_CONSTRAINT_HPP
24 
25 #include <mlpack/core.hpp>
26 
27 namespace mlpack {
28 namespace gmm {
29 
37 {
38  public:
45  EigenvalueRatioConstraint(const arma::vec& ratios) :
46  ratios(ratios)
47  {
48  // Check validity of ratios.
49  if (std::abs(ratios[0] - 1.0) > 1e-20)
50  Log::Fatal << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
51  << "first element of ratio vector is not 1.0!" << std::endl;
52 
53  for (size_t i = 1; i < ratios.n_elem; ++i)
54  {
55  if (ratios[i] > 1.0)
56  Log::Fatal << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
57  << "element " << i << " of ratio vector is greater than 1.0!"
58  << std::endl;
59  if (ratios[i] < 0.0)
60  Log::Warn << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
61  << "element " << i << " of ratio vectors is negative and will "
62  << "probably cause the covariance to be non-invertible..."
63  << std::endl;
64  }
65  }
66 
70  void ApplyConstraint(arma::mat& covariance) const
71  {
72  // Eigendecompose the matrix.
73  arma::vec eigenvalues;
74  arma::mat eigenvectors;
75  arma::eig_sym(eigenvalues, eigenvectors, covariance);
76 
77  // Change the eigenvalues to what we are forcing them to be. There
78  // shouldn't be any negative eigenvalues anyway, so it doesn't matter if we
79  // are suddenly forcing them to be positive. If the first eigenvalue is
80  // negative, well, there are going to be some problems later...
81  eigenvalues = (eigenvalues[0] * ratios);
82 
83  // Reassemble the matrix.
84  covariance = eigenvectors * arma::diagmat(eigenvalues) * eigenvectors.t();
85  }
86 
87  private:
89  const arma::vec& ratios;
90 };
91 
92 }; // namespace gmm
93 }; // namespace mlpack
94 
95 #endif