LSST Applications g180d380827+78227d2bc4,g2079a07aa2+86d27d4dc4,g2305ad1205+bdd7851fe3,g2bbee38e9b+c6a8a0fb72,g337abbeb29+c6a8a0fb72,g33d1c0ed96+c6a8a0fb72,g3a166c0a6a+c6a8a0fb72,g3d1719c13e+260d7c3927,g3ddfee87b4+723a6db5f3,g487adcacf7+29e55ea757,g50ff169b8f+96c6868917,g52b1c1532d+585e252eca,g591dd9f2cf+9443c4b912,g62aa8f1a4b+7e2ea9cd42,g858d7b2824+260d7c3927,g864b0138d7+8498d97249,g95921f966b+dffe86973d,g991b906543+260d7c3927,g99cad8db69+4809d78dd9,g9c22b2923f+e2510deafe,g9ddcbc5298+9a081db1e4,ga1e77700b3+03d07e1c1f,gb0e22166c9+60f28cb32d,gb23b769143+260d7c3927,gba4ed39666+c2a2e4ac27,gbb8dafda3b+e22341fd87,gbd998247f1+585e252eca,gc120e1dc64+713f94b854,gc28159a63d+c6a8a0fb72,gc3e9b769f7+385ea95214,gcf0d15dbbd+723a6db5f3,gdaeeff99f8+f9a426f77a,ge6526c86ff+fde82a80b9,ge79ae78c31+c6a8a0fb72,gee10cc3b42+585e252eca,w.2024.18
LSST Data Management Base Package
Loading...
Searching...
No Matches
mixture.cc
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#include "pybind11/pybind11.h"
26#include "pybind11/eigen.h"
27#include "pybind11/stl.h"
28
29#include <sstream> // Python.h must come before even system headers
30
31#include "ndarray/pybind11.h"
32#include "ndarray/eigen.h"
33
34
36
37namespace py = pybind11;
38using namespace pybind11::literals;
39
40namespace lsst {
41namespace meas {
42namespace modelfit {
43namespace {
44
45using PyMixtureComponent = py::class_<MixtureComponent>;
46using PyMixtureUpdateRestriction =
47 py::class_<MixtureUpdateRestriction, std::shared_ptr<MixtureUpdateRestriction>>;
48using PyMixture = py::class_<Mixture, std::shared_ptr<Mixture>>;
49
50PyMixtureComponent declareMixtureComponent(lsst::cpputils::python::WrapperCollection &wrappers) {
51 return wrappers.wrapType(
52 PyMixtureComponent(wrappers.module, "MixtureComponent"), [](auto &mod, auto &cls) {
53 cls.def("getDimension", &MixtureComponent::getDimension);
54 cls.def_readwrite("weight", &MixtureComponent::weight);
55 cls.def("getMu", &MixtureComponent::getMu);
56 cls.def("setMu", &MixtureComponent::setMu);
57 cls.def("getSigma", &MixtureComponent::getSigma);
58 cls.def("setSigma", &MixtureComponent::setSigma);
59 cls.def("project", (MixtureComponent (MixtureComponent::*)(int) const) &MixtureComponent::project,
60 "dim"_a);
61 cls.def("project", (MixtureComponent (MixtureComponent::*)(int, int) const) &MixtureComponent::project,
62 "dim1"_a, "dim2"_a);
63 cls.def(py::init<int>(), "dim"_a);
64 cls.def(py::init<Scalar, Vector const &, Matrix const &>(), "weight"_a, "mu"_a, "sigma"_a);
65 utils::python::addOutputOp(cls, "__str__");
66 utils::python::addOutputOp(cls, "__repr__");
67 });
68}
69
70PyMixtureUpdateRestriction declareMixtureUpdateRestriction(lsst::cpputils::python::WrapperCollection &wrappers) {
71 return wrappers.wrapType(PyMixtureUpdateRestriction(
72 wrappers.module, "MixtureUpdateRestriction"), [](auto &mod, auto &cls) {
73 cls.def("getDimension", &MixtureUpdateRestriction::getDimension);
74 cls.def(py::init<int>(), "dim"_a);
75 // The rest of this interface isn't usable in Python, and doesn't need to be.
76 });
77}
78
79PyMixture declareMixture(lsst::cpputils::python::WrapperCollection &wrappers) {
80 return wrappers.wrapType(PyMixture(wrappers.module, "Mixture"), [](auto &mod, auto &cls) {
81 afw::table::io::python::addPersistableMethods<Mixture>(cls);
82 cls.def("__iter__", [](Mixture &self) { return py::make_iterator(self.begin(), self.end()); },
83 py::keep_alive<0, 1>());
84 cls.def("__getitem__",
85 [](Mixture &self, std::ptrdiff_t i) { return self[utils::python::cppIndex(self.size(), i)]; },
86 py::return_value_policy::reference_internal);
87 cls.def("__len__", &Mixture::size);
88 cls.def("getComponentCount", &Mixture::getComponentCount);
89 cls.def("project", (std::shared_ptr<Mixture> (Mixture::*)(int) const) &Mixture::project, "dim"_a);
90 cls.def("project", (std::shared_ptr<Mixture> (Mixture::*)(int, int) const) &Mixture::project, "dim1"_a,
91 "dim2"_a);
92 cls.def("getDimension", &Mixture::getDimension);
93 cls.def("normalize", &Mixture::normalize);
94 cls.def("shift", &Mixture::shift, "dim"_a, "offset"_a);
95 cls.def("clip", &Mixture::clip, "threshold"_a = 0.0);
96 cls.def("getDegreesOfFreedom", &Mixture::getDegreesOfFreedom);
97 cls.def("setDegreesOfFreedom", &Mixture::setDegreesOfFreedom,
99 cls.def("evaluate",
100 [](Mixture const &self, MixtureComponent const &component,
101 ndarray::Array<Scalar, 1, 0> const &array) -> Scalar {
102 return self.evaluate(component, ndarray::asEigenMatrix(array));
103 },
104 "component"_a, "x"_a);
105 cls.def("evaluate",
106 [](Mixture const &self, ndarray::Array<Scalar, 1, 0> const &array) -> Scalar {
107 return self.evaluate(ndarray::asEigenMatrix(array));
108 },
109 "x"_a);
110 cls.def("evaluate", (void (Mixture::*)(ndarray::Array<Scalar const, 2, 1> const &,
111 ndarray::Array<Scalar, 1, 0> const &) const) &
112 Mixture::evaluate,
113 "x"_a, "p"_a);
114 cls.def("evaluateComponents", &Mixture::evaluateComponents, "x"_a, "p"_a);
115 cls.def("evaluateDerivatives",
116 py::overload_cast<ndarray::Array<Scalar const, 1, 1> const &,
117 ndarray::Array<Scalar, 1, 1> const &,
118 ndarray::Array<Scalar, 2, 1> const &>(&Mixture::evaluateDerivatives, py::const_),
119 "x"_a, "gradient"_a, "hessian"_a);
120 cls.def("draw", &Mixture::draw, "rng"_a, "x"_a);
121 cls.def("updateEM", (void (Mixture::*)(ndarray::Array<Scalar const, 2, 1> const &,
122 ndarray::Array<Scalar const, 1, 0> const &, Scalar, Scalar)) &
123 Mixture::updateEM,
124 "x"_a, "w"_a, "tau1"_a = 0.0, "tau2"_a = 0.5);
125 cls.def("updateEM", (void (Mixture::*)(ndarray::Array<Scalar const, 2, 1> const &,
126 ndarray::Array<Scalar const, 1, 0> const &,
127 MixtureUpdateRestriction const &restriction, Scalar, Scalar)) &
128 Mixture::updateEM,
129 "x"_a, "w"_a, "restriction"_a, "tau1"_a = 0.0, "tau2"_a = 0.5);
130 cls.def("updateEM", (void (Mixture::*)(ndarray::Array<Scalar const, 2, 1> const &,
131 MixtureUpdateRestriction const &restriction, Scalar, Scalar)) &
132 Mixture::updateEM,
133 "x"_a, "restriction"_a, "tau1"_a = 0.0, "tau2"_a = 0.5);
134 cls.def("clone", &Mixture::clone);
135 cls.def(py::init<int, Mixture::ComponentList &, Scalar>(), "dim"_a, "components"_a,
137 utils::python::addOutputOp(cls, "__str__");
138 utils::python::addOutputOp(cls, "__repr__");
139 });
140}
141} // namespace
142
144 auto clsMixtureComponent = declareMixtureComponent(wrappers);
145 auto clsMixtureUpdateRestriction = declareMixtureUpdateRestriction(wrappers);
146 auto clsMixture = declareMixture(wrappers);
147 clsMixture.attr("Component") = clsMixtureComponent;
148 clsMixture.attr("UpdateRestriction") = clsMixtureUpdateRestriction;
149}
150
151} // namespace modelfit
152} // namespace meas
153} // namespace lsst
A helper class for subdividing pybind11 module across multiple translation units (i....
Definition python.h:242
PyType wrapType(PyType cls, ClassWrapperCallback function, bool setModuleName=true)
Add a type (class or enum) wrapper, deferring method and other attribute definitions until finish() i...
Definition python.h:391
Scalar getDegreesOfFreedom() const
Get the number of degrees of freedom in the component Student's T distributions (inf=Gaussian)
Definition Mixture.h:187
std::size_t size() const
Return the number of components.
Definition Mixture.h:157
void normalize()
Iterate over all components, rescaling their weights so they sum to one.
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.
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.
void shift(int dim, Scalar offset)
Shift the mixture in the given dimension, adding the given offset to all mu vectors.
virtual std::shared_ptr< Mixture > clone() const
Polymorphic deep copy.
virtual int getComponentCount() const
Return the number of components.
Definition Mixture.h:160
void draw(afw::math::Random &rng, ndarray::Array< Scalar, 2, 1 > const &x) const
Draw random variates from the distribution.
int getDimension() const
Return the number of dimensions.
Definition Mixture.h:169
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)
std::size_t clip(Scalar threshold=0.0)
Iterate over all components, removing those with weight less than or equal to threshold.
str project
Definition conf.py:10
void wrapMixture(lsst::cpputils::python::WrapperCollection &wrappers)
Definition mixture.cc:143
double Scalar
Typedefs to be used for probability and parameter values.
Definition common.h:44