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
jkqtpmathtools.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 as published by
8 the Free Software Foundation, either version 3 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 for more details.
15
16 You should have received a copy of the GNU Lesser General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
18*/
19
20
21
22#ifndef jkqtpmathtools_H_INCLUDED
23#define jkqtpmathtools_H_INCLUDED
24#include "jkqtcommon/jkqtcommon_imexport.h"
25#include "jkqtcommon/jkqtpstringtools.h"
26#include <cmath>
27#include <limits>
28#include <QPoint>
29#include <QPointF>
30#include <QLineF>
31#include <QRectF>
32#include <vector>
33#include <QString>
34#include <functional>
35#include <type_traits>
36#include <QHashFunctions>
37
38#ifdef max
39# undef max
40#endif
41#ifdef min
42# undef min
43#endif
44
45/*! \brief \f$ \pi=3.14159... \f$
46 \ingroup jkqtptools_math_basic
47
48*/
49#ifdef M_PI
50# define JKQTPSTATISTICS_PI M_PI
51#else
52# define JKQTPSTATISTICS_PI 3.14159265358979323846
53#endif
54
55
56/*! \brief \f$ \sqrt{2\pi}=2.50662827463 \f$
57 \ingroup jkqtptools_math_basic
58
59*/
60#define JKQTPSTATISTICS_SQRT_2PI 2.50662827463
61
62
63/*! \brief \f$ \mbox{ln}(10)=2.30258509299404568402... \f$
64 \ingroup jkqtptools_math_basic
65
66*/
67#ifdef M_LN10
68# define JKQTPSTATISTICS_LN10 M_LN10
69#else
70# define JKQTPSTATISTICS_LN10 2.30258509299404568402
71#endif
72
73
74/** \brief double-value NotANumber
75 * \ingroup jkqtptools_math_basic
76 */
77#define JKQTP_DOUBLE_NAN (std::numeric_limits<double>::signaling_NaN())
78
79/** \brief float-value NotANumber
80 * \ingroup jkqtptools_math_basic
81 */
82#define JKQTP_FLOAT_NAN (std::numeric_limits<float>::signaling_NaN())
83
84/** \brief double-value NotANumber
85 * \ingroup jkqtptools_math_basic
86 */
87#define JKQTP_NAN JKQTP_DOUBLE_NAN
88
89/** \brief double-value epsilon
90 * \ingroup jkqtptools_math_basic
91 */
92#define JKQTP_DOUBLE_EPSILON (std::numeric_limits<double>::epsilon())
93
94/** \brief float-value epsilon
95 * \ingroup jkqtptools_math_basic
96 */
97#define JKQTP_FLOAT_EPSILON (std::numeric_limits<float>::epsilon())
98
99/** \brief double-value NotANumber
100 * \ingroup jkqtptools_math_basic
101 */
102#define JKQTP_EPSILON JKQTP_DOUBLE_EPSILON
103
104/** \brief converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
105 * \ingroup jkqtptools_math_basic
106 *
107 * This function uses static_cast<double>() by default, but certain specializations (e.g. for bool) are
108 * readily available.
109 *
110 * \callergraph
111 */
112template<typename T>
113inline constexpr double jkqtp_todouble(const T& d) {
114 return static_cast<double>(d);
115}
116
117
118/** \brief converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
119 * \ingroup jkqtptools_math_basic
120 *
121 * Specialisation of the generic template jkqtp_todouble() with (true -> 1.0, false -> 0.0)
122 *
123 * \callergraph
124 */
125template<>
126inline constexpr double jkqtp_todouble(const bool& d) {
127 return static_cast<double>((d)?1.0:0.0);
128}
129
130
131/** \brief round a double \a v using round() and convert it to a specified type T (static_cast!)
132 * \ingroup jkqtptools_math_basic
133 *
134 * \tparam T a numeric datatype (int, double, ...)
135 * \param v the value to round and cast
136 *
137 * this is equivalent to
138 * \code
139 * static_cast<T>(round(v));
140 * \endcode
141 *
142 * \callergraph
143 */
144template<typename T>
145inline T jkqtp_roundTo(const double& v) {
146 return static_cast<T>(round(v));
147}
148
149/** \brief round a double \a v using round() to a given number of decimal digits
150 * \ingroup jkqtptools_math_basic
151 *
152 * \param v the value to round and cast
153 * \param decDigits number of decimal digits, i.e. precision of the result
154 *
155 * this is equivalent to
156 * \code
157 * round(v * pow(10.0,(double)decDigits))/pow(10.0,(double)decDigits);
158 * \endcode
159 *
160 * \callergraph
161 */
162inline double jkqtp_roundToDigits(const double& v, const int decDigits) {
163 const double fac=pow(10.0,(double)decDigits);
164 return round(v * fac) / fac;
165}
166
167/** \brief round a double \a v using ceil() and convert it to a specified type T (static_cast!)
168 * \ingroup jkqtptools_math_basic
169 *
170 * \tparam T a numeric datatype (int, double, ...)
171 * \param v the value to ceil and cast
172 *
173 * this is equivalent to
174 * \code
175 * static_cast<T>(ceil(v));
176 * \endcode
177 *
178 * \callergraph
179 */
180template<typename T>
181inline T jkqtp_ceilTo(const double& v) {
182 return static_cast<T>(ceil(v));
183}
184
185/** \brief round a double \a v using trunc() and convert it to a specified type T (static_cast!)
186 * \ingroup jkqtptools_math_basic
187 *
188 * \tparam T a numeric datatype (int, double, ...)
189 * \param v the value to trunc and cast
190 *
191 * this is equivalent to
192 * \code
193 * static_cast<T>(trunc(v));
194 * \endcode
195 *
196 * \callergraph
197 */
198template<typename T>
199inline T jkqtp_truncTo(const double& v) {
200 return static_cast<T>(trunc(v));
201}
202
203/** \brief round a double \a v using floor() and convert it to a specified type T (static_cast!)
204 * \ingroup jkqtptools_math_basic
205 *
206 * \tparam T a numeric datatype (int, double, ...)
207 * \param v the value to floor and cast
208 *
209 * this is equivalent to
210 * \code
211 * static_cast<T>(floor(v));
212 * \endcode
213 *
214 * \callergraph
215 */
216template<typename T>
217inline T jkqtp_floorTo(const double& v) {
218 return static_cast<T>(floor(v));
219}
220
221
222/** \brief round a double \a v using round() and convert it to a specified type T (static_cast!).
223 * Finally the value is bounded to the range \a min ... \a max
224 * \ingroup jkqtptools_math_basic
225 *
226 * \tparam T a numeric datatype (int, double, ...)
227 * \param min minimum output value
228 * \param v the value to round and cast
229 * \param max maximum output value
230 *
231 * this is equivalent to
232 * \code
233 * qBound(min, static_cast<T>(round(v)), max);
234 * \endcode
235 */
236template<typename T>
237inline T jkqtp_boundedRoundTo(T min, const double& v, T max) {
238 return qBound(min, static_cast<T>(round(v)), max);
239}
240
241/** \brief round a double \a v using round() and convert it to a specified type T (static_cast!).
242 * Finally the value is bounded to the range \c std::numeric_limits<T>::min() ... \c std::numeric_limits<T>::max()
243 * \ingroup jkqtptools_math_basic
244 *
245 * \tparam T a numeric datatype (int, double, ...)
246 * \param v the value to round and cast
247 *
248 * this is equivalent to
249 * \code
250 * jkqtp_boundedRoundTo<T>(std::numeric_limits<T>::min(), v, std::numeric_limits<T>::max())
251 * \endcode
252 */
253template<typename T>
254inline T jkqtp_boundedRoundTo(const double& v) {
255 return jkqtp_boundedRoundTo<T>(std::numeric_limits<T>::min(), v, std::numeric_limits<T>::max());
256}
257
258/** \brief limits a value \a v to the given range \a min ... \a max
259 * \ingroup jkqtptools_math_basic
260 *
261 * \tparam T a numeric datatype (int, double, ...)
262 * \param min minimum output value
263 * \param v the value to round and cast
264 * \param max maximum output value
265 */
266template<typename T>
267inline T jkqtp_bounded(T min, T v, T max) {
268 return (v<min) ? min : ((v>max)? max : v);
269}
270
271/** \brief limits a value \a v to the range of the given type \a T , i.e. \c std::numeric_limits<T>::min() ... \c std::numeric_limits<T>::max()
272 * \ingroup jkqtptools_math_basic
273 *
274 * \tparam T a numeric datatype (int, double, ...) for the output
275 * \tparam TIn a numeric datatype (int, double, ...) or the input \a v
276 * \param v the value to round and cast
277 *
278 * \note As a special feature, this function detectes whether one of T or TIn are unsigned and then cmpares against a limit of 0 instead of \c std::numeric_limits<T>::min() .
279 */
280template<typename T, typename TIn>
281inline T jkqtp_bounded(TIn v) {
282 if (std::is_integral<T>::value && std::is_integral<TIn>::value && (std::is_signed<TIn>::value!=std::is_signed<T>::value)) {
283 return (v<TIn(0)) ? T(0) : ((v>std::numeric_limits<T>::max())? std::numeric_limits<T>::max() : static_cast<T>(v));
284 } else {
285 return (v<std::numeric_limits<T>::min()) ? std::numeric_limits<T>::min() : ((v>std::numeric_limits<T>::max())? std::numeric_limits<T>::max() : static_cast<T>(v));
286 }
287}
288
289/** \brief compare two floats \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
290 * \ingroup jkqtptools_math_basic */
291inline bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0f*JKQTP_FLOAT_EPSILON)
292{
293 return fabsf(a - b) <= epsilon;
294}
295
296/** \brief compare two doubles \a a and \a b for euqality, where any difference smaller than \a epsilon is seen as equality
297 * \ingroup jkqtptools_math_basic */
298inline bool jkqtp_approximatelyEqual(double a, double b, double epsilon=2.0*JKQTP_DOUBLE_EPSILON)
299{
300 return fabs(a - b) <= epsilon;
301}
302
303/** \brief compare two floats \a a and \a b for uneuqality, where any difference smaller than \a epsilon is seen as equality
304 * \ingroup jkqtptools_math_basic */
305inline bool jkqtp_approximatelyUnequal(float a, float b, float epsilon=2.0f*JKQTP_FLOAT_EPSILON)
306{
307 return fabsf(a - b) > epsilon;
308}
309
310/** \brief compare two doubles \a a and \a b for uneuqality, where any difference smaller than \a epsilon is seen as equality
311 * \ingroup jkqtptools_math_basic */
312inline bool jkqtp_approximatelyUnequal(double a, double b, double epsilon=2.0*JKQTP_DOUBLE_EPSILON)
313{
314 return fabs(a - b) > epsilon;
315}
316
317/** \brief returns the given value \a v (i.e. identity function)
318 * \ingroup jkqtptools_math_basic */
319template<typename T>
320inline T jkqtp_identity(const T& v) {
321 return v;
322}
323
324/** \brief returns the quare of the value \a v, i.e. \c v*v
325 * \ingroup jkqtptools_math_basic */
326template<typename T>
327inline T jkqtp_sqr(const T& v) {
328 return v*v;
329}
330
331
332/*! \brief 4-th power of a number
333 \ingroup jkqtptools_math_basic
334
335*/
336template <class T>
337inline T jkqtp_pow4(T x) {
338 const T xx=x*x;
339 return xx*xx;
340}
341
342/*! \brief 5-th power of a number
343 \ingroup jkqtptools_math_basic
344
345*/
346template <class T>
347inline T jkqtp_pow5(T x) {
348 const T xx=x*x;
349 return xx*xx*x;
350}
351
352/*! \brief cube of a number
353 \ingroup jkqtptools_math_basic
354
355*/
356template <class T>
357inline T jkqtp_cube(T x) {
358 return x*x*x;
359}
360
361
362/*! \brief calculates the sign of number \a x (-1 for x<0 and +1 for x>=0)
363 \ingroup jkqtptools_math_basic
364*/
365template <class T>
366inline T jkqtp_sign(T x) {
367 if (x<0) return -1;
368 else return 1;
369}
370
371/** \brief returns the inversely proportional value 1/\a v of \a v
372 * \ingroup jkqtptools_math_basic */
373template<typename T>
374inline T jkqtp_inverseProp(const T& v) {
375 return T(1.0)/v;
376}
377
378/** \brief returns the inversely proportional value 1/\a v of \a v and ensures that \f$ |v|\geq \mbox{absMinV} \f$
379 * \ingroup jkqtptools_math_basic */
380template<typename T>
381inline T jkqtp_inversePropSave(const T& v, const T& absMinV) {
382 T vv=v;
383 if (fabs(vv)<absMinV) vv=jkqtp_sign(v)*absMinV;
384 return T(1.0)/vv;
385}
386
387/** \brief returns the inversely proportional value 1/\a v of \a v and ensures that \f$ |v|\geq \mbox{absMinV} \f$, uses \c absMinV=std::numeric_limits<T>::epsilon()*100.0
388 * \ingroup jkqtptools_math_basic */
389template<typename T>
390inline T jkqtp_inversePropSaveDefault(const T& v) {
391 return jkqtp_inversePropSave<T>(v, std::numeric_limits<T>::epsilon()*100.0);
392}
393
394#if defined(JKQtPlotter_HAS_j0) || defined(JKQtPlotter_HAS__j0) || defined(DOXYGEN)
395
396 /*! \brief j0() function (without compiler issues)
397 \ingroup jkqtptools_math_basic
398
399 */
400 inline double jkqtp_j0(double x) {
401 #ifdef JKQtPlotter_HAS__j0
402 return _j0(x);
403 #elif defined(JKQtPlotter_HAS_j0)
404 return j0(x);
405 #endif
406 }
407
408 /*! \brief j1() function (without compiler issues)
409 \ingroup jkqtptools_math_basic
410
411 */
412 inline double jkqtp_j1(double x) {
413 #ifdef JKQtPlotter_HAS__j0
414 return _j1(x);
415 #elif defined(JKQtPlotter_HAS_j0)
416 return j1(x);
417 #endif
418 }
419#endif
420
421#if defined(JKQtPlotter_HAS_jn) || defined(JKQtPlotter_HAS__jn) || defined(DOXYGEN)
422 /*! \brief jn() function (without compiler issues)
423 \ingroup jkqtptools_math_basic
424
425 */
426 inline double jkqtp_jn(int n, double x) {
427 #ifdef JKQtPlotter_HAS__jn
428 return _jn(n,x);
429 #elif defined(JKQtPlotter_HAS_jn)
430 return jn(n,x);
431 #endif
432 }
433#endif
434
435
436#if defined(JKQtPlotter_HAS_y0) || defined(JKQtPlotter_HAS__y0) || defined(DOXYGEN)
437 /*! \brief y0() function (without compiler issues)
438 \ingroup jkqtptools_math_basic
439
440 */
441 inline double jkqtp_y0(double x) {
442 #ifdef JKQtPlotter_HAS__y0
443 return _y0(x);
444 #elif defined(JKQtPlotter_HAS_y0)
445 return y0(x);
446 #endif
447 }
448
449 /*! \brief y1() function (without compiler issues)
450 \ingroup jkqtptools_math_basic
451
452 */
453 inline double jkqtp_y1(double x) {
454 #ifdef JKQtPlotter_HAS__y0
455 return _y1(x);
456 #elif defined(JKQtPlotter_HAS_y0)
457 return y1(x);
458 #endif
459 }
460#endif
461#if defined(JKQtPlotter_HAS_yn) || defined(JKQtPlotter_HAS__yn) || defined(DOXYGEN)
462 /*! \brief yn() function (without compiler issues)
463 \ingroup jkqtptools_math_basic
464
465 */
466 inline double jkqtp_yn(int n, double x) {
467 #ifdef JKQtPlotter_HAS__yn
468 return _yn(n,x);
469 #elif defined(JKQtPlotter_HAS_yn)
470 return yn(n,x);
471 #endif
472 }
473#endif
474
475
476/** \brief calculate the distance between two QPointF points
477 * \ingroup jkqtptools_math_basic
478 *
479 */
480inline double jkqtp_distance(const QPointF& p1, const QPointF& p2){
481 return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
482}
483
484/** \brief calculate the distance between two QPoint points
485 * \ingroup jkqtptools_math_basic
486 *
487 */
488inline double jkqtp_distance(const QPoint& p1, const QPoint& p2){
489 return sqrt(jkqtp_sqr<double>(p1.x()-p2.x())+jkqtp_sqr<double>(p1.y()-p2.y()));
490}
491
492/** \brief check whether the dlotaing point number is OK (i.e. non-inf, non-NAN)
493 * \ingroup jkqtptools_math_basic
494 */
495template <typename T>
496inline bool JKQTPIsOKFloat(T v) {
497 return std::isfinite(v)&&(!std::isinf(v))&&(!std::isnan(v));
498}
499
500inline bool JKQTPIsOKFloat(const QPointF& v) {
501 return JKQTPIsOKFloat<qreal>(v.x()) && JKQTPIsOKFloat<qreal>(v.y());
502}
503
504inline bool JKQTPIsOKFloat(const QLineF& v) {
505 return JKQTPIsOKFloat<qreal>(v.x1()) && JKQTPIsOKFloat<qreal>(v.x2()) && JKQTPIsOKFloat<qreal>(v.y1()) && JKQTPIsOKFloat<qreal>(v.y2());
506}
507
508inline bool JKQTPIsOKFloat(const QRectF& v) {
509 return JKQTPIsOKFloat<qreal>(v.x()) && JKQTPIsOKFloat<qreal>(v.x()) && JKQTPIsOKFloat<qreal>(v.width()) && JKQTPIsOKFloat<qreal>(v.height());
510}
511
512/** \brief evaluates a gaussian propability density function
513 * \ingroup jkqtptools_math_basic
514 *
515 * \f[ f(x,\mu, \sigma)=\frac{1}{\sqrt{2\pi\sigma^2}}\cdot\exp\left(-\frac{(x-\mu)^2}{2\sigma^2}\right) \f]
516 */
517inline double jkqtp_gaussdist(double x, double mu=0.0, double sigma=1.0) {
518 return exp(-0.5*jkqtp_sqr(x-mu)/jkqtp_sqr(sigma))/sqrt(2.0*JKQTPSTATISTICS_PI*sigma*sigma);
519}
520
521/*! \brief evaluate a polynomial \f$ f(x)=\sum\limits_{i=0}^Pp_ix^i \f$ with \f$ p_i \f$ taken from the range \a firstP ... \a lastP
522 \ingroup jkqtptools_math_basic
523
524 \tparam PolyItP iterator for the polynomial coefficients
525 \param x where to evaluate
526 \param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
527 \param lastP points behind the last polynomial coefficient \f$ p_P \f$
528 \return value of polynomial \f$ f(x)=\sum\limits_{i=0}^Pp_ix^i \f$ at location \a x
529
530*/
531template <class PolyItP>
532inline double jkqtp_polyEval(double x, PolyItP firstP, PolyItP lastP) {
533 double v=0.0;
534 double xx=1.0;
535 for (auto itP=firstP; itP!=lastP; ++itP) {
536 v=v+(*itP)*xx;
537 xx=xx*x;
538 }
539 return v;
540}
541
542
543/*! \brief a C++-functor, which evaluates a polynomial
544 \ingroup jkqtptools_math_basic
545*/
547 std::vector<double> P;
548 template <class PolyItP>
549 inline JKQTPPolynomialFunctor(PolyItP firstP, PolyItP lastP) {
550 for (auto itP=firstP; itP!=lastP; ++itP) {
551 P.push_back(*itP);
552 }
553 }
554 inline double operator()(double x) const { return jkqtp_polyEval(x, P.begin(), P.end()); }
555
556};
557
558/*! \brief returns a C++-functor, which evaluates a polynomial
559 \ingroup jkqtptools_math_basic
560
561 \tparam PolyItP iterator for the polynomial coefficients
562 \param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
563 \param lastP points behind the last polynomial coefficient \f$ p_P \f$
564*/
565template <class PolyItP>
566inline std::function<double(double)> jkqtp_generatePolynomialModel(PolyItP firstP, PolyItP lastP) {
567 return JKQTPPolynomialFunctor(firstP, lastP);
568}
569
570/*! \brief Generates a LaTeX string for the polynomial model with the coefficients \a firstP ... \a lastP
571 \ingroup jkqtptools_math_basic
572
573 \tparam PolyItP iterator for the polynomial coefficients
574 \param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
575 \param lastP points behind the last polynomial coefficient \f$ p_P \f$
576 */
577template <class PolyItP>
578QString jkqtp_polynomialModel2Latex(PolyItP firstP, PolyItP lastP) {
579 QString str="f(x)=";
580 size_t p=0;
581 for (auto itP=firstP; itP!=lastP; ++itP) {
582 if (p==0) str+=jkqtp_floattolatexqstr(*itP, 3);
583 else {
584 if (*itP>=0) str+="+";
585 str+=QString("%2{\\cdot}x^{%1}").arg(p).arg(jkqtp_floattolatexqstr(*itP, 3));
586 }
587 p++;
588 }
589 return str;
590}
591
592
593
594/*! \brief Calculates a factorial \f$ n!=n\cdot(n-1)\cdot(n-2)\cdot...\cdot2\cdot1 \f$
595 \ingroup jkqtptools_math_basic
596
597 */
598template <class T=int>
599inline T jkqtp_factorial(T n) {
600 T result = 1;
601 for (T i =1; i <= n; i++){
602 result = result*i;
603 }
604 return result;
605}
606
607
608/*! \brief Calculates a combination \f$ \left(\stackrel{n}{k}\right)=\frac{n!}{k!\cdot(n-k)!} \f$
609 \ingroup jkqtptools_math_basic
610
611 */
612template <class T=int>
613inline T jkqtp_combination(T n, T k) {
614 if (n==k) return 1;
615 if (k==0) return 1;
616 if (k>n) return 0;
618}
619
620
621
622/*! \brief creates a functor that evaluates the Bernstein polynomial \f$ B_i^n(t):=\left(\stackrel{n}{i}\right)\cdot t^i\cdot(1-t)^{n-1},\ \ \ \ 0\leq i\leq n \f$
623 \ingroup jkqtptools_math_basic
624
625 */
626template <class T>
627std::function<T(T)> jkqtp_makeBernstein(int n, int i){
628 if (n==0 && i==0) return [=](T t) { return 1; };
629 if (n==1 && i==0) return [=](T t) { return (1.0-t); };
630 if (n==1 && i==1) return [=](T t) { return t; };
631 if (n==2 && i==0) return [=](T t) { return jkqtp_sqr(1.0-t); };
632 if (n==2 && i==1) return [=](T t) { return T(2.0)*t*(1.0-t); };
633 if (n==2 && i==2) return [=](T t) { return jkqtp_sqr(t); };
634 if (n==3 && i==0) return [=](T t) { return T(1)*jkqtp_cube(1.0-t); };
635 if (n==3 && i==1) return [=](T t) { return T(3)*t*jkqtp_sqr(1.0-t); };
636 if (n==3 && i==2) return [=](T t) { return T(3)*jkqtp_sqr(t)*(1.0-t); };
637 if (n==3 && i==3) return [=](T t) { return T(1)*jkqtp_cube(t); };
638 if (n==4 && i==0) return [=](T t) { return T(1)*jkqtp_pow4(1.0-t); };
639 if (n==4 && i==1) return [=](T t) { return T(4)*t*jkqtp_cube(1.0-t); };
640 if (n==4 && i==2) return [=](T t) { return T(6)*jkqtp_sqr(t)*jkqtp_sqr(1.0-t); };
641 if (n==4 && i==3) return [=](T t) { return T(4)*jkqtp_cube(t)*(1.0-t); };
642 if (n==4 && i==4) return [=](T t) { return T(1)*jkqtp_pow4(t); };
643 const T fac=jkqtp_combination<int64_t>(n,i);
644 return [=](T t) { return fac*pow(t,i)*pow(1.0-t,n-i); };
645}
646
647
648/*! \brief calculate the grwates common divisor (GCD) of \a a and \a b
649 \ingroup jkqtptools_math_basic
650
651 */
652JKQTCOMMON_LIB_EXPORT uint64_t jkqtp_gcd(uint64_t a, uint64_t b);
653
654
655/*! \brief calculates numeratur integer part \a intpart , \a num and denominator \a denom of a fraction, representing a given floating-point number \a input
656 \ingroup jkqtptools_math_basic
657
658 */
659JKQTCOMMON_LIB_EXPORT void jkqtp_estimateFraction(double input, int &sign, uint64_t &intpart, uint64_t& num, uint64_t& denom, unsigned int precision=9);
660
661/*! \brief returns the reversed containter \a l
662 \ingroup jkqtptools_math_basic
663
664 */
665template <class T>
666inline T jkqtp_reversed(const T& l) {
667 T reversed_l;
668 reversed_l.reserve(l.size());
669 std::reverse_copy(l.begin(), l.end(), std::back_inserter(reversed_l));
670 return reversed_l;
671}
672
673/*! \brief can be used to build a hash-values from several hash-values
674 \ingroup jkqtptools_math_basic
675
676 \code
677 std::size_t seed=0;
678 jkqtp_hash_combine(seed, valA);
679 jkqtp_hash_combine(seed, valB);
680 //...
681 // finally seed contains the combined hash
682 \endcode
683
684*/
685template <class T>
686inline void jkqtp_hash_combine(std::size_t& seed, const T& v)
687{
688 const auto hsh=::qHash(v,0);
689 seed ^= hsh + 0x9e3779b9 + (seed<<6) + (seed>>2);
690}
691
692/*! \brief can be used to build a hash-values from several hash-values
693 \ingroup jkqtptools_math_basic
694
695 \code
696 std::size_t seed=0;
697 jkqtp_combine_hash(seed, qHash(valA));
698 jkqtp_combine_hash(seed, qHash(valB));
699 //...
700 // finally seed contains the combined hash
701 \endcode
702
703*/
704inline void jkqtp_combine_hash(std::size_t& seed, std::size_t hsh)
705{
706 seed ^= hsh + 0x9e3779b9 + (seed<<6) + (seed>>2);
707}
708
709#endif // jkqtpmathtools_H_INCLUDED
size_t qHash(const JKQTBasePlotter::textSizeKey &data, size_t)
qHash()-specialization
Definition jkqtpbaseplotter.h:2820
#define JKQTCOMMON_LIB_EXPORT
Definition jkqtcommon_imexport.h:87
double jkqtp_y1(double x)
y1() function (without compiler issues)
Definition jkqtpmathtools.h:453
double jkqtp_gaussdist(double x, double mu=0.0, double sigma=1.0)
evaluates a gaussian propability density function
Definition jkqtpmathtools.h:517
T jkqtp_reversed(const T &l)
returns the reversed containter l
Definition jkqtpmathtools.h:666
double jkqtp_roundToDigits(const double &v, const int decDigits)
round a double v using round() to a given number of decimal digits
Definition jkqtpmathtools.h:162
T jkqtp_roundTo(const double &v)
round a double v using round() and convert it to a specified type T (static_cast!)
Definition jkqtpmathtools.h:145
T jkqtp_inverseProp(const T &v)
returns the inversely proportional value 1/v of v
Definition jkqtpmathtools.h:374
double jkqtp_j1(double x)
j1() function (without compiler issues)
Definition jkqtpmathtools.h:412
T jkqtp_truncTo(const double &v)
round a double v using trunc() and convert it to a specified type T (static_cast!)
Definition jkqtpmathtools.h:199
T jkqtp_sign(T x)
calculates the sign of number x (-1 for x<0 and +1 for x>=0)
Definition jkqtpmathtools.h:366
QString jkqtp_polynomialModel2Latex(PolyItP firstP, PolyItP lastP)
Generates a LaTeX string for the polynomial model with the coefficients firstP ......
Definition jkqtpmathtools.h:578
T jkqtp_bounded(T min, T v, T max)
limits a value v to the given range min ... max
Definition jkqtpmathtools.h:267
T jkqtp_pow4(T x)
4-th power of a number
Definition jkqtpmathtools.h:337
#define JKQTP_FLOAT_EPSILON
float-value epsilon
Definition jkqtpmathtools.h:97
double jkqtp_distance(const QPointF &p1, const QPointF &p2)
calculate the distance between two QPointF points
Definition jkqtpmathtools.h:480
#define JKQTP_DOUBLE_EPSILON
double-value epsilon
Definition jkqtpmathtools.h:92
T jkqtp_ceilTo(const double &v)
round a double v using ceil() and convert it to a specified type T (static_cast!)
Definition jkqtpmathtools.h:181
void jkqtp_hash_combine(std::size_t &seed, const T &v)
can be used to build a hash-values from several hash-values
Definition jkqtpmathtools.h:686
T jkqtp_factorial(T n)
Calculates a factorial .
Definition jkqtpmathtools.h:599
void jkqtp_combine_hash(std::size_t &seed, std::size_t hsh)
can be used to build a hash-values from several hash-values
Definition jkqtpmathtools.h:704
constexpr double jkqtp_todouble(const T &d)
converts a boolean to a double, is used to convert boolean to double by JKQTPDatastore
Definition jkqtpmathtools.h:113
JKQTCOMMON_LIB_EXPORT void jkqtp_estimateFraction(double input, int &sign, uint64_t &intpart, uint64_t &num, uint64_t &denom, unsigned int precision=9)
calculates numeratur integer part intpart , num and denominator denom of a fraction,...
double jkqtp_j0(double x)
j0() function (without compiler issues)
Definition jkqtpmathtools.h:400
T jkqtp_inversePropSave(const T &v, const T &absMinV)
returns the inversely proportional value 1/v of v and ensures that
Definition jkqtpmathtools.h:381
double jkqtp_y0(double x)
y0() function (without compiler issues)
Definition jkqtpmathtools.h:441
std::function< T(T)> jkqtp_makeBernstein(int n, int i)
creates a functor that evaluates the Bernstein polynomial
Definition jkqtpmathtools.h:627
bool jkqtp_approximatelyUnequal(float a, float b, float epsilon=2.0f *JKQTP_FLOAT_EPSILON)
compare two floats a and b for uneuqality, where any difference smaller than epsilon is seen as equal...
Definition jkqtpmathtools.h:305
T jkqtp_boundedRoundTo(T min, const double &v, T max)
round a double v using round() and convert it to a specified type T (static_cast!)....
Definition jkqtpmathtools.h:237
T jkqtp_pow5(T x)
5-th power of a number
Definition jkqtpmathtools.h:347
JKQTCOMMON_LIB_EXPORT uint64_t jkqtp_gcd(uint64_t a, uint64_t b)
calculate the grwates common divisor (GCD) of a and b
std::function< double(double)> jkqtp_generatePolynomialModel(PolyItP firstP, PolyItP lastP)
returns a C++-functor, which evaluates a polynomial
Definition jkqtpmathtools.h:566
T jkqtp_sqr(const T &v)
returns the quare of the value v, i.e. v*v
Definition jkqtpmathtools.h:327
T jkqtp_cube(T x)
cube of a number
Definition jkqtpmathtools.h:357
double jkqtp_jn(int n, double x)
jn() function (without compiler issues)
Definition jkqtpmathtools.h:426
T jkqtp_floorTo(const double &v)
round a double v using floor() and convert it to a specified type T (static_cast!)
Definition jkqtpmathtools.h:217
bool jkqtp_approximatelyEqual(float a, float b, float epsilon=2.0f *JKQTP_FLOAT_EPSILON)
compare two floats a and b for euqality, where any difference smaller than epsilon is seen as equalit...
Definition jkqtpmathtools.h:291
T jkqtp_combination(T n, T k)
Calculates a combination .
Definition jkqtpmathtools.h:613
#define JKQTPSTATISTICS_PI
Definition jkqtpmathtools.h:52
T jkqtp_inversePropSaveDefault(const T &v)
returns the inversely proportional value 1/v of v and ensures that , uses absMinV=std::numeric_limits...
Definition jkqtpmathtools.h:390
bool JKQTPIsOKFloat(T v)
check whether the dlotaing point number is OK (i.e. non-inf, non-NAN)
Definition jkqtpmathtools.h:496
double jkqtp_polyEval(double x, PolyItP firstP, PolyItP lastP)
evaluate a polynomial with taken from the range firstP ... lastP
Definition jkqtpmathtools.h:532
T jkqtp_identity(const T &v)
returns the given value v (i.e. identity function)
Definition jkqtpmathtools.h:320
double jkqtp_yn(int n, double x)
yn() function (without compiler issues)
Definition jkqtpmathtools.h:466
JKQTCOMMON_LIB_EXPORT QString jkqtp_floattolatexqstr(double data, int past_comma=5, bool remove_trail0=false, double belowIsZero=1e-16, double minNoExponent=1e-3, double maxNoExponent=1e4, bool ensurePlusMinus=false)
convert a double to a string, encoding powers of ten as exponent in LaTeX notation (e....
a C++-functor, which evaluates a polynomial
Definition jkqtpmathtools.h:546
JKQTPPolynomialFunctor(PolyItP firstP, PolyItP lastP)
Definition jkqtpmathtools.h:549
double operator()(double x) const
Definition jkqtpmathtools.h:554
std::vector< double > P
Definition jkqtpmathtools.h:547