LSSTApplications  20.0.0
LSSTDataManagementBasePackage
Mixture.h
Go to the documentation of this file.
1 // -*- lsst-c++ -*-
2 /*
3  * LSST Data Management System
4  * Copyright 2008-2013 LSST Corporation.
5  *
6  * This product includes software developed by the
7  * LSST Project (http://www.lsst.org/).
8  *
9  * This program is free software: you can redistribute it and/or modify
10  * it under the terms of the GNU General Public License as published by
11  * the Free Software Foundation, either version 3 of the License, or
12  * (at your option) any later version.
13  *
14  * This program is distributed in the hope that it will be useful,
15  * but WITHOUT ANY WARRANTY; without even the implied warranty of
16  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17  * GNU General Public License for more details.
18  *
19  * You should have received a copy of the LSST License Statement and
20  * the GNU General Public License along with this program. If not,
21  * see <http://www.lsstcorp.org/LegalNotices/>.
22  */
23 
24 #ifndef LSST_MEAS_MODELFIT_Mixture_h_INCLUDED
25 #define LSST_MEAS_MODELFIT_Mixture_h_INCLUDED
26 
27 #include <limits>
28 
29 #include "Eigen/Cholesky"
30 #include "Eigen/StdVector"
31 #include "Eigen/Dense"
32 
33 #include "ndarray.h"
34 
35 #include "lsst/base.h"
36 #include "lsst/afw/math/Random.h"
39 #include "lsst/afw/table/io/python.h" // for declarePersistableFacade
40 
41 
42 namespace lsst { namespace meas { namespace modelfit {
43 
48 public:
49 
51  int getDimension() const { return _mu.size(); }
52 
55 
57  Vector getMu() const { return _mu; }
59  void setMu(Vector const & mu) { _mu = mu; }
61 
63 
71  Matrix getSigma() const { return _sigmaLLT.reconstructedMatrix(); }
72  void setSigma(Matrix const & sigma);
74 
76  MixtureComponent project(int dim) const;
77 
79  MixtureComponent project(int dim1, int dim2) const;
80 
82  explicit MixtureComponent(int dim);
83 
85  MixtureComponent(Scalar weight_, Vector const & mu, Matrix const & sigma);
86 
88 
90  self._stream(os);
91  return os;
92  }
93 
94 private:
95 
96  friend class Mixture;
97 
98  void _stream(std::ostream & os, int offset=0) const;
99 
100  Scalar _sqrtDet;
101  Vector _mu;
102  Eigen::LLT<Matrix> _sigmaLLT;
103 };
104 
112 public:
113 
114  int getDimension() const { return _dim; }
115 
116  virtual void restrictMu(Vector & mu) const {}
117 
118  virtual void restrictSigma(Matrix & sigma) const {}
119 
121 
122  explicit MixtureUpdateRestriction(int dim) : _dim(dim) {}
123 
124 private:
125  int _dim;
126 };
127 
129 public:
130 
134  typedef ComponentList::iterator iterator;
135  typedef ComponentList::const_iterator const_iterator;
136 
138 
146  iterator begin() { return _components.begin(); }
147  iterator end() { return _components.end(); }
148 
149  const_iterator begin() const { return _components.begin(); }
150  const_iterator end() const { return _components.end(); }
151 
152  Component & operator[](std::size_t i) { return _components[i]; }
153  Component const & operator[](std::size_t i) const { return _components[i]; }
155 
157  std::size_t size() const { return _components.size(); }
158 
160  virtual int getComponentCount() const { return size(); }
161 
163  PTR(Mixture) project(int dim) const;
164 
166  PTR(Mixture) project(int dim1, int dim2) const;
167 
169  int getDimension() const { return _dim; }
170 
172  void normalize();
173 
175  void shift(int dim, Scalar offset);
176 
184  std::size_t clip(Scalar threshold=0.0);
185 
187  Scalar getDegreesOfFreedom() const { return _df; }
188 
191 
197  template <typename Derived>
198  Scalar evaluate(Component const & component, Eigen::MatrixBase<Derived> const & x) const {
199  Scalar z = _computeZ(component, x);
200  return component.weight * _evaluate(z) / component._sqrtDet;
201  }
202 
208  template <typename Derived>
209  Scalar evaluate(Eigen::MatrixBase<Derived> const & x) const {
210  Scalar p = 0.0;
211  for (const_iterator i = begin(); i != end(); ++i) {
212  p += evaluate(*i, x);
213  }
214  return p;
215  }
216 
223  void evaluate(
224  ndarray::Array<Scalar const,2,1> const & x,
225  ndarray::Array<Scalar,1,0> const & p
226  ) const;
227 
235  ndarray::Array<Scalar const,2,1> const & x,
236  ndarray::Array<Scalar,2,1> const & p
237  ) const;
238 
247  ndarray::Array<Scalar const,1,1> const & x,
248  ndarray::Array<Scalar,1,1> const & gradient,
249  ndarray::Array<Scalar,2,1> const & hessian
250  ) const;
251 
260  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> & x,
261  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> & gradient,
262  Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic> & hessian
263  ) const;
264 
272  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> & x,
273  Eigen::Matrix<Scalar, Eigen::Dynamic, 1> & gradient
274  ) const;
275 
282  void draw(afw::math::Random & rng, ndarray::Array<Scalar,2,1> const & x) const;
283 
306  void updateEM(
307  ndarray::Array<Scalar const,2,1> const & x,
308  ndarray::Array<Scalar const,1,0> const & w,
309  Scalar tau1=0.0, Scalar tau2=0.5
310  );
311 
322  void updateEM(
323  ndarray::Array<Scalar const,2,1> const & x,
324  ndarray::Array<Scalar const,1,0> const & w,
325  UpdateRestriction const & restriction,
326  Scalar tau1=0.0, Scalar tau2=0.5
327  );
328 
338  void updateEM(
339  ndarray::Array<Scalar const,2,1> const & x,
340  UpdateRestriction const & restriction,
341  Scalar tau1=0.0, Scalar tau2=0.5
342  );
343 
345  virtual PTR(Mixture) clone() const;
346 
358 
359  friend std::ostream & operator<<(std::ostream & os, Mixture const & self) {
360  self._stream(os);
361  return os;
362  }
363 
364  virtual bool isPersistable() const noexcept override { return true; }
365 
366 protected:
367 
368  std::string getPythonModule() const override { return "lsst.meas.modelfit"; }
369 
370  std::string getPersistenceName() const override;
371 
372  void write(OutputArchiveHandle & handle) const override;
373 
374 private:
375  template <typename A, typename B, typename C>
376  void _evaluateDerivativesImpl(A const & x,
377  B & gradient,
378  C * hessian,
379  bool computeHessian = true) const;
380 
381  template <typename Derived>
382  Scalar _computeZ(Component const & component, Eigen::MatrixBase<Derived> const & x) const {
383  _workspace = x - component._mu;
384  component._sigmaLLT.matrixL().solveInPlace(_workspace);
385  return _workspace.squaredNorm();
386  }
387 
388  // Helper function used in updateEM
389  void updateDampedSigma(int k, Matrix const & sigma, double tau1, double tau2);
390 
391  Scalar _evaluate(Scalar z) const;
392 
393  void _stream(std::ostream & os) const;
394 
395  bool _isGaussian;
396  int _dim;
397  Scalar _df;
398  Scalar _norm;
399  mutable Vector _workspace;
400  ComponentList _components;
401 };
402 
403 }}} // namespace lsst::meas::modelfit
404 
405 #endif // !LSST_MEAS_MODELFIT_Mixture_h_INCLUDED
lsst::meas::modelfit::Mixture::begin
iterator begin()
Iterator and indexed access to components.
Definition: Mixture.h:146
lsst::meas::modelfit::MixtureComponent::weight
Scalar weight
Weight of this distribution in the mixture.
Definition: Mixture.h:54
lsst::meas::modelfit::Mixture::updateEM
void updateEM(ndarray::Array< Scalar const, 2, 1 > const &x, UpdateRestriction const &restriction, Scalar tau1=0.0, Scalar tau2=0.5)
Perform an Expectation-Maximization step, updating the component parameters to match the given unweig...
std::string
STL class.
lsst::meas::modelfit::Mixture::clone
virtual boost::shared_ptr< Mixture > clone() const
Polymorphic deep copy.
lsst::meas::modelfit::Mixture::begin
const_iterator begin() const
Definition: Mixture.h:149
lsst::meas::modelfit::Mixture::size
std::size_t size() const
Return the number of components.
Definition: Mixture.h:157
lsst::meas::modelfit::Mixture::operator[]
Component const & operator[](std::size_t i) const
Definition: Mixture.h:153
lsst::meas::modelfit::MixtureComponent::setMu
void setMu(Vector const &mu)
Definition: Mixture.h:59
lsst::meas::modelfit::Mixture::getPersistenceName
std::string getPersistenceName() const override
Return the unique name used to persist this object and look up its factory.
lsst::afw::table::io::OutputArchiveHandle
An object passed to Persistable::write to allow it to persist itself.
Definition: OutputArchive.h:118
std::vector< Component >
lsst::meas::modelfit::MixtureComponent::MixtureComponent
MixtureComponent(int dim)
Default-construct a mixture component with weight=1, mu=0, sigma=identity.
std::vector::size
T size(T... args)
lsst::meas::modelfit::Mixture::ComponentList
std::vector< Component > ComponentList
Definition: Mixture.h:133
lsst::meas::modelfit::MixtureComponent::MixtureComponent
MixtureComponent(Scalar weight_, Vector const &mu, Matrix const &sigma)
Default-construct a mixture component with the given parameters.
lsst::meas::modelfit::Scalar
double Scalar
Typedefs to be used for probability and parameter values.
Definition: common.h:44
sigma
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:50
lsst::meas::modelfit::Mixture::setDegreesOfFreedom
void setDegreesOfFreedom(Scalar df=std::numeric_limits< Scalar >::infinity())
Set the number of degrees of freedom in the component Student's T distributions (inf=Gaussian)
lsst::meas::modelfit::Mixture::getPythonModule
std::string getPythonModule() const override
Return the fully-qualified Python module that should be imported to guarantee that its factory is reg...
Definition: Mixture.h:368
lsst::meas::modelfit::MixtureUpdateRestriction
Helper class used to define restrictions to the form of the component parameters in Mixture::updateEM...
Definition: Mixture.h:111
lsst::meas::modelfit::MixtureComponent::getSigma
Matrix getSigma() const
Get/set the shape/size parameter.
Definition: Mixture.h:71
lsst::meas::modelfit::MixtureComponent
A weighted Student's T or Gaussian distribution used as a component in a Mixture.
Definition: Mixture.h:47
lsst::meas::modelfit::Mixture::end
const_iterator end() const
Definition: Mixture.h:150
lsst::meas::modelfit::Mixture::clip
std::size_t clip(Scalar threshold=0.0)
Iterate over all components, removing those with weight less than or equal to threshold.
lsst::meas::modelfit::Mixture::getComponentCount
virtual int getComponentCount() const
Return the number of components.
Definition: Mixture.h:160
lsst::meas::modelfit::Mixture::const_iterator
ComponentList::const_iterator const_iterator
Definition: Mixture.h:135
lsst::meas::modelfit::Mixture::operator<<
friend std::ostream & operator<<(std::ostream &os, Mixture const &self)
Definition: Mixture.h:359
lsst::meas::modelfit::Mixture::evaluateComponents
void evaluateComponents(ndarray::Array< Scalar const, 2, 1 > const &x, ndarray::Array< Scalar, 2, 1 > const &p) const
Evaluate the contributions of each component to the full probability at the given points.
lsst::meas::modelfit::Mixture::getDimension
int getDimension() const
Return the number of dimensions.
Definition: Mixture.h:169
std::ostream
STL class.
z
double z
Definition: Match.cc:44
x
double x
Definition: ChebyshevBoundedField.cc:277
lsst::meas::modelfit::Mixture::getDegreesOfFreedom
Scalar getDegreesOfFreedom() const
Get the number of degrees of freedom in the component Student's T distributions (inf=Gaussian)
Definition: Mixture.h:187
other
ItemVariant const * other
Definition: Schema.cc:56
lsst::meas::modelfit::MixtureUpdateRestriction::~MixtureUpdateRestriction
virtual ~MixtureUpdateRestriction()
Definition: Mixture.h:120
lsst::meas::modelfit::Mixture::end
iterator end()
Definition: Mixture.h:147
lsst::meas::modelfit::Mixture
Definition: Mixture.h:128
lsst::meas::modelfit::Mixture::Component
MixtureComponent Component
Definition: Mixture.h:131
lsst::meas::modelfit::Vector
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
Definition: common.h:46
lsst::meas::modelfit::MixtureComponent::operator<<
friend std::ostream & operator<<(std::ostream &os, MixtureComponent const &self)
Definition: Mixture.h:89
lsst::meas::modelfit::MixtureComponent::setSigma
void setSigma(Matrix const &sigma)
lsst::meas::modelfit::Mixture::project
boost::shared_ptr< Mixture > project(int dim) const
Project the distribution onto the given dimensions (marginalize over all others)
base.h
lsst::meas::modelfit::Mixture::shift
void shift(int dim, Scalar offset)
Shift the mixture in the given dimension, adding the given offset to all mu vectors.
lsst::meas::modelfit::Mixture::UpdateRestriction
MixtureUpdateRestriction UpdateRestriction
Definition: Mixture.h:132
lsst
A base class for image defects.
Definition: imageAlgorithm.dox:1
lsst::meas::modelfit::Mixture::evaluateDerivatives
void evaluateDerivatives(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &x, Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &gradient) const
Evaluate the derivative of the distribution at the given point.
lsst::meas::modelfit::MixtureComponent::getMu
Vector getMu() const
Get/set the location parameter (mean/median/mode) of this component.
Definition: Mixture.h:58
lsst::meas::modelfit::Matrix
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > Matrix
Definition: common.h:45
lsst::meas::modelfit::Mixture::updateEM
void updateEM(ndarray::Array< Scalar const, 2, 1 > const &x, ndarray::Array< Scalar const, 1, 0 > const &w, UpdateRestriction const &restriction, Scalar tau1=0.0, Scalar tau2=0.5)
Perform an Expectation-Maximization step, updating the component parameters to match the given weight...
lsst::afw::table::io::Persistable
A base class for objects that can be persisted via afw::table::io Archive classes.
Definition: Persistable.h:74
os
std::ostream * os
Definition: Schema.cc:746
lsst::meas::modelfit::Mixture::project
boost::shared_ptr< Mixture > project(int dim1, int dim2) const
Project the distribution onto the given dimensions (marginalize over all others)
lsst::meas::modelfit::Mixture::evaluate
Scalar evaluate(Component const &component, Eigen::MatrixBase< Derived > const &x) const
Evaluate the probability density at the given point for the given component distribution.
Definition: Mixture.h:198
common.h
lsst::meas::modelfit::Mixture::evaluateDerivatives
void evaluateDerivatives(Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &x, Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > &gradient, Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > &hessian) const
Evaluate the derivative of the distribution at the given point.
lsst::afw::math::Random
A class that can be used to generate sequences of random numbers according to a number of different a...
Definition: Random.h:57
python.h
lsst::meas::modelfit::MixtureUpdateRestriction::MixtureUpdateRestriction
MixtureUpdateRestriction(int dim)
Definition: Mixture.h:122
lsst::meas::modelfit::Mixture::normalize
void normalize()
Iterate over all components, rescaling their weights so they sum to one.
lsst::meas::modelfit::Mixture::evaluateDerivatives
void evaluateDerivatives(ndarray::Array< Scalar const, 1, 1 > const &x, ndarray::Array< Scalar, 1, 1 > const &gradient, ndarray::Array< Scalar, 2, 1 > const &hessian) const
Evaluate the derivative of the distribution at the given point.
lsst::meas::modelfit::Mixture::updateEM
void updateEM(ndarray::Array< Scalar const, 2, 1 > const &x, ndarray::Array< Scalar const, 1, 0 > const &w, Scalar tau1=0.0, Scalar tau2=0.5)
Perform an Expectation-Maximization step, updating the component parameters to match the given weight...
std::vector::begin
T begin(T... args)
Persistable.h
lsst::meas::modelfit::Mixture::isPersistable
virtual bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
Definition: Mixture.h:364
PTR
#define PTR(...)
Definition: base.h:41
lsst::meas::modelfit::Mixture::Mixture
Mixture(int dim, ComponentList &components, Scalar df=std::numeric_limits< Scalar >::infinity())
Construct a mixture model.
lsst::meas::modelfit::Mixture::operator[]
Component & operator[](std::size_t i)
Definition: Mixture.h:152
lsst::meas::modelfit::MixtureUpdateRestriction::getDimension
int getDimension() const
Definition: Mixture.h:114
lsst::afw::table::io::PersistableFacade
A CRTP facade class for subclasses of Persistable.
Definition: Persistable.h:176
lsst::meas::modelfit::MixtureComponent::project
MixtureComponent project(int dim) const
Project the distribution onto the given dimension (marginalize over all others)
lsst::meas::modelfit::MixtureUpdateRestriction::restrictSigma
virtual void restrictSigma(Matrix &sigma) const
Definition: Mixture.h:118
w
double w
Definition: CoaddPsf.cc:69
lsst::meas::modelfit::Mixture::iterator
ComponentList::iterator iterator
Definition: Mixture.h:134
std::size_t
std::vector::end
T end(T... args)
lsst::meas::modelfit::MixtureUpdateRestriction::restrictMu
virtual void restrictMu(Vector &mu) const
Definition: Mixture.h:116
Random.h
lsst::meas::modelfit::MixtureComponent::operator=
MixtureComponent & operator=(MixtureComponent const &other)
lsst::meas::modelfit::MixtureComponent::project
MixtureComponent project(int dim1, int dim2) const
Project the distribution onto the given dimensions (marginalize over all others)
std::numeric_limits
components
table::Key< table::Array< int > > components
Definition: LinearCombinationKernel.cc:301
lsst::meas::modelfit::MixtureComponent::getDimension
int getDimension() const
Return the number of dimensions.
Definition: Mixture.h:51
lsst::meas::modelfit::Mixture::write
void write(OutputArchiveHandle &handle) const override
Write the object to one or more catalogs.
lsst::meas::modelfit::Mixture::draw
void draw(afw::math::Random &rng, ndarray::Array< Scalar, 2, 1 > const &x) const
Draw random variates from the distribution.
lsst::meas::modelfit::Mixture::evaluate
Scalar evaluate(Eigen::MatrixBase< Derived > const &x) const
Evaluate the mixture distribution probability density function (PDF) at the given points.
Definition: Mixture.h:209
lsst::meas::modelfit::Mixture::evaluate
void evaluate(ndarray::Array< Scalar const, 2, 1 > const &x, ndarray::Array< Scalar, 1, 0 > const &p) const
Evaluate the distribution probability density function (PDF) at the given points.