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
9namespace Ekos
10{
11
12PolynomialFit::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());
16 QVector<QPointF> values;
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
40PolynomialFit::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
51void 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
57double 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
67double 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
76bool 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.
Definition align.cpp:83
QAction * solve(const QObject *recvr, const char *slot, QObject *parent)
NETWORKMANAGERQT_EXPORT NetworkManager::Status status()
iterator begin()
qsizetype count() const const
pointer data()
iterator end()
qsizetype size() const const
value_type takeLast()
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Mon Nov 18 2024 12:16:40 by doxygen 1.12.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.