26 #ifndef LEAST_SQ_FITTER_2D 27 #define LEAST_SQ_FITTER_2D 76 double valueAt(
double x,
double y);
85 Eigen::MatrixXd expandParams(Eigen::VectorXd
const & input)
const;
87 double func2d(
double x,
double y,
int term);
88 double func1d(
double value,
int exponent);
95 Eigen::JacobiSVD<Eigen::MatrixXd> _svd;
121 _x(x), _y(y), _z(z), _s(s), _order(order), _nPar(0), _par(1) {
125 for (
int i = 0; i < order; ++i) {
131 if (_nData != static_cast<int>(_y.
size())) {
134 if (_nData != static_cast<int>(_s.
size())) {
137 if (_nData != static_cast<int>(_z.
size())) {
141 for (
int i = 0; i < _nData; ++i) {
142 if ( _s[i] == 0.0 ) {
143 std::string msg =
"Illegal zero value for fit weight encountered.";
148 if (_nData < _order) {
154 Eigen::MatrixXd design(_nData, _nPar);
155 Eigen::VectorXd rhs(_nData);
156 for (
int i = 0; i < _nData; ++i) {
157 rhs[i] = z[i] / s[i];
158 for (
int j = 0; j < _nPar; ++j) {
159 design(i, j) = func2d(_x[i], _y[i], j) / _s[i];
162 _svd.compute(design, Eigen::ComputeThinU | Eigen::ComputeThinV);
163 _par = _svd.solve(rhs);
177 return expandParams(_par);
181 template<
class FittingFunc>
183 Eigen::MatrixXd out = Eigen::MatrixXd::Zero(_order, _order);
185 for (
int i = 0; i < _order; ++i) {
186 for (
int j = 0; j < _order - i; ++j) {
187 out(i, j) = input[count++];
198 for (
int i = 0; i < _nData; ++i) {
199 double val = _z[i] -
valueAt(_x[i], _y[i]);
201 chisq += pow(val, 2);
214 return getChiSq()/(double) (_nData - _nPar);
224 for (
int i = 0; i < _nPar; ++i) {
225 val += _par[i] * func2d(x, y, i);
237 for (
int i = 0; i < _nData; ++i) {
246 template<
class FittingFunc>
249 for (
int i = 0; i < _nPar; ++i) {
250 variance[i] = _svd.matrixV().row(i).dot(
251 (_svd.singularValues().array().inverse().square() * _svd.matrixV().col(i).array()).matrix()
254 return expandParams(variance.sqrt().matrix());
266 for (
int i = 0; i < _order; ++i) {
283 for (
int i = 0; i<term; ++i) {
284 yexp = (yexp + 1) % (_order - xexp);
290 double xcomp = func1d(x, xexp);
291 double ycomp = func1d(y, yexp);
293 #if 0 //A useful debugging printf statement 294 printf(
"The %i(th) function: x^%i * y^%i = %.1f * %.1f\n", term, xexp, yexp, xcomp, ycomp);
301 return (*_funcArray[exponent])(value);
Fit an lsst::afw::math::Function1 object to a set of data points in two dimensions.
double getReducedChiSq()
Return a measure of the goodness of fit.
std::vector< double > residuals()
Return a vector of residuals of the fit (i.e the difference between the input z values, and the value of the fitting function at that point.
double getChiSq()
Return a measure of the goodness of fit.
double valueAt(double x, double y)
Return the value of the best fit function at a given position (x,y)
Eigen::MatrixXd getParams()
Build up a triangular matrix of the parameters.
#define LSST_EXCEPT(type,...)
Eigen::MatrixXd getErrors()
Companion function to getParams(). Returns uncertainties in the parameters as a matrix.
LeastSqFitter2d(const std::vector< double > &x, const std::vector< double > &y, const std::vector< double > &z, const std::vector< double > &s, int order)
Fit a 2d polynomial to a set of data points z(x, y)