12 #include <QApplication> 23 void FittingStatistics::calculateCurveFit (
int orderReduced,
26 int significantDigits)
30 if (0 <= orderReduced) {
36 int orderReducedFurther = orderReduced;
37 while (!calculateCurveFitReducedFurther (orderReducedFurther,
43 --orderReducedFurther;
44 if (orderReducedFurther < 0) {
54 if (order < a.size ()) {
57 coefficients [order] = a [order];
58 fittingCurveCoef.append (a [order]);
60 }
else if (order < coefficients.size ()) {
63 coefficients [order] = 0;
69 bool FittingStatistics::calculateCurveFitReducedFurther (
int orderReducedFurther,
71 int significantDigits,
72 QVector<double> &a)
const 75 Matrix X (pointsConvenient.size (), orderReducedFurther + 1);
76 QVector<double> Y (pointsConvenient.size ());
77 loadXAndYArrays (orderReducedFurther,
95 << orderReducedFurther;
101 Matrix expectedIdentity = denominator * inv;
103 LOG4CPP_DEBUG_S ((*
mainCat)) <<
"FittingStatistics::calculateCurveFitReducedFurther succeeded with order=" 104 << orderReducedFurther
105 <<
" expectedIdentity=" 106 << expectedIdentity.
toString ().toLatin1().data ();
117 int significantDigits)
120 qApp->setOverrideCursor (Qt::WaitCursor);
125 int orderReduced = qMin (qFloor (order),
126 pointsConvenient.size() - 1);
128 calculateCurveFit (orderReduced,
132 calculateStatistics (pointsConvenient,
138 qApp->restoreOverrideCursor();
149 FittingPointsConvenient::const_iterator itrC;
150 for (itrC = pointsConvenient.begin (); itrC != pointsConvenient.end (); itrC++) {
152 const QPointF &pointC = *itrC;
155 double yAverage = ySum / pointsConvenient.length();
162 if (pointsConvenient.count() > 0) {
164 double mseSum = 0, rSquaredNumerator = 0, rSquaredDenominator = 0;
165 for (itrC = pointsConvenient.begin(); itrC != pointsConvenient.end (); itrC++) {
167 const QPointF &pointC = *itrC;
168 double yActual = pointC.y();
169 double yCurveFit = yFromXAndCoefficients (coefficients,
172 mseSum += (yCurveFit - yActual ) * (yCurveFit - yActual );
173 rSquaredNumerator += (yCurveFit - yAverage) * (yCurveFit - yAverage);
174 rSquaredDenominator += (yActual - yAverage) * (yActual - yAverage);
177 mse = mseSum / pointsConvenient.count ();
179 rSquared = (rSquaredDenominator > 0 ?
180 rSquaredNumerator / rSquaredDenominator :
185 void FittingStatistics::loadXAndYArrays (
int orderReduced,
188 QVector<double> &Y)
const 194 FittingPointsConvenient::const_iterator itr;
195 for (row = 0, itr = pointsConvenient.begin(); itr != pointsConvenient.end(); itr++, row++) {
197 const QPointF &p = *itr;
201 for (
int order = 0; order <= orderReduced; order++) {
203 X.
set (row, order, qPow (x, order));
217 if (order < coefficients.size ()) {
218 coef = coefficients [order];
220 sum += coef * qPow (x,
double (order));
Matrix transpose() const
Return the transpose of the current matrix.
void calculateCurveFitAndStatistics(unsigned int order, const FittingPointsConvenient &pointsConvenient, FittingCurveCoefficients &coefficients, double &mse, double &rms, double &rSquared, int significantDigits)
Compute the curve fit and the statistics for that curve fit.
const int MAX_POLYNOMIAL_ORDER
QList< QPointF > FittingPointsConvenient
Array of (x,y) points in graph coordinates.
MatrixConsistent
Indicates if matrix is consistent (i.e. has at least one solution)
Matrix inverse(int significantDigits, MatrixConsistent &matrixConsistent) const
Return the inverse of this matrix.
double determinant() const
Return the determinant of this matrix.
FittingStatistics()
Single constructor.
Matrix class that supports arbitrary NxN size.
log4cpp::Category * mainCat
QVector< double > FittingCurveCoefficients
Coefficients x0, x1, ... in y = a0 + a1 * x + a2 * x^2 + ...
int rows() const
Height of matrix.
void set(int row, int col, double value)
Set (row, col) element.
virtual ~FittingStatistics()
#define ENGAUGE_ASSERT(cond)
Drop in replacement for Q_ASSERT if defined(QT_NO_DEBUG) && !defined(QT_FORCE_ASSERTS) define ENGAUGE...
#define LOG4CPP_DEBUG_S(logger)
QString toString() const
Dump matrix to a string.