LSSTApplications  18.0.0+106,18.0.0+50,19.0.0,19.0.0+1,19.0.0+10,19.0.0+11,19.0.0+13,19.0.0+17,19.0.0+2,19.0.0-1-g20d9b18+6,19.0.0-1-g425ff20,19.0.0-1-g5549ca4,19.0.0-1-g580fafe+6,19.0.0-1-g6fe20d0+1,19.0.0-1-g7011481+9,19.0.0-1-g8c57eb9+6,19.0.0-1-gb5175dc+11,19.0.0-1-gdc0e4a7+9,19.0.0-1-ge272bc4+6,19.0.0-1-ge3aa853,19.0.0-10-g448f008b,19.0.0-12-g6990b2c,19.0.0-2-g0d9f9cd+11,19.0.0-2-g3d9e4fb2+11,19.0.0-2-g5037de4,19.0.0-2-gb96a1c4+3,19.0.0-2-gd955cfd+15,19.0.0-3-g2d13df8,19.0.0-3-g6f3c7dc,19.0.0-4-g725f80e+11,19.0.0-4-ga671dab3b+1,19.0.0-4-gad373c5+3,19.0.0-5-ga2acb9c+2,19.0.0-5-gfe96e6c+2,w.2020.01
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 
190  void setDegreesOfFreedom(Scalar df=std::numeric_limits<Scalar>::infinity());
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 
234  void evaluateComponents(
235  ndarray::Array<Scalar const,2,1> const & x,
236  ndarray::Array<Scalar,2,1> const & p
237  ) const;
238 
246  void evaluateDerivatives(
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 
259  void evaluateDerivatives(
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 
271  void evaluateDerivatives(
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 
357  explicit Mixture(int dim, ComponentList & components, Scalar df=std::numeric_limits<Scalar>::infinity());
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
table::Key< table::Array< int > > components
def write(self, patchRef, catalog)
Write the output.
Component const & operator[](std::size_t i) const
Iterator and indexed access to components.
Definition: Mixture.h:153
Scalar getDegreesOfFreedom() const
Get the number of degrees of freedom in the component Student&#39;s T distributions (inf=Gaussian) ...
Definition: Mixture.h:187
virtual bool isPersistable() const noexcept override
Return true if this particular object can be persisted using afw::table::io.
Definition: Mixture.h:364
Component & operator[](std::size_t i)
Iterator and indexed access to components.
Definition: Mixture.h:152
Basic LSST definitions.
std::vector< Component > ComponentList
Definition: Mixture.h:133
ComponentList::iterator iterator
Definition: Mixture.h:134
An object passed to Persistable::write to allow it to persist itself.
MixtureComponent(int dim)
Default-construct a mixture component with weight=1, mu=0, sigma=identity.
MixtureUpdateRestriction UpdateRestriction
Definition: Mixture.h:132
MixtureComponent Component
Definition: Mixture.h:131
std::size_t size() const
Return the number of components.
Definition: Mixture.h:157
double Scalar
Typedefs to be used for probability and parameter values.
Definition: common.h:44
MixtureComponent & operator=(MixtureComponent const &other)
ItemVariant const * other
Definition: Schema.cc:56
double z
Definition: Match.cc:44
int getDimension() const
Return the number of dimensions.
Definition: Mixture.h:51
Vector getMu() const
Get/set the location parameter (mean/median/mode) of this component.
Definition: Mixture.h:58
afw::table::Key< double > sigma
Definition: GaussianPsf.cc:50
STL class.
A weighted Student&#39;s T or Gaussian distribution used as a component in a Mixture. ...
Definition: Mixture.h:47
A base class for objects that can be persisted via afw::table::io Archive classes.
Definition: Persistable.h:74
Helper class used to define restrictions to the form of the component parameters in Mixture::updateEM...
Definition: Mixture.h:111
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
Scalar evaluate(Eigen::MatrixBase< Derived > const &x) const
Evaluate the mixture distribution probability density function (PDF) at the given points...
Definition: Mixture.h:209
A base class for image defects.
Eigen::Matrix< Scalar, Eigen::Dynamic, Eigen::Dynamic > Matrix
Typedefs to be used for probability and parameter values.
Definition: common.h:45
int getDimension() const
Return the number of dimensions.
Definition: Mixture.h:169
Eigen::Matrix< Scalar, Eigen::Dynamic, 1 > Vector
Typedefs to be used for probability and parameter values.
Definition: common.h:46
MixtureComponent project(int dim) const
Project the distribution onto the given dimension (marginalize over all others)
const_iterator begin() const
Iterator and indexed access to components.
Definition: Mixture.h:149
virtual int getComponentCount() const
Return the number of components.
Definition: Mixture.h:160
double x
ComponentList::const_iterator const_iterator
Definition: Mixture.h:135
double w
Definition: CoaddPsf.cc:69
Scalar weight
Weight of this distribution in the mixture.
Definition: Mixture.h:54
friend std::ostream & operator<<(std::ostream &os, Mixture const &self)
Definition: Mixture.h:359
virtual void restrictSigma(Matrix &sigma) const
Definition: Mixture.h:118
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
void setSigma(Matrix const &sigma)
Get/set the shape/size parameter.
const_iterator end() const
Iterator and indexed access to components.
Definition: Mixture.h:150
iterator end()
Iterator and indexed access to components.
Definition: Mixture.h:147
std::ostream * os
Definition: Schema.cc:746
Matrix getSigma() const
Get/set the shape/size parameter.
Definition: Mixture.h:71
A CRTP facade class for subclasses of Persistable.
Definition: Persistable.h:176
STL class.
#define PTR(...)
Definition: base.h:41
int end
iterator begin()
Iterator and indexed access to components.
Definition: Mixture.h:146
A class that can be used to generate sequences of random numbers according to a number of different a...
Definition: Random.h:57
friend std::ostream & operator<<(std::ostream &os, MixtureComponent const &self)
Definition: Mixture.h:89
virtual void restrictMu(Vector &mu) const
Definition: Mixture.h:116
void setMu(Vector const &mu)
Get/set the location parameter (mean/median/mode) of this component.
Definition: Mixture.h:59