moved basic polynomial functions to jkqtpmathtools.h

renamed jkqtptoolsdebugging.h to jkqtpdebuggingtools.h
added jkqtpstatWeightedCoefficientOfDetermination()
This commit is contained in:
jkriege2 2019-06-02 15:38:09 +02:00
parent ad38ac47f2
commit 9ff9076e63
12 changed files with 148 additions and 98 deletions

View File

@ -17,6 +17,7 @@ functionaly groups.
\defgroup jkqtptools_math_basic Mathematical Functions & Tools
\ingroup jkqtptools_math
This group assembles a variety of mathematical tool functions that are used in different places.
\defgroup jkqtptools_math_array Data Array Tools

View File

@ -314,10 +314,10 @@ To demonstrate this function we first generate data from a poylnomial model (wit
size_t colPolyY=datastore1->addColumn("polynomial data, y");
for (double x=-10; x<=10; x++) {
datastore1->appendToColumn(colPolyX, x);
datastore1->appendToColumn(colPolyY, jkqtpstatPolyEval(x, pPoly.begin(), pPoly.end())+d1(gen));
datastore1->appendToColumn(colPolyY, jkqtp_polyEval(x, pPoly.begin(), pPoly.end())+d1(gen));
}
```
The function `jkqtpstatPolyEval()` is used to evaluate a given polynomial (coefficients in `pPoly`) at a position `x`.
The function `jkqtp_polyEval()` is used to evaluate a given polynomial (coefficients in `pPoly`) at a position `x`.
The generated data is visualized with scatter-plots:
```.cpp
@ -325,9 +325,9 @@ The generated data is visualized with scatter-plots:
plot6->addGraph(graphP=new JKQTPXYLineGraph(plot6));
graphP->setXYColumns(colPolyX, colPolyY);
graphP->setDrawLine(false);
graphP->setTitle(QString("data $%1+\\mathcal{N}(0,50)$").arg(jkqtpstatPolynomialModel2Latex(pPoly.begin(), pPoly.end())));
graphP->setTitle(QString("data $%1+\\mathcal{N}(0,50)$").arg(jkqtp_polynomialModel2Latex(pPoly.begin(), pPoly.end())));
```
Here the function `jkqtpstatPolynomialModel2Latex()` generates a string from a polynomial model.
Here the function `jkqtp_polynomialModel2Latex()` generates a string from a polynomial model.
Now we can call `jkqtpstatPolyFit()` to fit different polynomial regression models to the data:
```.cpp
@ -336,11 +336,11 @@ Now we can call `jkqtpstatPolyFit()` to fit different polynomial regression mode
JKQTPXFunctionLineGraph* gPoly;
jkqtpstatPolyFit(datastore1->begin(colPolyX), datastore1->end(colPolyX), datastore1->begin(colPolyY), datastore1->end(colPolyY), p, std::back_inserter(pFit));
plot6->addGraph(gPoly=new JKQTPXFunctionLineGraph(plot6));
gPoly->setPlotFunctionFunctor(jkqtpstatGeneratePolynomialModel(pFit.begin(), pFit.end()));
gPoly->setTitle(QString("regression: $%1$").arg(jkqtpstatPolynomialModel2Latex(pFit.begin(), pFit.end())));
gPoly->setPlotFunctionFunctor(jkqtp_generatePolynomialModel(pFit.begin(), pFit.end()));
gPoly->setTitle(QString("regression: $%1$").arg(jkqtp_polynomialModel2Latex(pFit.begin(), pFit.end())));
}
```
Each model is also ploted using a `JKQTPXFunctionLineGraph`. The plot function assigned to these `JKQTPXFunctionLineGraph` is generated by calling `jkqtpstatGeneratePolynomialModel()`, which returns a C++-functor for a polynomial.
Each model is also ploted using a `JKQTPXFunctionLineGraph`. The plot function assigned to these `JKQTPXFunctionLineGraph` is generated by calling `jkqtp_generatePolynomialModel()`, which returns a C++-functor for a polynomial.
The resulting plots look like this (without added gaussian noise):

View File

@ -274,22 +274,22 @@ int main(int argc, char* argv[])
size_t colPolyY=datastore1->addColumn("polynomial data, y");
for (double x=-10; x<=10; x++) {
datastore1->appendToColumn(colPolyX, x);
datastore1->appendToColumn(colPolyY, jkqtpstatPolyEval(x, pPoly.begin(), pPoly.end())+d1(gen)*50.0);
datastore1->appendToColumn(colPolyY, jkqtp_polyEval(x, pPoly.begin(), pPoly.end())+d1(gen)*50.0);
}
// we visualize this data with a simple scatter graph:
JKQTPXYLineGraph* graphP;
plot6->addGraph(graphP=new JKQTPXYLineGraph(plot6));
graphP->setXYColumns(colPolyX, colPolyY);
graphP->setDrawLine(false);
graphP->setTitle(QString("data $%1+\\mathcal{N}(0,50)$").arg(jkqtpstatPolynomialModel2Latex(pPoly.begin(), pPoly.end())));
graphP->setTitle(QString("data $%1+\\mathcal{N}(0,50)$").arg(jkqtp_polynomialModel2Latex(pPoly.begin(), pPoly.end())));
// 6.2. now we can fit polynomials with different number of coefficients:
for (size_t p=0; p<=5; p++) {
std::vector<double> pFit;
JKQTPXFunctionLineGraph* gPoly;
jkqtpstatPolyFit(datastore1->begin(colPolyX), datastore1->end(colPolyX), datastore1->begin(colPolyY), datastore1->end(colPolyY), p, std::back_inserter(pFit));
plot6->addGraph(gPoly=new JKQTPXFunctionLineGraph(plot6));
gPoly->setPlotFunctionFunctor(jkqtpstatGeneratePolynomialModel(pFit.begin(), pFit.end()));
gPoly->setTitle(QString("regression: $%1$").arg(jkqtpstatPolynomialModel2Latex(pFit.begin(), pFit.end())));
gPoly->setPlotFunctionFunctor(jkqtp_generatePolynomialModel(pFit.begin(), pFit.end()));
gPoly->setTitle(QString("regression: $%1$").arg(jkqtp_polynomialModel2Latex(pFit.begin(), pFit.end())));
}
// 6.3. of course also the "adaptor" shortcuts are available:
//for (size_t p=0; p<=5; p++) {

View File

@ -21,7 +21,7 @@ Copyright (c) 2008-2019 Jan W. Krieger (<jan@jkrieger.de>)
#include "jkqtcommon/jkqtptoolsdebugging.h"
#include "jkqtcommon/jkqtpdebuggingtools.h"
#include <QDebug>
#include <QApplication>

View File

@ -22,11 +22,14 @@
#ifndef jkqtpmathtools_H_INCLUDED
#define jkqtpmathtools_H_INCLUDED
#include "jkqtcommon/jkqtp_imexport.h"
#include "jkqtcommon/jkqtpstringtools.h"
#include <cmath>
#include <limits>
#include <QPoint>
#include <QPointF>
#include <vector>
#include <QString>
#include <functional>
@ -279,4 +282,74 @@ inline double jkqtp_gaussdist(double x, double mu=0.0, double sigma=1.0) {
return exp(-0.5*jkqtp_sqr(x-mu)/jkqtp_sqr(sigma))/sqrt(2.0*M_PI*sigma*sigma);
}
/*! \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
\ingroup jkqtptools_math_basic
\tparam PolyItP iterator for the polynomial coefficients
\param x where to evaluate
\param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
\param lastP points behind the last polynomial coefficient \f$ p_P \f$
\return value of polynomial \f$ f(x)=\sum\limits_{i=0}^Pp_ix^i \f$ at location \a x
*/
template <class PolyItP>
inline double jkqtp_polyEval(double x, PolyItP firstP, PolyItP lastP) {
double v=0.0;
double xx=1.0;
for (auto itP=firstP; itP!=lastP; ++itP) {
v=v+(*itP)*xx;
xx=xx*x;
}
return v;
}
/*! \brief a C++-functor, which evaluates a polynomial
\ingroup jkqtptools_math_basic
*/
struct JKQTPPolynomialFunctor {
std::vector<double> P;
template <class PolyItP>
inline JKQTPPolynomialFunctor(PolyItP firstP, PolyItP lastP) {
for (auto itP=firstP; itP!=lastP; ++itP) {
P.push_back(*itP);
}
}
inline double operator()(double x) const { return jkqtp_polyEval(x, P.begin(), P.end()); }
};
/*! \brief returns a C++-functor, which evaluates a polynomial
\ingroup jkqtptools_math_basic
\tparam PolyItP iterator for the polynomial coefficients
\param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
\param lastP points behind the last polynomial coefficient \f$ p_P \f$
*/
template <class PolyItP>
inline std::function<double(double)> jkqtp_generatePolynomialModel(PolyItP firstP, PolyItP lastP) {
return JKQTPPolynomialFunctor(firstP, lastP);
}
/*! \brief Generates a LaTeX string for the polynomial model with the coefficients \a firstP ... \a lastP
\ingroup jkqtptools_math_basic
\tparam PolyItP iterator for the polynomial coefficients
\param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
\param lastP points behind the last polynomial coefficient \f$ p_P \f$
*/
template <class PolyItP>
QString jkqtp_polynomialModel2Latex(PolyItP firstP, PolyItP lastP) {
QString str="f(x)=";
size_t p=0;
for (auto itP=firstP; itP!=lastP; ++itP) {
if (p==0) str+=jkqtp_floattolatexqstr(*itP, 3);
else {
if (*itP>=0) str+="+";
str+=QString("%2{\\cdot}x^{%1}").arg(p).arg(jkqtp_floattolatexqstr(*itP, 3));
}
p++;
}
return str;
}
#endif // jkqtpmathtools_H_INCLUDED

View File

@ -132,7 +132,7 @@ std::function<double (double)> jkqtpStatGenerateRegressionModel(JKQTPStatRegress
std::pair<std::function<double (double)>, std::function<double (double)> > jkqtpStatGenerateTransformation(JKQTPStatRegressionModelType type) {
auto logF=[](double x)->double { return log(x); };
auto expF=[](double x)->double { return exp(x); };
//auto expF=[](double x)->double { return exp(x); };
auto idF=&jkqtp_identity<double>;
switch(type) {
case JKQTPStatRegressionModelType::Linear: return std::pair<std::function<double(double)>,std::function<double(double)> >(idF, idF);

View File

@ -37,7 +37,7 @@
#include "jkqtcommon/jkqtp_imexport.h"
#include "jkqtcommon/jkqtplinalgtools.h"
#include "jkqtcommon/jkqtparraytools.h"
#include "jkqtcommon/jkqtptoolsdebugging.h"
#include "jkqtcommon/jkqtpdebuggingtools.h"
@ -2209,6 +2209,7 @@ inline void jkqtpstatWeightedRegression(JKQTPStatRegressionModelType type, Input
/*! \brief fits (in a least-squares sense) a polynomial \f$ f(x)=\sum\limits_{i=0}^Pp_ix^i \f$ of order P to a set of N data pairs \f$ (x_i,y_i) \f$
\ingroup jkqtptools_math_statistics_poly
\ingroup jkqtptools_math_statistics_regression
\tparam InputItX standard iterator type of \a firstX and \a lastX.
\tparam InputItY standard iterator type of \a firstY and \a lastY.
@ -2322,82 +2323,9 @@ inline void jkqtpstatPolyFit(InputItX firstX, InputItX lastX, InputItY firstY, I
}
/*! \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
\ingroup jkqtptools_math_statistics_poly
\tparam PolyItP iterator for the polynomial coefficients
\param x where to evaluate
\param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
\param lastP points behind the last polynomial coefficient \f$ p_P \f$
\return value of polynomial \f$ f(x)=\sum\limits_{i=0}^Pp_ix^i \f$ at location \a x
*/
template <class PolyItP>
inline double jkqtpstatPolyEval(double x, PolyItP firstP, PolyItP lastP) {
double v=0.0;
double xx=1.0;
for (auto itP=firstP; itP!=lastP; ++itP) {
v=v+(*itP)*xx;
xx=xx*x;
}
return v;
}
/*! \brief a C++-functor, which evaluates a polynomial
\ingroup jkqtptools_math_statistics_poly
*/
struct JKQTPStatPolynomialFunctor {
std::vector<double> P;
template <class PolyItP>
inline JKQTPStatPolynomialFunctor(PolyItP firstP, PolyItP lastP) {
for (auto itP=firstP; itP!=lastP; ++itP) {
P.push_back(*itP);
}
}
inline double operator()(double x) const { return jkqtpstatPolyEval(x, P.begin(), P.end()); }
};
/*! \brief returns a C++-functor, which evaluates a polynomial
\ingroup jkqtptools_math_statistics_poly
\tparam PolyItP iterator for the polynomial coefficients
\param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
\param lastP points behind the last polynomial coefficient \f$ p_P \f$
*/
template <class PolyItP>
inline std::function<double(double)> jkqtpstatGeneratePolynomialModel(PolyItP firstP, PolyItP lastP) {
return JKQTPStatPolynomialFunctor(firstP, lastP);
}
/*! \brief Generates a LaTeX string for the polynomial model with the coefficients \a firstP ... \a lastP
\ingroup jkqtptools_math_statistics_regression
\tparam PolyItP iterator for the polynomial coefficients
\param firstP points to the first polynomial coefficient \f$ p_1 \f$ (i.e. the offset with \f$ x^0 \f$ )
\param lastP points behind the last polynomial coefficient \f$ p_P \f$
*/
template <class PolyItP>
QString jkqtpstatPolynomialModel2Latex(PolyItP firstP, PolyItP lastP) {
QString str="f(x)=";
size_t p=0;
for (auto itP=firstP; itP!=lastP; ++itP) {
if (p==0) str+=jkqtp_floattolatexqstr(*itP, 3);
else {
if (*itP>=0) str+="+";
str+=QString("%2{\\cdot}x^{%1}").arg(p).arg(jkqtp_floattolatexqstr(*itP, 3));
}
p++;
}
return str;
}
/*! \brief calculates the coefficient of determination \f$ R^2 \f$ for a set of measurements \f$ (x_i,y_i) \f$ with a fit function \f$ f(x) \f$
\ingroup jkqtptools_math_statistics_poly
\ingroup jkqtptools_math_statistics_regression
\tparam InputItX standard iterator type of \a firstX and \a lastX.
\tparam InputItY standard iterator type of \a firstY and \a lastY.
@ -2434,10 +2362,58 @@ inline double jkqtpstatCoefficientOfDetermination(InputItX firstX, InputItX last
}
/*! \brief calculates the weightedcoefficient of determination \f$ R^2 \f$ for a set of measurements \f$ (x_i,y_i,w_i) \f$ with a fit function \f$ f(x) \f$
\ingroup jkqtptools_math_statistics_regression
\tparam InputItX standard iterator type of \a firstX and \a lastX.
\tparam InputItY standard iterator type of \a firstY and \a lastY.
\tparam InputItW standard iterator type of \a firstW and \a lastW.
\param firstX iterator pointing to the first item in the x-dataset to use \f$ x_1 \f$
\param lastX iterator pointing behind the last item in the x-dataset to use \f$ x_N \f$
\param firstY iterator pointing to the first item in the y-dataset to use \f$ y_1 \f$
\param lastY iterator pointing behind the last item in the y-dataset to use \f$ y_N \f$
\param firstW iterator pointing to the first item in the weight-dataset to use \f$ w_1 \f$
\param lastW iterator pointing behind the last item in the weight-dataset to use \f$ w_N \f$
\param f function \f$ f(x) \f$, result of a fit to the data
\param fWeightDataToWi an optional function, which is applied to the data from \a firstW ... \a lastW to convert them to weight, i.e. \c wi=fWeightDataToWi(*itW)
e.g. if you use data used to draw error bars, you can use jkqtp_inversePropSaveDefault(). The default is jkqtp_identity(), which just returns the values.
In the case of jkqtp_inversePropSaveDefault(), a datapoint x,y, has a large weight, if it's error is small and in the case if jkqtp_identity() it's weight
is directly proportional to the given value.
\return weighted coeffcicient of determination \f[ R^2=1-\frac{\sum_iw_i^2\bigl[y_i-f(x_i)\bigr]^2}{\sum_iw_i^2\bigl[y_i-\overline{y}\bigr]^2} \f] where \f[ \overline{y}=\frac{1}{N}\cdot\sum_iw_iy_i \f]
with \f[ \sum_iw_i=1 \f]
\see https://en.wikipedia.org/wiki/Coefficient_of_determination
*/
template <class InputItX, class InputItY, class InputItW>
inline double jkqtpstatWeightedCoefficientOfDetermination(InputItX firstX, InputItX lastX, InputItY firstY, InputItY lastY, InputItW firstW, InputItW lastW, std::function<double(double)> f, std::function<double(double)> fWeightDataToWi=&jkqtp_identity<double>) {
auto itX=firstX;
auto itY=firstY;
auto itW=firstW;
const double yMean=jkqtpstatWeightedAverage(firstX,lastX,firstW);
double SSres=0;
double SStot=0;
for (; itX!=lastX && itY!=lastY && itW!=lastW; ++itX, ++itY, ++itW) {
const double fit_x=jkqtp_todouble(*itX);
const double fit_y=jkqtp_todouble(*itY);
const double fit_w2=jkqtp_sqr(fWeightDataToWi(jkqtp_todouble(*itW)));
if (JKQTPIsOKFloat(fit_x) && JKQTPIsOKFloat(fit_y) && JKQTPIsOKFloat(fit_w2)) {
SSres+=(fit_w2*jkqtp_sqr(fit_y-f(fit_x)));
SStot+=(fit_w2*jkqtp_sqr(fit_y-yMean));
}
}
return 1.0-SSres/SStot;
}
/*! \brief calculates the sum of deviations \f$ \chi^2 \f$ for a set of measurements \f$ (x_i,y_i) \f$ with a fit function \f$ f(x) \f$
\ingroup jkqtptools_math_statistics_poly
\ingroup jkqtptools_math_statistics_regression
\tparam InputItX standard iterator type of \a firstX and \a lastX.
\tparam InputItY standard iterator type of \a firstY and \a lastY.
@ -2474,7 +2450,7 @@ inline double jkqtpstatSumOfDeviations(InputItX firstX, InputItX lastX, InputItY
/*! \brief calculates the weighted sum of deviations \f$ \chi^2 \f$ for a set of measurements \f$ (x_i,y_i,w_i) \f$ with a fit function \f$ f(x) \f$
\ingroup jkqtptools_math_statistics_poly
\ingroup jkqtptools_math_statistics_regression
\tparam InputItX standard iterator type of \a firstX and \a lastX.
\tparam InputItY standard iterator type of \a firstY and \a lastY.

View File

@ -17,7 +17,7 @@ isEmpty(JKQTP_COMMON_PRI_INCLUDED) {
}
HEADERS += $$PWD/jkqtcommon/jkqtp_imexport.h \
$$PWD/jkqtcommon/jkqtptoolsdebugging.h \
$$PWD/jkqtcommon/jkqtpdebuggingtools.h \
$$PWD/jkqtcommon/jkqtpmathtools.h \
$$PWD/jkqtcommon/jkqtpalgorithms.h \
$$PWD/jkqtcommon/jkqtpstringtools.h \
@ -33,7 +33,7 @@ isEmpty(JKQTP_COMMON_PRI_INCLUDED) {
$$PWD/jkqtcommon/jkqtpstatisticstools.h
SOURCES += $$PWD/jkqtcommon/jkqtptoolsdebugging.cpp \
SOURCES += $$PWD/jkqtcommon/jkqtpdebuggingtools.cpp \
$$PWD/jkqtcommon/jkqtpmathtools.cpp \
$$PWD/jkqtcommon/jkqtpalgorithms.cpp \
$$PWD/jkqtcommon/jkqtpstringtools.cpp \

View File

@ -21,7 +21,7 @@
#include "jkqtcommon/jkqtp_imexport.h"
#include "jkqtplotter/jkqtptools.h"
#include "jkqtcommon/jkqtptoolsdebugging.h"
#include "jkqtcommon/jkqtpdebuggingtools.h"
#include <vector>
#include <cmath>
#include <iostream>

View File

@ -20,7 +20,7 @@
#include "jkqtcommon/jkqtp_imexport.h"
#include "jkqtcommon/jkqtpstatisticstools.h"
#include "jkqtcommon/jkqtptoolsdebugging.h"
#include "jkqtcommon/jkqtpdebuggingtools.h"
#include "jkqtplotter/jkqtpgraphsbase.h"
#include "jkqtplotter/jkqtpgraphsbaseerrors.h"
#include "jkqtplotter/jkqtpgraphsboxplot.h"
@ -853,7 +853,7 @@ inline JKQTPXFunctionLineGraph* jkqtpstatAddLinearWeightedRegression(JKQTBasePlo
JKQTPXFunctionLineGraph* g=new JKQTPXFunctionLineGraph(plotter);
g->setSpecialFunction(JKQTPXFunctionLineGraph::SpecialFunction::Line);
g->setParamsV(cA, cB);
g->setTitle(QString("weighted regression: $f(x) = %1%2{\\cdot}x, \\chi^2=%4, R^2=%3$").arg(jkqtp_floattolatexqstr(cA, 2, true, 1e-16,1e-2, 1e4,false)).arg(jkqtp_floattolatexqstr(cB, 2, true, 1e-16,1e-2, 1e4,true)).arg(jkqtp_floattolatexqstr(jkqtpstatCoefficientOfDetermination(firstX,lastX,firstY,lastY,jkqtpStatGenerateRegressionModel(JKQTPStatRegressionModelType::Linear, cA, cB)),3)).arg(jkqtp_floattolatexqstr(jkqtpstatWeightedSumOfDeviations(firstX,lastX,firstY,lastY,firstW,lastW,jkqtpStatGenerateRegressionModel(JKQTPStatRegressionModelType::Linear, cA, cB),fWeightDataToWi),3)));
g->setTitle(QString("weighted regression: $f(x) = %1%2{\\cdot}x, \\chi^2=%4, R^2=%3$").arg(jkqtp_floattolatexqstr(cA, 2, true, 1e-16,1e-2, 1e4,false)).arg(jkqtp_floattolatexqstr(cB, 2, true, 1e-16,1e-2, 1e4,true)).arg(jkqtp_floattolatexqstr(jkqtpstatWeightedCoefficientOfDetermination(firstX,lastX,firstY,lastY,firstW,lastW,jkqtpStatGenerateRegressionModel(JKQTPStatRegressionModelType::Linear, cA, cB),fWeightDataToWi),3)).arg(jkqtp_floattolatexqstr(jkqtpstatWeightedSumOfDeviations(firstX,lastX,firstY,lastY,firstW,lastW,jkqtpStatGenerateRegressionModel(JKQTPStatRegressionModelType::Linear, cA, cB),fWeightDataToWi),3)));
plotter->addGraph(g);
if (coeffA) *coeffA=cA;
if (coeffB) *coeffB=cB;
@ -1175,8 +1175,8 @@ inline JKQTPXFunctionLineGraph* jkqtpstatAddPolyFit(JKQTBasePlotter* plotter, In
std::vector<double> pFit;
JKQTPXFunctionLineGraph* gPoly=new JKQTPXFunctionLineGraph(plotter);
jkqtpstatPolyFit(firstX,lastX,firstY,lastY,P,std::back_inserter(pFit));
gPoly->setPlotFunctionFunctor(jkqtpstatGeneratePolynomialModel(pFit.begin(), pFit.end()));
gPoly->setTitle(QString("regression: $%1, \\chi^2=%3, R^2=%2$").arg(jkqtpstatPolynomialModel2Latex(pFit.begin(), pFit.end())).arg(jkqtp_floattolatexqstr(jkqtpstatCoefficientOfDetermination(firstX,lastX,firstY,lastY,jkqtpstatGeneratePolynomialModel(pFit.begin(), pFit.end())),3)).arg(jkqtp_floattolatexqstr(jkqtpstatSumOfDeviations(firstX,lastX,firstY,lastY,jkqtpstatGeneratePolynomialModel(pFit.begin(), pFit.end())),3)));
gPoly->setPlotFunctionFunctor(jkqtp_generatePolynomialModel(pFit.begin(), pFit.end()));
gPoly->setTitle(QString("regression: $%1, \\chi^2=%3, R^2=%2$").arg(jkqtp_polynomialModel2Latex(pFit.begin(), pFit.end())).arg(jkqtp_floattolatexqstr(jkqtpstatCoefficientOfDetermination(firstX,lastX,firstY,lastY,jkqtp_generatePolynomialModel(pFit.begin(), pFit.end())),3)).arg(jkqtp_floattolatexqstr(jkqtpstatSumOfDeviations(firstX,lastX,firstY,lastY,jkqtp_generatePolynomialModel(pFit.begin(), pFit.end())),3)));
std::copy(pFit.begin(), pFit.end(), firstRes);
plotter->addGraph(gPoly);
return gPoly;

View File

@ -44,7 +44,7 @@
#include <stdexcept>
#include <cctype>
#include "jkqtcommon/jkqtpstringtools.h"
#include "jkqtcommon/jkqtptoolsdebugging.h"
#include "jkqtcommon/jkqtpdebuggingtools.h"
#include "jkqtcommon/jkqtpmathtools.h"
#include "jkqtcommon/jkqtpalgorithms.h"
#include "jkqtcommon/jkqtpcodestructuring.h"