# Kstars

curvefit.h
1 #pragma once
2
3 #include <QVector>
4 #include <qcustomplot.h>
5 #include <gsl/gsl_vector.h>
6 #include <gsl/gsl_min.h>
7 #include <gsl/gsl_matrix.h>
8 #include <gsl/gsl_multifit.h>
9 #include <gsl/gsl_multifit_nlin.h>
10 #include <gsl/gsl_blas.h>
11
12 namespace Ekos
13 {
14 // The curve fitting class provides curve fitting algorithms using the Lehvensberg-Marquart (LM)
15 // solver as provided the the Gnu Science Library (GSL). See the comments at the start of curvefit.cpp
16 // for more details.
17 //
18 // 2 curves, hyperbola and parabola are provided.
19 // For compatibility with existing Ekos functionality a Quadratic option using the exising Ekos linear
20 // least squares solver (again provided by GSL) is supported. The Quadratic and Parabola curves are
21 // the same thing mathematically but Parabola uses the non-linear least squares LM solver whilst Quadratic
22 // uses the original Ekos linear least squares solver.
23 //
24 // Users of CurveFitting operate on focuser position and HFR. Within CurveFitting the curve uses the more
25 // usual mathematical notation of x, y
26 //
27 // Furture releases may migrate all curve fitting to the LM solver.
28 class CurveFitting
29 {
30  public:
31  typedef enum { FOCUS_QUADRATIC, FOCUS_HYPERBOLA, FOCUS_PARABOLA } CurveFit;
32
33  // Data structures to hold datapoints for the class
34  struct DataPT
35  {
36  double x; // focuser position
37  double y; // star HFR
38  double sigma; // standard deviation of star HFR
39  };
40
41  struct DataPointT // This is the data strcture passed into GSL LM routines
42  {
43  bool useWeights; // Are we fitting the curve with or without weights (using sigma or not)
44  QVector<DataPT> dps; // Vector of DataPT
45
46  // Helper function to operate on the data structure
47  void push_back(double x, double y, double sigma)
48  {
49  dps.push_back({x, y, sigma});
50  }
51  };
52
53  // Constructor just initialises the object
54  CurveFitting();
55  // fitCurve takes in the vectors with the position, hfr and sigma (standard deviation in HFR) values
56  // along with the type of curve to use and whether or not to sigmas in the calculation
57  // It fits the curve and solves for the coefficients.
58  void fitCurve(const QVector<int> &position, const QVector<double> &hfr, const QVector<double> &sigma,
59  const CurveFit curveFit,
60  const bool useWeights);
61
62  // Returns the minimum position and value in the pointers for the solved curve.
63  // Returns false if the curve couldn't be solved.
64  bool findMin(double expected, double minPosition, double maxPosition, double *position, double *value, CurveFit curveFit);
65  // f calculates the value of y (hfr) for a given x (position) using the appropriate curve algorithm
66  double f(double x);
67  // Calculates the R-squared which is a measure of how well the curve fits the datapoints
68  double calculateR2(CurveFit curveFit);
69
70  private:
71  // TODO: This function will likely go when Linear and L1P merge to be closer.
72  // Calculates the value of the polynomial at x. Params will be cast to a CurveFit*.
73  static double curveFunction(double x, void *params);
74
75  // TODO: This function will likely go when Linear and L1P merge to be closer.
76  QVector<double> polynomial_fit(const double *const data_x, const double *const data_y, const int n, const int order);
77  QVector<double> hyperbola_fit(const QVector<double> data_x, const QVector<double> data_y, const QVector<double> data_sigma,
78  bool useWeights);
79  QVector<double> parabola_fit(const QVector<double> data_x, const QVector<double> data_y, const QVector<double> data_sigma,
80  bool useWeights);
81
82  bool minimumQuadratic(double expected, double minPosition, double maxPosition, double *position, double *value);
83  bool minimumHyperbola(double expected, double minPosition, double maxPosition, double *position, double *value);
84  bool minimumParabola(double expected, double minPosition, double maxPosition, double *position, double *value);
85
86  void hypMakeGuess(const QVector<double> inX, const QVector<double> inY, gsl_vector * guess);
87  void parMakeGuess(const QVector<double> inX, const QVector<double> inY, gsl_vector * guess);
88
89  // Calculation engine for the R-squared which is a measure of how well the curve fits the datapoints
90  double calcR2(QVector<double> dataPoints, QVector<double> curvePoints);
91
92  // Type of curve
93  CurveFit m_CurveType;
94  // The data values.
95  QVector<double> m_x, m_y, m_sigma;
96  // The solved parameters.
97  QVector<double> m_coefficients;
98  // State variables used by the LM solver. These variables provide a way of optimising the starting
99  // point for the solver by using the solution found by the previous run providing the relevant
100  // solver parameters are consistent between runs.
101  bool firstSolverRun;
102  CurveFit lastCurveType;
103  QVector<double> lastCoefficients;
104 };
105
106 } //namespace
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:70
void push_back(const T &value)
This file is part of the KDE documentation.