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.
static util::PrefixedOutStream Warn
Definition: log.hpp:99
Linear algebra utility functions, generally performed on matrices or vectors.
The core includes that mlpack expects; standard C++ includes, Armadillo, cereal, and a few basic mlpa...
void ApplyConstraint(arma::vec &diagCovariance) const
Apply the eigenvalue ratio constraint to the given diagonal covariance matrix (represented as a vecto...
static util::PrefixedOutStream Fatal
Definition: log.hpp:105
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.