Loading [MathJax]/extensions/tex2jax.js
LSST Applications g0fba68d861+05816baf74,g1ec0fe41b4+f536777771,g1fd858c14a+a9301854fb,g35bb328faa+fcb1d3bbc8,g4af146b050+a5c07d5b1d,g4d2262a081+6e5fcc2a4e,g53246c7159+fcb1d3bbc8,g56a49b3a55+9c12191793,g5a012ec0e7+3632fc3ff3,g60b5630c4e+ded28b650d,g67b6fd64d1+ed4b5058f4,g78460c75b0+2f9a1b4bcd,g786e29fd12+cf7ec2a62a,g8352419a5c+fcb1d3bbc8,g87b7deb4dc+7b42cf88bf,g8852436030+e5453db6e6,g89139ef638+ed4b5058f4,g8e3bb8577d+d38d73bdbd,g9125e01d80+fcb1d3bbc8,g94187f82dc+ded28b650d,g989de1cb63+ed4b5058f4,g9d31334357+ded28b650d,g9f33ca652e+50a8019d8c,gabe3b4be73+1e0a283bba,gabf8522325+fa80ff7197,gb1101e3267+d9fb1f8026,gb58c049af0+f03b321e39,gb665e3612d+2a0c9e9e84,gb89ab40317+ed4b5058f4,gcf25f946ba+e5453db6e6,gd6cbbdb0b4+bb83cc51f8,gdd1046aedd+ded28b650d,gde0f65d7ad+941d412827,ge278dab8ac+d65b3c2b70,ge410e46f29+ed4b5058f4,gf23fb2af72+b7cae620c0,gf5e32f922b+fcb1d3bbc8,gf67bdafdda+ed4b5058f4,w.2025.16
LSST Data Management Base Package
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Modules Pages
LeastSqFitter1d.h
Go to the documentation of this file.
1// -*- LSST-C++ -*-
2
3/*
4 * LSST Data Management System
5 * Copyright 2008, 2009, 2010 LSST Corporation.
6 *
7 * This product includes software developed by the
8 * LSST Project (http://www.lsst.org/).
9 *
10 * This program is free software: you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation, either version 3 of the License, or
13 * (at your option) any later version.
14 *
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
19 *
20 * You should have received a copy of the LSST License Statement and
21 * the GNU General Public License along with this program. If not,
22 * see <http://www.lsstcorp.org/LegalNotices/>.
23 */
24
25#ifndef LEAST_SQ_FITTER_1D
26#define LEAST_SQ_FITTER_1D
27
28#include <cstdio>
29#include <memory>
30#include <vector>
31
32#include "Eigen/Core"
33#include "Eigen/SVD"
34
37
38namespace lsst {
39namespace meas {
40namespace astrom {
41namespace sip {
42
62
63template <class FittingFunc>
65public:
67 int order);
68
69 Eigen::VectorXd getParams();
70 Eigen::VectorXd getErrors();
71 FittingFunc getBestFitFunction();
72 double valueAt(double x);
74
75 double getChiSq();
76 double getReducedChiSq();
77
78private:
79 void initFunctions();
80
81 double func1d(double value, int exponent);
82
83 std::vector<double> _x, _y, _s;
84 int _order; // Degree of polynomial to fit, e.g 4=> cubic
85 int _nData; // Number of data points, == _x.size()
86
87 Eigen::JacobiSVD<Eigen::MatrixXd> _svd;
88 Eigen::VectorXd _par;
89
91};
92
93// The .cc part
94
103template <class FittingFunc>
105 const std::vector<double> &s, int order)
106 : _x(x), _y(y), _s(s), _order(order) {
107 if (order == 0) {
108 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Fit order must be >= 1");
109 }
110
111 _nData = _x.size();
112 if (_nData != static_cast<int>(_y.size())) {
113 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "x and y vectors of different lengths");
114 }
115 if (_nData != static_cast<int>(_s.size())) {
116 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "x and s vectors of different lengths");
117 }
118
119 if (_nData < _order) {
120 throw LSST_EXCEPT(pex::exceptions::RuntimeError, "Fewer data points than parameters");
121 }
122
123 initFunctions();
124
125 Eigen::MatrixXd design(_nData, _order);
126 Eigen::VectorXd rhs(_nData);
127 for (int i = 0; i < _nData; ++i) {
128 rhs[i] = y[i] / _s[i];
129 for (int j = 0; j < _order; ++j) {
130 design(i, j) = func1d(_x[i], j) / _s[i];
131 }
132 }
133 _svd.compute(design, Eigen::ComputeThinU | Eigen::ComputeThinV);
134 _par = _svd.solve(rhs);
135}
136
138template <class FittingFunc>
140 Eigen::VectorXd vec = Eigen::VectorXd::Zero(_order);
141 for (int i = 0; i < _order; ++i) {
142 vec(i) = _par(i);
143 }
144 return vec;
145}
146
148template <class FittingFunc>
150 Eigen::ArrayXd variance(_order);
151 for (int i = 0; i < _order; ++i) {
152 variance[i] = _svd.matrixV().row(i).dot(
153 (_svd.singularValues().array().inverse().square() * _svd.matrixV().col(i).array()).matrix());
154 }
155 return variance.sqrt().matrix();
156}
157
159template <class FittingFunc>
161 // FittingFunc and LeastSqFitter disagree on the definition of order of a function.
162 // LSF says that a linear function is order 2 (two coefficients), FF says only 1
163 FittingFunc func(_order - 1);
164
165 for (int i = 0; i < _order; ++i) {
166 func.setParameter(i, _par(i));
167 }
168 return func;
169}
170
172template <class FittingFunc>
174 FittingFunc f = getBestFitFunction();
175
176 return f(x);
177}
178
181template <class FittingFunc>
184 out.reserve(_nData);
185
186 FittingFunc f = getBestFitFunction();
187
188 for (int i = 0; i < _nData; ++i) {
189 out.push_back(_y[i] - f(_x[i]));
190 }
191
192 return out;
193}
194
198template <class FittingFunc>
200 FittingFunc f = getBestFitFunction();
201
202 double chisq = 0;
203 for (int i = 0; i < _nData; ++i) {
204 double val = _y[i] - f(_x[i]);
205 val /= _s[i];
206 chisq += pow(val, 2);
207 }
208
209 return chisq;
210}
211
217template <class FittingFunc>
219 return getChiSq() / (double)(_nData - _order);
220}
221
224template <class FittingFunc>
225void LeastSqFitter1d<FittingFunc>::initFunctions() {
226 _funcArray.reserve(_order);
227
229 coeff.reserve(_order);
230
231 coeff.push_back(1.0);
232 for (int i = 0; i < _order; ++i) {
233 std::shared_ptr<FittingFunc> p(new FittingFunc(coeff));
234 _funcArray.push_back(p);
235 coeff[i] = 0.0;
236 coeff.push_back(1.0); // coeff now looks like [0,0,...,0,1]
237 }
238}
239
240template <class FittingFunc>
241double LeastSqFitter1d<FittingFunc>::func1d(double value, int exponent) {
242 return (*_funcArray[exponent])(value);
243}
244
245} // namespace sip
246} // namespace astrom
247} // namespace meas
248} // namespace lsst
249
250#endif
#define LSST_EXCEPT(type,...)
Create an exception with a given type.
Definition Exception.h:48
std::vector< double > residuals()
Return a vector of residuals of the fit (i.e the difference between the input y values,...
double getChiSq()
Return a measure of the goodness of fit.
Eigen::VectorXd getParams()
Return the best fit parameters as an Eigen::Matrix.
double getReducedChiSq()
Return a measure of the goodness of fit.
Eigen::VectorXd getErrors()
Return the 1 sigma uncertainties in the best fit parameters as an Eigen::Matrix.
FittingFunc getBestFitFunction()
Return the best fit polynomial as a lsst::afw::math::Function1 object.
LeastSqFitter1d(const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &s, int order)
Fit a 1d polynomial to a set of data points z(x, y)
double valueAt(double x)
Calculate the value of the function at a given point.
Reports errors that are due to events beyond the control of the program.
Definition Runtime.h:104
T push_back(T... args)
T reserve(T... args)