# Kstars

polynomialfit.cpp
1 #include "polynomialfit.h"
2
3 #include "ekos/ekos.h"
4 #include <gsl/gsl_fit.h>
5 #include <gsl/gsl_vector.h>
6 #include <gsl/gsl_min.h>
7 #include <ekos_focus_debug.h>
8
9 namespace Ekos
10 {
11
12 PolynomialFit::PolynomialFit(int degree_, uint8_t maxCount, const QVector<double> &x_, const QVector<double> &y_)
13  : degree(degree_), x(x_), y(y_)
14 {
15  Q_ASSERT(x_.size() == y_.size());
17  for (int i = 0; i < x.count(); i++)
18  values << QPointF(x[i], y[i]);
19
20  std::sort(values.begin(), values.end(), [](const QPointF & a, const QPointF & b)
21  {
22  return a.y() < b.y();
23  });
24
25  while(values.count() > maxCount)
26  values.takeLast();
27
28  x.clear();
29  y.clear();
30
31  for (const auto &onePoint : values)
32  {
33  x << onePoint.x();
34  y << onePoint.y();
35  }
36
37  solve(x, y);
38 }
39
40 PolynomialFit::PolynomialFit(int degree_, const QVector<int> &x_, const QVector<double> &y_)
41  : degree(degree_), y(y_)
42 {
43  Q_ASSERT(x_.size() == y_.size());
44  for (int i = 0; i < x_.size(); ++i)
45  {
46  x.push_back(static_cast<double>(x_[i]));
47  }
48  solve(x, y);
49 }
50
51 void PolynomialFit::solve(const QVector<double> &x, const QVector<double> &y)
52 {
53  double chisq = 0;
54  coefficients = gsl_polynomial_fit(x.data(), y.data(), x.count(), degree, chisq);
55 }
56
57 double PolynomialFit::polynomialFunction(double x, void *params)
58 {
59  PolynomialFit *instance = static_cast<PolynomialFit *>(params);
60
61  if (instance && !instance->coefficients.empty())
62  return instance->f(x);
63  else
64  return -1;
65 }
66
67 double PolynomialFit::f(double x)
68 {
69  const int order = coefficients.size() - 1;
70  double sum = 0;
71  for (int i = 0; i <= order; ++i)
72  sum += coefficients[i] * pow(x, i);
73  return sum;
74 }
75
76 bool PolynomialFit::findMinimum(double expected, double minPosition, double maxPosition, double *position, double *value)
77 {
78  int status;
79  int iter = 0, max_iter = 100;
80  const gsl_min_fminimizer_type *T;
81  gsl_min_fminimizer *s;
82  double m = expected;
83
84  gsl_function F;
85  F.function = &PolynomialFit::polynomialFunction;
86  F.params = this;
87
88  // Must turn off error handler or it aborts on error
89  gsl_set_error_handler_off();
90
91  T = gsl_min_fminimizer_brent;
92  s = gsl_min_fminimizer_alloc(T);
93  status = gsl_min_fminimizer_set(s, &F, expected, minPosition, maxPosition);
94
95  if (status != GSL_SUCCESS)
96  {
97  qCWarning(KSTARS_EKOS_FOCUS) << "Focus GSL error:" << gsl_strerror(status);
98  return false;
99  }
100
101  do
102  {
103  iter++;
104  status = gsl_min_fminimizer_iterate(s);
105
106  m = gsl_min_fminimizer_x_minimum(s);
107  minPosition = gsl_min_fminimizer_x_lower(s);
108  maxPosition = gsl_min_fminimizer_x_upper(s);
109
110  status = gsl_min_test_interval(minPosition, maxPosition, 0.01, 0.0);
111
112  if (status == GSL_SUCCESS)
113  {
114  *position = m;
115  *value = polynomialFunction(m, this);
116  }
117  }
118  while (status == GSL_CONTINUE && iter < max_iter);
119
120  gsl_min_fminimizer_free(s);
121  return (status == GSL_SUCCESS);
122 }
123 } // namespace
124
Ekos is an advanced Astrophotography tool for Linux. It is based on a modular extensible framework to...
Definition: align.cpp:70
T * data()
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
QAction * solve(const QObject *recvr, const char *slot, QObject *parent)
int count(const T &value) const const
int size() const const
QVector< V > values(const QMultiHash< K, V > &c)
This file is part of the KDE documentation.