JKQTPlotter trunk/v5.0.0
an extensive Qt5+Qt6 Plotter framework (including a feature-richt plotter widget, a speed-optimized, but limited variant and a LaTeX equation renderer!), written fully in C/C++ and without external dependencies
Loading...
Searching...
No Matches
jkqtpevaluatedfunctionbase.h
1/*
2 Copyright (c) 2008-2024 Jan W. Krieger (<jan@jkrieger.de>)
3
4
5
6 This software is free software: you can redistribute it and/or modify
7 it under the terms of the GNU Lesser General Public License (LGPL) as published by
8 the Free Software Foundation, either version 2.1 of the License, or
9 (at your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU Lesser General Public License (LGPL) for more details.
15
16 You should have received a copy of the GNU Lesser General Public License (LGPL)
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20
21#ifndef jkqtpevaluatedfunctionbase_H
22#define jkqtpevaluatedfunctionbase_H
23
24
25#include <QString>
26#include <QPainter>
27#include <QPair>
28#include "jkqtplotter/graphs/jkqtpscatter.h"
29#include "jkqtplotter/jkqtpgraphsbasestylingmixins.h"
30#include "jkqtplotter/jkqtplotter_imexport.h"
31#include "jkqtcommon/jkqtpgeometrytools.h"
32#include <functional>
33
34
35
36
37/** \brief Base class for graph classes that evaluate a mathematical function (e.g. defined as a C-function),
38 * using an adaptive plotting algorithm from JKQTPAdaptiveFunctionGraphEvaluator
39 * \ingroup jkqtplotter_functiongraphs
40 *
41 * This class always plots a general 2D-graph \f$ [x,y]=\vec{f}(t) \f$ , which is calculated in dependence of
42 * a parameter \f$ t \f$ . This parametrization is general enough to cover the cases of parametric function, as well as
43 * x- and y-dependent function graphs:
44 * - plot a function \f$ f(x) \f$ i.e. the plot points will be \f$ [x, f(x)] \f$
45 * and the value rage will be the x-axis range. This is implemented by e.g. JKQTPXFunctionLineGraph.
46 * - plot a function \f$ f(y) \f$ i.e. the plot points will be \f$ [f(y), y] \f$
47 * and the value rage will be the y-axis range. This is implemented by e.g. JKQTPYFunctionLineGraph.
48 * - plot a function \f$ [x,y]=\vec{f}(t) \f$ i.e. the plot points will be \f$ \vec{f}(t) \f$
49 * and the value rage will be a user-defined range for \f$ gt \f$.
50 * This is implemented by e.g. JKQTPXYFunctionLineGraph.
51 * .
52 *
53 * In order to implement a special cas, one has to override/implement buildPlotFunctorSpec(), which
54 * returns a functor and a value-range that can represent the cases above.
55 *
56 *
57 * This class uses the intelligent plotting algorithm for functions, implemented in JKQTPAdaptiveFunctionGraphEvaluator.
58 * It starts by sampling the function at minSamples positions. Then each function interval is bisected recursively if
59 * necessary. To do so the function is evaluated at the mid point and the slopes \f$ \alpha_{\mbox{left}} \f$
60 * and \f$ \alpha_{\mbox{right}} \f$ of the two linear segments are compared. the midpoint is added
61 * to the graph if \f[ \left|\alpha_{\mbox{right}}-\alpha_{\mbox{left}}\right|>\mbox{slopeTolerance} \f]
62 * In addition all sampling points except minimum and maximum are beeing shifted by a random fraction their
63 * distance to the other points. This helps to prevent beats when sampling periodic functions.
64 *
65 * Finally the obtained data is cleaned up to reduce the amount of points, by deleting a point, when it leads to an
66 * angle between consecutive line-segments of less than dataCleanupMaxAllowedAngleDegree.
67 *
68 *
69 *
70 *
71 *
72 * \see JKQTPAdaptiveFunctionGraphEvaluator, JKQTPXFunctionLineGraph, JKQTPYFunctionLineGraph, JKQTPXYFunctionLineGraph
73 */
75 Q_OBJECT
76 public:
77
78 /** \brief class constructor */
80
81 /** \brief class constructor */
83
84 /** \brief class destructor */
86
87 /** \copydoc JKQTPPlotElement::getXMinMax() */
88 virtual bool getXMinMax(double& minx, double& maxx, double& smallestGreaterZero) override;
89 /** \copydoc JKQTPPlotElement::getYMinMax() */
90 virtual bool getYMinMax(double& miny, double& maxy, double& smallestGreaterZero) override;
91
92 /** \brief sets the params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
93 virtual void setParams(const QVector<double>& params);
94 /** \brief sets the params from a copy of the given array of length \a N */
95 void setCopiedParams(const double* params, int N);
96
97 /** \brief returns the currently set internal parameter vector */
98 const QVector<double>& getInternalParams() const;
99 /** \brief returns the currently set internal parameter vector */
100 QVector<double>& getInternalParams();
101 /** \copydoc parameterColumn */
103
104 /** \copydoc JKQTPGraph::usesColumn() */
105 virtual bool usesColumn(int c) const override;
106
107
108 /** \copydoc minSamples */
109 unsigned int getMinSamples() const;
110 /** \copydoc maxRefinementDegree */
111 unsigned int getMaxRefinementDegree() const;
112 /** \copydoc slopeTolerance */
113 double getSlopeTolerance() const;
114 /** \copydoc minPixelPerSample */
115 double getMinPixelPerSample() const;
116 /** \copydoc dataCleanupMaxAllowedAngleDegree */
118 /** \copydoc displaySamplePoints */
120 public Q_SLOTS:
121 /** \copydoc minSamples */
122 void setMinSamples(const unsigned int & __value);
123 /** \copydoc maxRefinementDegree */
124 void setMaxRefinementDegree(const unsigned int & __value);
125 /** \copydoc slopeTolerance */
126 void setSlopeTolerance(double __value);
127 /** \copydoc minPixelPerSample */
128 void setMinPixelPerSample(double __value);
129 /** \copydoc dataCleanupMaxAllowedAngleDegree */
131 /** \copydoc displaySamplePoints */
132 void setDisplaySamplePoints(bool __value);
133
134 /** \brief set an internal parameter vector as function parameters, initialized with {p1} */
135 void setParamsV(double p1);
136 /** \brief set an internal parameter vector as function parameters, initialized with {p1,p2} */
137 void setParamsV(double p1, double p2);
138 /** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3} */
139 void setParamsV(double p1, double p2, double p3);
140 /** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4} */
141 void setParamsV(double p1, double p2, double p3, double p4);
142 /** \brief set an internal parameter vector as function parameters, initialized with {p1,p2,p3,p4,p5} */
143 void setParamsV(double p1, double p2, double p3, double p4, double p5);
144
145 /** \copydoc parameterColumn */
146 void setParameterColumn(int __value);
147 /** \copydoc parameterColumn */
148 void setParameterColumn (size_t __value);
149
150 protected:
151 /** \brief specifies an internal plot functor \see buildPlotFunctor() */
153 /** brief construct an in-valid PlotFunctorSpec ... will become valid, by assigning a non-zero range and a plot-function */
155 /** \brief calculates the points \f$ [x,y] \f$ on the function graph, in dependence on
156 * a dependent parameter variable, could be e.g. \f$ [x, f(x)] \f$ for plotting
157 * a function \f$ f(x) \f$ over the x-axis. */
158 std::function<QPointF(double)> func;
159 /** \brief lower bound for the dependent parameter variable of func */
161 /** \brief upper bound for the dependent parameter variable of func */
162 double range_end;
163
164 bool isValid() const;
165 };
166 /** \brief this function returns a functor that is used to generate the plot data
167 * in coordinate space, based on a range of the dependent variable in coordinate space.
168 * In addition it also contains the value range over which to evaluate the functor PlotFunctorSpec::func
169 *
170 * This function has to be overridden by each class. Depending on the way that class defines
171 * the actual plot function, this function has to compose its return type in different ways.
172 * The three most common ways are:
173 * - plot a function \f$ f(x) \f$ i.e. the plot points will be \f$ [x, f(x)] \f$
174 * and the value rage will be the x-axis range. This is implemented by e.g. JKQTPXFunctionLineGraph.
175 * - plot a function \f$ f(y) \f$ i.e. the plot points will be \f$ [f(y), y] \f$
176 * and the value rage will be the y-axis range. This is implemented by e.g. JKQTPYFunctionLineGraph.
177 * - plot a function \f$ [x,y]=\vec{f}(t) \f$ i.e. the plot points will be \f$ \vec{f}(t) \f$
178 * and the value rage will be a user-defined range for \f$ gt \f$.
179 * This is implemented by e.g. JKQTPXYFunctionLineGraph.
180 * .
181 */
183
184 /** \brief ensure that current function parameters for a plot function (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams */
185 virtual void collectParameters();
186
187 /** \brief draw all the sample points in data as small symbols */
188 void drawSamplePoints(JKQTPEnhancedPainter &painter, QColor graphColor);
189
190 /** \brief fill the data array with data from the function plotFunction */
191 virtual void createPlotData( bool collectParams=true) ;
192
193 /** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the plot function */
195
196 /** \brief internal storage for the current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) */
197 QVector<double> iparams;
198
199 /** \brief plot data calculated by createPlotData(), i.e. the datapoints \f$ \mbox{transform}\left(x, y=f(x, \vec{p})\right) \f$ to be plotted */
200 QVector<QPointF> data;
201
202 /** \brief the minimum number of points to evaluate the function at */
203 unsigned int minSamples;
204 /** \brief the maximum number of recursive refinement steps
205 *
206 * each step bisects the interval \f$ [a, b] \f$ into two halfes. So the maximum number
207 * of points plotted at all are thus:
208 * \f[ \mbox{minSamples} \cdot 2^{\mbox{maxRefinementDegree}} \f]
209 */
211 /** \brief the tolerance for the difference of two subsequent slopes */
213 /** \brief create one sample at least every \a minPixelPerSample pixels */
215 /** \brief in the clean-up step of plot-data creation, a point is removed from the data, if
216 * it caused its neighboring line-segments to form an angle less than this value, given in degrees. */
218 /** \brief if true [default: off] display the points where the function has been sampled */
220};
221
222
223/** \brief extends JKQTPEvaluatedFunctionGraphBase with some basic properties (e.g. function parameters)
224 * for a second function that calculates an error (for drawing error indicators)
225 * \ingroup jkqtplotter_functiongraphs
226 *
227 * When implementing this, you will have to implement buildErrorFunctorSpec() in addition to
228 * JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec()!
229 *
230 * \see JKQTPEvaluatedFunctionGraphBase
231 */
233 Q_OBJECT
234public:
235 /** \brief class constructor */
237 /** \brief class constructor */
239 /** \brief class destructor */
241
242 /** \copydoc errorParameterColumn */
244
245 /** \brief returns the currently set internal parameter vector */
246 const QVector<double>& getInternalErrorParams() const;
247 /** \brief returns the currently set internal parameter vector */
248 QVector<double>& getInternalErrorParams();
249
250 /** \copydoc JKQTPGraph::usesColumn() */
251 virtual bool usesColumn(int c) const override;
252public Q_SLOTS:
253 /** \brief sets the error params as a pointer to an internal COPY of the given vector (not the data of the vector, as then the size would be unknown!!!) */
254 void setErrorParams(const QVector<double>& errorParams);
255 /** \copydoc errorParameterColumn */
256 void setErrorParameterColumn(int __value);
257 /** \copydoc errorParameterColumn */
258 void setErrorParameterColumn (size_t __value);
259
260 /** \brief set the internal error function parameters to {p1} */
261 void setErrorParamsV(double p1);
262 /** \brief set the internal error function parameters to {p1,p2} */
263 void setErrorParamsV(double p1, double p2);
264 /** \brief set the internal error function parameters to {p1,p2,p3} */
265 void setErrorParamsV(double p1, double p2, double p3);
266 /** \brief set the internal error function parameters to {p1,p2,p3,p4} */
267 void setErrorParamsV(double p1, double p2, double p3, double p4);
268 /** \brief set the internal error function parameters to {p1,p2,p3,p4,p5} */
269 void setErrorParamsV(double p1, double p2, double p3, double p4, double p5);
270
271protected:
272 /** \brief ensure that current function parameters for plotFunction (which may stem from different sources, as direct data, a datastore column ...) are stored in iparams and ierrorparams */
273 virtual void collectParameters() override;
274 /** \brief same as JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec(), but for error functions.
275 *
276 * The functor, returned by this function should calculate the error of the function (in x- and y-direction)
277 * for every value \f$ t \f$ of the actual function.
278 *
279 * The parameter range is the same as for JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec()
280 *
281 * \see JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec()
282 */
283 virtual std::function<QPointF(double)> buildErrorFunctorSpec() =0;
284
285 /** \brief if set, the values from this datatsore column are used for the parameters \c p1 , \c p2 , \c p3 , ... of the error plot function */
287 /** \brief internal storage for the current error function parameters for errorPlotFunction (which may stem from different sources, as direct data, a datastore column ...) */
288 QVector<double> ierrorparams;
289};
290
291
292#endif // jkqtpevaluatedfunctionbase_H
base class for 2D plotter classes (used by the plotter widget JKQTPlotter)
Definition jkqtpbaseplotter.h:394
this class extends the QPainter
Definition jkqtpenhancedpainter.h:33
Base class for graph classes that evaluate a mathematical function (e.g. defined as a C-function),...
Definition jkqtpevaluatedfunctionbase.h:74
void setMinSamples(const unsigned int &__value)
the minimum number of points to evaluate the function at
const QVector< double > & getInternalParams() const
returns the currently set internal parameter vector
bool getDisplaySamplePoints() const
if true [default: off] display the points where the function has been sampled
JKQTPEvaluatedFunctionGraphBase(JKQTBasePlotter *parent=nullptr)
class constructor
void setMaxRefinementDegree(const unsigned int &__value)
the maximum number of recursive refinement steps
unsigned int maxRefinementDegree
the maximum number of recursive refinement steps
Definition jkqtpevaluatedfunctionbase.h:210
void setDataCleanupMaxAllowedAngleDegree(double __value)
in the clean-up step of plot-data creation, a point is removed from the data, if it caused its neighb...
void setParamsV(double p1, double p2, double p3)
set an internal parameter vector as function parameters, initialized with {p1,p2,p3}
void setParameterColumn(int __value)
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
virtual bool usesColumn(int c) const override
returns true if the given column is used by the graph
double slopeTolerance
the tolerance for the difference of two subsequent slopes
Definition jkqtpevaluatedfunctionbase.h:212
double getMinPixelPerSample() const
create one sample at least every minPixelPerSample pixels
unsigned int getMaxRefinementDegree() const
the maximum number of recursive refinement steps
bool displaySamplePoints
if true [default: off] display the points where the function has been sampled
Definition jkqtpevaluatedfunctionbase.h:219
virtual PlotFunctorSpec buildPlotFunctorSpec()=0
this function returns a functor that is used to generate the plot data in coordinate space,...
int getParameterColumn() const
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
unsigned int getMinSamples() const
the minimum number of points to evaluate the function at
QVector< QPointF > data
plot data calculated by createPlotData(), i.e. the datapoints to be plotted
Definition jkqtpevaluatedfunctionbase.h:200
virtual void createPlotData(bool collectParams=true)
fill the data array with data from the function plotFunction
void setParamsV(double p1, double p2, double p3, double p4)
set an internal parameter vector as function parameters, initialized with {p1,p2,p3,...
virtual bool getYMinMax(double &miny, double &maxy, double &smallestGreaterZero) override
get the maximum and minimum y-value of the graph
void setParamsV(double p1, double p2)
set an internal parameter vector as function parameters, initialized with {p1,p2}
double minPixelPerSample
create one sample at least every minPixelPerSample pixels
Definition jkqtpevaluatedfunctionbase.h:214
void setSlopeTolerance(double __value)
the tolerance for the difference of two subsequent slopes
void setDisplaySamplePoints(bool __value)
if true [default: off] display the points where the function has been sampled
virtual ~JKQTPEvaluatedFunctionGraphBase()
class destructor
virtual void collectParameters()
ensure that current function parameters for a plot function (which may stem from different sources,...
void setParameterColumn(size_t __value)
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
virtual void setParams(const QVector< double > &params)
sets the params as a pointer to an internal COPY of the given vector (not the data of the vector,...
double getDataCleanupMaxAllowedAngleDegree() const
in the clean-up step of plot-data creation, a point is removed from the data, if it caused its neighb...
double getSlopeTolerance() const
the tolerance for the difference of two subsequent slopes
double dataCleanupMaxAllowedAngleDegree
in the clean-up step of plot-data creation, a point is removed from the data, if it caused its neighb...
Definition jkqtpevaluatedfunctionbase.h:217
void setParamsV(double p1)
set an internal parameter vector as function parameters, initialized with {p1}
JKQTPEvaluatedFunctionGraphBase(JKQTPlotter *parent)
class constructor
QVector< double > iparams
internal storage for the current function parameters for plotFunction (which may stem from different ...
Definition jkqtpevaluatedfunctionbase.h:197
void setCopiedParams(const double *params, int N)
sets the params from a copy of the given array of length N
QVector< double > & getInternalParams()
returns the currently set internal parameter vector
void setParamsV(double p1, double p2, double p3, double p4, double p5)
set an internal parameter vector as function parameters, initialized with {p1,p2,p3,...
int parameterColumn
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
Definition jkqtpevaluatedfunctionbase.h:194
void setMinPixelPerSample(double __value)
create one sample at least every minPixelPerSample pixels
virtual bool getXMinMax(double &minx, double &maxx, double &smallestGreaterZero) override
get the maximum and minimum x-value of the graph
void drawSamplePoints(JKQTPEnhancedPainter &painter, QColor graphColor)
draw all the sample points in data as small symbols
unsigned int minSamples
the minimum number of points to evaluate the function at
Definition jkqtpevaluatedfunctionbase.h:203
extends JKQTPEvaluatedFunctionGraphBase with some basic properties (e.g. function parameters) for a s...
Definition jkqtpevaluatedfunctionbase.h:232
void setErrorParameterColumn(int __value)
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
void setErrorParamsV(double p1, double p2, double p3, double p4, double p5)
set the internal error function parameters to {p1,p2,p3,p4,p5}
void setErrorParamsV(double p1, double p2)
set the internal error function parameters to {p1,p2}
virtual ~JKQTPEvaluatedFunctionWithErrorsGraphBase()
class destructor
void setErrorParamsV(double p1)
set the internal error function parameters to {p1}
void setErrorParamsV(double p1, double p2, double p3)
set the internal error function parameters to {p1,p2,p3}
virtual std::function< QPointF(double)> buildErrorFunctorSpec()=0
same as JKQTPEvaluatedFunctionGraphBase::buildPlotFunctorSpec(), but for error functions.
void setErrorParameterColumn(size_t __value)
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
JKQTPEvaluatedFunctionWithErrorsGraphBase(JKQTBasePlotter *parent=nullptr)
class constructor
int getErrorParameterColumn() const
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
virtual bool usesColumn(int c) const override
returns true if the given column is used by the graph
int errorParameterColumn
if set, the values from this datatsore column are used for the parameters p1 , p2 ,...
Definition jkqtpevaluatedfunctionbase.h:286
void setErrorParams(const QVector< double > &errorParams)
sets the error params as a pointer to an internal COPY of the given vector (not the data of the vecto...
QVector< double > & getInternalErrorParams()
returns the currently set internal parameter vector
void setErrorParamsV(double p1, double p2, double p3, double p4)
set the internal error function parameters to {p1,p2,p3,p4}
virtual void collectParameters() override
ensure that current function parameters for plotFunction (which may stem from different sources,...
const QVector< double > & getInternalErrorParams() const
returns the currently set internal parameter vector
JKQTPEvaluatedFunctionWithErrorsGraphBase(JKQTPlotter *parent)
class constructor
QVector< double > ierrorparams
internal storage for the current error function parameters for errorPlotFunction (which may stem from...
Definition jkqtpevaluatedfunctionbase.h:288
this virtual base class of the (data-column based) graphs, which are part of a JKQTPlotter plot and w...
Definition jkqtpgraphsbase.h:429
plotter widget for scientific plots (uses JKQTBasePlotter to do the actual drawing)
Definition jkqtplotter.h:364
#define JKQTPLOTTER_LIB_EXPORT
Definition jkqtplotter_imexport.h:89
specifies an internal plot functor
Definition jkqtpevaluatedfunctionbase.h:152
double range_start
lower bound for the dependent parameter variable of func
Definition jkqtpevaluatedfunctionbase.h:160
std::function< QPointF(double)> func
calculates the points on the function graph, in dependence on a dependent parameter variable,...
Definition jkqtpevaluatedfunctionbase.h:158
double range_end
upper bound for the dependent parameter variable of func
Definition jkqtpevaluatedfunctionbase.h:162