eigenvalue_ratio_constraint.hpp
Go to the documentation of this file.
1 
12 #ifndef MLPACK_METHODS_GMM_EIGENVALUE_RATIO_CONSTRAINT_HPP
13 #define MLPACK_METHODS_GMM_EIGENVALUE_RATIO_CONSTRAINT_HPP
14 
15 #include <mlpack/prereqs.hpp>
16 
17 namespace mlpack {
18 namespace gmm {
19 
28 {
29  public:
36  EigenvalueRatioConstraint(const arma::vec& ratios) :
37  // Make an alias of the ratios vector. It will never be modified here.
38  ratios(const_cast<double*>(ratios.memptr()), ratios.n_elem, false)
39  {
40  // Check validity of ratios.
41  if (std::abs(ratios[0] - 1.0) > 1e-20)
42  Log::Fatal << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
43  << "first element of ratio vector is not 1.0!" << std::endl;
44 
45  for (size_t i = 1; i < ratios.n_elem; ++i)
46  {
47  if (ratios[i] > 1.0)
48  Log::Fatal << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
49  << "element " << i << " of ratio vector is greater than 1.0!"
50  << std::endl;
51  if (ratios[i] < 0.0)
52  Log::Warn << "EigenvalueRatioConstraint::EigenvalueRatioConstraint(): "
53  << "element " << i << " of ratio vectors is negative and will "
54  << "probably cause the covariance to be non-invertible..."
55  << std::endl;
56  }
57  }
58 
62  void ApplyConstraint(arma::mat& covariance) const
63  {
64  // Eigendecompose the matrix.
65  arma::vec eigenvalues;
66  arma::mat eigenvectors;
67  covariance = arma::symmatu(covariance);
68  if (!arma::eig_sym(eigenvalues, eigenvectors, covariance))
69  {
70  Log::Fatal << "applying to constraint could not be accomplished."
71  << std::endl;
72  }
73 
74  // Change the eigenvalues to what we are forcing them to be. There
75  // shouldn't be any negative eigenvalues anyway, so it doesn't matter if we
76  // are suddenly forcing them to be positive. If the first eigenvalue is
77  // negative, well, there are going to be some problems later...
78  eigenvalues = (eigenvalues[0] * ratios);
79 
80  // Reassemble the matrix.
81  covariance = eigenvectors * arma::diagmat(eigenvalues) * eigenvectors.t();
82  }
83 
88  void ApplyConstraint(arma::vec& diagCovariance) const
89  {
90  // The matrix is already eigendecomposed but we need to sort the elements.
91  arma::uvec eigvalOrder = arma::sort_index(diagCovariance);
92  arma::vec eigvals = diagCovariance(eigvalOrder);
93 
94  // Change the eigenvalues to what we are forcing them to be. There
95  // shouldn't be any negative eigenvalues anyway, so it doesn't matter if we
96  // are suddenly forcing them to be positive. If the first eigenvalue is
97  // negative, well, there are going to be some problems later...
98  eigvals = eigvals[0] * ratios;
99 
100  // Reassemble the matrix.
101  for (size_t i = 0; i < eigvalOrder.n_elem; ++i)
102  diagCovariance[eigvalOrder[i]] = eigvals[i];
103  }
104 
106  template<typename Archive>
107  void serialize(Archive& ar, const uint32_t /* version */)
108  {
109  // Strip the const for the sake of loading/saving. This is the only time it
110  // is modified (other than the constructor).
111  ar(CEREAL_NVP(const_cast<arma::vec&>(ratios)));
112  }
113 
114  private:
116  const arma::vec ratios;
117 };
118 
119 } // namespace gmm
120 } // namespace mlpack
121 
122 #endif
EigenvalueRatioConstraint(const arma::vec &ratios)
Create the EigenvalueRatioConstraint object with the given vector of eigenvalue ratios.
Linear algebra utility functions, generally performed on matrices or vectors.
The core includes that mlpack expects; standard C++ includes and Armadillo.
static MLPACK_EXPORT util::PrefixedOutStream Fatal
Prints fatal messages prefixed with [FATAL], then terminates the program.
Definition: log.hpp:90
void ApplyConstraint(arma::vec &diagCovariance) const
Apply the eigenvalue ratio constraint to the given diagonal covariance matrix (represented as a vecto...
static MLPACK_EXPORT util::PrefixedOutStream Warn
Prints warning messages prefixed with [WARN ].
Definition: log.hpp:87
Given a vector of eigenvalue ratios, ensure that the covariance matrix always has those eigenvalue ra...
void serialize(Archive &ar, const uint32_t)
Serialize the constraint.
void ApplyConstraint(arma::mat &covariance) const
Apply the eigenvalue ratio constraint to the given covariance matrix.