File indexing completed on 2024-04-28 03:48:04
0001 /* 0002 File : FitTest.cpp 0003 Project : LabPlot 0004 Description : Tests for data fitting 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2017 Alexander Semke <alexander.semke@web.de> 0007 SPDX-FileCopyrightText: 2018-2022 Stefan Gerlach <stefan.gerlach@uni.kn> 0008 0009 SPDX-License-Identifier: GPL-2.0-or-later 0010 */ 0011 0012 #include "FitTest.h" 0013 #include "backend/core/AbstractAspect.h" 0014 #include "backend/core/AbstractColumn.h" 0015 #include "backend/core/Project.h" 0016 #include "backend/core/column/Column.h" 0017 #include "backend/datasources/filters/AsciiFilter.h" 0018 #include "backend/spreadsheet/Spreadsheet.h" 0019 #include "backend/worksheet/Worksheet.h" 0020 #include "backend/worksheet/plots/cartesian/Histogram.h" 0021 #include "backend/worksheet/plots/cartesian/XYFitCurve.h" 0022 0023 #include "backend/nsl/nsl_sf_stats.h" 0024 #include "backend/nsl/nsl_stats.h" 0025 0026 // ############################################################################## 0027 // ################# linear regression with NIST datasets ###################### 0028 // ############################################################################## 0029 void FitTest::testLinearNorris() { 0030 // NIST data for Norris dataset 0031 QVector<double> xData = {0.2, 337.4, 118.2, 884.6, 10.1, 226.5, 666.3, 996.3, 448.6, 777.0, 558.2, 0.4, 0.6, 775.5, 666.9, 338.0, 447.5, 11.6, 0032 556.0, 228.1, 995.8, 887.6, 120.2, 0.3, 0.3, 556.8, 339.1, 887.2, 999.0, 779.0, 11.1, 118.3, 229.2, 669.1, 448.9, 0.5}; 0033 QVector<double> yData = {0.1, 338.8, 118.1, 888.0, 9.2, 228.1, 668.5, 998.5, 449.1, 778.9, 559.2, 0.3, 0.1, 778.1, 668.8, 339.3, 448.9, 10.8, 0034 557.7, 228.3, 998.0, 888.8, 119.6, 0.3, 0.6, 557.6, 339.3, 888.0, 998.5, 778.9, 10.2, 117.6, 228.9, 668.4, 449.2, 0.2}; 0035 0036 // data source columns 0037 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0038 xDataColumn.replaceValues(0, xData); 0039 0040 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0041 yDataColumn.replaceValues(0, yData); 0042 0043 XYFitCurve fitCurve(QStringLiteral("fit")); 0044 fitCurve.setXDataColumn(&xDataColumn); 0045 fitCurve.setYDataColumn(&yDataColumn); 0046 0047 // prepare the fit 0048 XYFitCurve::FitData fitData = fitCurve.fitData(); 0049 fitData.modelCategory = nsl_fit_model_basic; 0050 fitData.modelType = nsl_fit_model_polynomial; 0051 fitData.degree = 1; 0052 XYFitCurve::initFitData(fitData); 0053 fitCurve.setFitData(fitData); 0054 0055 // perform the fit 0056 fitCurve.recalculate(); 0057 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0058 0059 // check the results 0060 QCOMPARE(fitResult.available, true); 0061 QCOMPARE(fitResult.valid, true); 0062 0063 const int np = fitData.paramNames.size(); 0064 QCOMPARE(np, 2); 0065 0066 QCOMPARE(fitResult.paramValues.at(0), -0.262323073774029); 0067 QCOMPARE(fitResult.errorValues.at(0), 0.232818234301152); 0068 QCOMPARE(fitResult.paramValues.at(1), 1.00211681802045); 0069 QCOMPARE(fitResult.errorValues.at(1), 0.429796848199937e-3); 0070 0071 QCOMPARE(fitResult.rsd, 0.884796396144373); 0072 QCOMPARE(fitResult.rsquare, 0.999993745883712); 0073 QCOMPARE(fitResult.sse, 26.6173985294224); 0074 QCOMPARE(fitResult.rms, 0.782864662630069); 0075 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 5436385.54083098 0076 FuzzyCompare(fitResult.fdist_F, 5436385.54079785, 1.e-9); 0077 } 0078 0079 void FitTest::testLinearPontius() { 0080 // NIST data for Pontius dataset 0081 QVector<int> xData = {150000, 300000, 450000, 600000, 750000, 900000, 1050000, 1200000, 1350000, 1500000, 1650000, 1800000, 1950000, 2100000, 0082 2250000, 2400000, 2550000, 2700000, 2850000, 3000000, 150000, 300000, 450000, 600000, 750000, 900000, 1050000, 1200000, 0083 1350000, 1500000, 1650000, 1800000, 1950000, 2100000, 2250000, 2400000, 2550000, 2700000, 2850000, 3000000}; 0084 QVector<double> yData = {.11019, .21956, .32949, .43899, .54803, .65694, .76562, .87487, .98292, 1.09146, 1.20001, 1.30822, 1.41599, 1.52399, 0085 1.63194, 1.73947, 1.84646, 1.95392, 2.06128, 2.16844, .11052, .22018, .32939, .43886, .54798, .65739, .76596, .87474, 0086 .98300, 1.09150, 1.20004, 1.30818, 1.41613, 1.52408, 1.63159, 1.73965, 1.84696, 1.95445, 2.06177, 2.16829}; 0087 0088 // data source columns 0089 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0090 xDataColumn.replaceInteger(0, xData); 0091 0092 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0093 yDataColumn.replaceValues(0, yData); 0094 0095 XYFitCurve fitCurve(QStringLiteral("fit")); 0096 fitCurve.setXDataColumn(&xDataColumn); 0097 fitCurve.setYDataColumn(&yDataColumn); 0098 0099 // prepare the fit 0100 XYFitCurve::FitData fitData = fitCurve.fitData(); 0101 fitData.modelCategory = nsl_fit_model_basic; 0102 fitData.modelType = nsl_fit_model_polynomial; 0103 fitData.degree = 2; 0104 XYFitCurve::initFitData(fitData); 0105 fitCurve.setFitData(fitData); 0106 0107 // perform the fit 0108 fitCurve.recalculate(); 0109 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0110 0111 // check the results 0112 QCOMPARE(fitResult.available, true); 0113 QCOMPARE(fitResult.valid, true); 0114 0115 const int np = fitData.paramNames.size(); 0116 QCOMPARE(np, 3); 0117 0118 QCOMPARE(fitResult.paramValues.at(0), 0.673565789473684e-3); 0119 QCOMPARE(fitResult.errorValues.at(0), 0.107938612033077e-3); 0120 QCOMPARE(fitResult.paramValues.at(1), 0.732059160401003e-6); 0121 QCOMPARE(fitResult.errorValues.at(1), 0.157817399981659e-9); 0122 QCOMPARE(fitResult.paramValues.at(2), -0.316081871345029e-14); 0123 QCOMPARE(fitResult.errorValues.at(2), 0.486652849992036e-16); 0124 0125 QCOMPARE(fitResult.rsd, 0.205177424076185e-3); 0126 QCOMPARE(fitResult.rsquare, 0.999999900178537); 0127 QCOMPARE(fitResult.sse, 0.155761768796992e-5); 0128 QCOMPARE(fitResult.rms, 0.420977753505385e-7); 0129 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 185330865.884471 0130 FuzzyCompare(fitResult.fdist_F, 185330865.995752, 1.e-9); 0131 } 0132 0133 void FitTest::testLinearNoInt1() { 0134 // NIST data for NoInt1 dataset 0135 QVector<int> xData = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70}; 0136 QVector<int> yData = {130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140}; 0137 0138 // data source columns 0139 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0140 xDataColumn.replaceInteger(0, xData); 0141 0142 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0143 yDataColumn.replaceInteger(0, yData); 0144 0145 XYFitCurve fitCurve(QStringLiteral("fit")); 0146 fitCurve.setXDataColumn(&xDataColumn); 0147 fitCurve.setYDataColumn(&yDataColumn); 0148 0149 // prepare the fit 0150 XYFitCurve::FitData fitData = fitCurve.fitData(); 0151 fitData.modelCategory = nsl_fit_model_custom; 0152 XYFitCurve::initFitData(fitData); 0153 fitData.model = QStringLiteral("b1*x"); 0154 fitData.paramNames << QStringLiteral("b1"); 0155 const int np = fitData.paramNames.size(); 0156 fitData.paramStartValues << 1.; 0157 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 0158 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 0159 // fitData.eps = 1.e-15; 0160 fitCurve.setFitData(fitData); 0161 0162 // perform the fit 0163 fitCurve.recalculate(); 0164 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0165 0166 // check the results 0167 QCOMPARE(fitResult.available, true); 0168 QCOMPARE(fitResult.valid, true); 0169 0170 QCOMPARE(np, 1); 0171 0172 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 2.07438016513166 0173 FuzzyCompare(fitResult.paramValues.at(0), 2.07438016528926, 1.e-9); 0174 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.0165289256079047 0175 FuzzyCompare(fitResult.errorValues.at(0), 0.165289256198347e-1, 1.e-9); 0176 0177 QCOMPARE(fitResult.rsd, 3.56753034006338); 0178 QCOMPARE(fitResult.sse, 127.272727272727); 0179 QCOMPARE(fitResult.rms, 12.7272727272727); 0180 QCOMPARE(fitResult.rsquare, 0.999365492298663); 0181 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 15750.2500000027 0182 QCOMPARE(fitResult.fdist_F, 15750.25); 0183 } 0184 0185 void FitTest::testLinearNoInt1_2() { 0186 // NIST data for NoInt1 dataset 0187 QVector<int> xData = {60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70}; 0188 QVector<int> yData = {130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140}; 0189 0190 // data source columns 0191 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0192 xDataColumn.replaceInteger(0, xData); 0193 0194 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0195 yDataColumn.replaceInteger(0, yData); 0196 0197 XYFitCurve fitCurve(QStringLiteral("fit")); 0198 fitCurve.setXDataColumn(&xDataColumn); 0199 fitCurve.setYDataColumn(&yDataColumn); 0200 0201 // prepare the fit 0202 XYFitCurve::FitData fitData = fitCurve.fitData(); 0203 fitData.modelCategory = nsl_fit_model_basic; 0204 fitData.modelType = nsl_fit_model_polynomial; 0205 fitData.degree = 1; 0206 XYFitCurve::initFitData(fitData); 0207 fitData.paramStartValues[0] = 0; 0208 fitData.paramFixed[0] = true; 0209 fitCurve.setFitData(fitData); 0210 0211 // perform the fit 0212 fitCurve.recalculate(); 0213 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0214 0215 // check the results 0216 QCOMPARE(fitResult.available, true); 0217 QCOMPARE(fitResult.valid, true); 0218 0219 const int np = fitData.paramNames.size(); 0220 QCOMPARE(np, 2); 0221 0222 QCOMPARE(fitResult.paramValues.at(0), 0.); 0223 QCOMPARE(fitResult.paramValues.at(1), 2.07438016528926); 0224 QCOMPARE(fitResult.errorValues.at(1), 0.165289256198347e-1); 0225 0226 QCOMPARE(fitResult.rsd, 3.56753034006338); 0227 QCOMPARE(fitResult.sse, 127.272727272727); 0228 QCOMPARE(fitResult.rms, 12.7272727272727); 0229 QCOMPARE(fitResult.rsquare, 0.999365492298663); 0230 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 15760.25 0231 QCOMPARE(fitResult.fdist_F, 15750.25); 0232 } 0233 0234 void FitTest::testLinearNoInt2() { 0235 // NIST data for NoInt2 dataset 0236 QVector<int> xData = {4, 5, 6}; 0237 QVector<int> yData = {3, 4, 4}; 0238 0239 // data source columns 0240 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0241 xDataColumn.replaceInteger(0, xData); 0242 0243 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0244 yDataColumn.replaceInteger(0, yData); 0245 0246 XYFitCurve fitCurve(QStringLiteral("fit")); 0247 fitCurve.setXDataColumn(&xDataColumn); 0248 fitCurve.setYDataColumn(&yDataColumn); 0249 0250 // prepare the fit 0251 XYFitCurve::FitData fitData = fitCurve.fitData(); 0252 fitData.modelCategory = nsl_fit_model_custom; 0253 XYFitCurve::initFitData(fitData); 0254 fitData.model = QStringLiteral("c * x"); 0255 fitData.paramNames << QStringLiteral("c"); 0256 const int np = fitData.paramNames.size(); 0257 fitData.paramStartValues << 1.; 0258 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 0259 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 0260 // fitData.eps = 1.e-15; 0261 fitCurve.setFitData(fitData); 0262 0263 // perform the fit 0264 fitCurve.recalculate(); 0265 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0266 0267 // check the results 0268 QCOMPARE(fitResult.available, true); 0269 QCOMPARE(fitResult.valid, true); 0270 0271 QCOMPARE(np, 1); 0272 0273 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 0.727272727152573 0274 FuzzyCompare(fitResult.paramValues.at(0), 0.727272727272727, 1.e-9); 0275 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.0420827316561797 0276 FuzzyCompare(fitResult.errorValues.at(0), 0.420827318078432E-01, 1.e-8); 0277 0278 QCOMPARE(fitResult.rsd, 0.369274472937998); 0279 QCOMPARE(fitResult.sse, 0.272727272727273); 0280 QCOMPARE(fitResult.rms, 0.136363636363636); 0281 // can not detect that intercept is zero for a custom linear model 0282 DEBUG(std::setprecision(15) << fitResult.rsquare); // result: 0.590909090909091 0283 // QCOMPARE(fitResult.rsquare, 0.993348115299335); 0284 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 2.88888888888889 0285 // FuzzyCompare(fitResult.fdist_F, 298.666666666667, 1.); 0286 } 0287 0288 void FitTest::testLinearNoInt2_2() { 0289 // NIST data for NoInt2 dataset 0290 QVector<int> xData = {4, 5, 6}; 0291 QVector<int> yData = {3, 4, 4}; 0292 0293 // data source columns 0294 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0295 xDataColumn.replaceInteger(0, xData); 0296 0297 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0298 yDataColumn.replaceInteger(0, yData); 0299 0300 XYFitCurve fitCurve(QStringLiteral("fit")); 0301 fitCurve.setXDataColumn(&xDataColumn); 0302 fitCurve.setYDataColumn(&yDataColumn); 0303 0304 // prepare the fit 0305 XYFitCurve::FitData fitData = fitCurve.fitData(); 0306 fitData.modelCategory = nsl_fit_model_basic; 0307 fitData.modelType = nsl_fit_model_polynomial; 0308 fitData.degree = 1; 0309 XYFitCurve::initFitData(fitData); 0310 fitData.paramStartValues[0] = 0; 0311 fitData.paramFixed[0] = true; 0312 fitCurve.setFitData(fitData); 0313 0314 // perform the fit 0315 fitCurve.recalculate(); 0316 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0317 0318 // check the results 0319 QCOMPARE(fitResult.available, true); 0320 QCOMPARE(fitResult.valid, true); 0321 0322 const int np = fitData.paramNames.size(); 0323 QCOMPARE(np, 2); 0324 0325 QCOMPARE(fitResult.paramValues.at(0), 0.); 0326 QCOMPARE(fitResult.paramValues.at(1), 0.727272727272727); 0327 QCOMPARE(fitResult.errorValues.at(1), 0.420827318078432e-1); 0328 0329 QCOMPARE(fitResult.rsd, 0.369274472937998); 0330 QCOMPARE(fitResult.sse, 0.272727272727273); 0331 QCOMPARE(fitResult.rms, 0.136363636363636); 0332 QCOMPARE(fitResult.rsquare, 0.993348115299335); 0333 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 300.666666666667 0334 QCOMPARE(fitResult.fdist_F, 298.666666666667); 0335 } 0336 0337 void FitTest::testLinearFilip() { 0338 // NIST data for Filip dataset 0339 QVector<double> xData = {-6.860120914, -4.324130045, -4.358625055, -4.358426747, -6.955852379, -6.661145254, -6.355462942, -6.118102026, -7.115148017, 0340 -6.815308569, -6.519993057, -6.204119983, -5.853871964, -6.109523091, -5.79832982, -5.482672118, -5.171791386, -4.851705903, 0341 -4.517126416, -4.143573228, -3.709075441, -3.499489089, -6.300769497, -5.953504836, -5.642065153, -5.031376979, -4.680685696, 0342 -4.329846955, -3.928486195, -8.56735134, -8.363211311, -8.107682739, -7.823908741, -7.522878745, -7.218819279, -6.920818754, 0343 -6.628932138, -6.323946875, -5.991399828, -8.781464495, -8.663140179, -8.473531488, -8.247337057, -7.971428747, -7.676129393, 0344 -7.352812702, -7.072065318, -6.774174009, -6.478861916, -6.159517513, -6.835647144, -6.53165267, -6.224098421, -5.910094889, 0345 -5.598599459, -5.290645224, -4.974284616, -4.64454848, -4.290560426, -3.885055584, -3.408378962, -3.13200249, -8.726767166, 0346 -8.66695597, -8.511026475, -8.165388579, -7.886056648, -7.588043762, -7.283412422, -6.995678626, -6.691862621, -6.392544977, 0347 -6.067374056, -6.684029655, -6.378719832, -6.065855188, -5.752272167, -5.132414673, -4.811352704, -4.098269308, -3.66174277, 0348 -3.2644011}; 0349 QVector<double> yData = {0.8116, 0.9072, 0.9052, 0.9039, 0.8053, 0.8377, 0.8667, 0.8809, 0.7975, 0.8162, 0.8515, 0.8766, 0.8885, 0.8859, 0350 0.8959, 0.8913, 0.8959, 0.8971, 0.9021, 0.909, 0.9139, 0.9199, 0.8692, 0.8872, 0.89, 0.891, 0.8977, 0.9035, 0351 0.9078, 0.7675, 0.7705, 0.7713, 0.7736, 0.7775, 0.7841, 0.7971, 0.8329, 0.8641, 0.8804, 0.7668, 0.7633, 0.7678, 0352 0.7697, 0.77, 0.7749, 0.7796, 0.7897, 0.8131, 0.8498, 0.8741, 0.8061, 0.846, 0.8751, 0.8856, 0.8919, 0.8934, 0353 0.894, 0.8957, 0.9047, 0.9129, 0.9209, 0.9219, 0.7739, 0.7681, 0.7665, 0.7703, 0.7702, 0.7761, 0.7809, 0.7961, 0354 0.8253, 0.8602, 0.8809, 0.8301, 0.8664, 0.8834, 0.8898, 0.8964, 0.8963, 0.9074, 0.9119, 0.9228}; 0355 0356 // data source columns 0357 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0358 xDataColumn.replaceValues(0, xData); 0359 0360 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0361 yDataColumn.replaceValues(0, yData); 0362 0363 XYFitCurve fitCurve(QStringLiteral("fit")); 0364 fitCurve.setXDataColumn(&xDataColumn); 0365 fitCurve.setYDataColumn(&yDataColumn); 0366 0367 // prepare the fit 0368 XYFitCurve::FitData fitData = fitCurve.fitData(); 0369 fitData.modelCategory = nsl_fit_model_basic; 0370 fitData.modelType = nsl_fit_model_polynomial; 0371 fitData.degree = 10; 0372 fitData.eps = 1.e-8; 0373 XYFitCurve::initFitData(fitData); 0374 const int np = fitData.paramNames.size(); 0375 fitCurve.setFitData(fitData); 0376 0377 // perform the fit 0378 fitCurve.recalculate(); 0379 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0380 0381 // check the results 0382 QCOMPARE(fitResult.available, true); 0383 QCOMPARE(fitResult.valid, true); 0384 0385 QCOMPARE(np, 11); 0386 0387 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: -1467.48962615175 0388 FuzzyCompare(fitResult.paramValues.at(0), -1467.48961422980, 2.e-5); 0389 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 298.084524514884 0390 FuzzyCompare(fitResult.errorValues.at(0), 298.084530995537, 1.e-7); 0391 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -2772.1796150428 0392 FuzzyCompare(fitResult.paramValues.at(1), -2772.17959193342, 2.e-5); 0393 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 559.779853249694 0394 FuzzyCompare(fitResult.errorValues.at(1), 559.779865474950, 1.e-7); 0395 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: -2316.37110148409 0396 FuzzyCompare(fitResult.paramValues.at(2), -2316.37108160893, 2.e-5); 0397 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 466.477561928144 0398 FuzzyCompare(fitResult.errorValues.at(2), 466.477572127796, 1.e-7); 0399 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: -1127.97395097195 0400 FuzzyCompare(fitResult.paramValues.at(3), -1127.97394098372, 2.e-5); 0401 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 227.204269523115 0402 FuzzyCompare(fitResult.errorValues.at(3), 227.204274477751, 1.e-6); 0403 DEBUG(std::setprecision(15) << fitResult.paramValues.at(4)); // result: -354.478236951913 0404 FuzzyCompare(fitResult.paramValues.at(4), -354.478233703349, 2.e-5); 0405 DEBUG(std::setprecision(15) << fitResult.errorValues.at(4)); // result: 71.6478645361214 0406 FuzzyCompare(fitResult.errorValues.at(4), 71.6478660875927, 1.e-7); 0407 DEBUG(std::setprecision(15) << fitResult.paramValues.at(5)); // result: -75.1242024539908 0408 FuzzyCompare(fitResult.paramValues.at(5), -75.1242017393757, 2.e-5); 0409 DEBUG(std::setprecision(15) << fitResult.errorValues.at(5)); // result: 15.289717547564 0410 FuzzyCompare(fitResult.errorValues.at(5), 15.2897178747400, 1.e-7); 0411 DEBUG(std::setprecision(15) << fitResult.paramValues.at(6)); // result: -10.875318143236 0412 FuzzyCompare(fitResult.paramValues.at(6), -10.8753180355343, 2.e-5); 0413 DEBUG(std::setprecision(15) << fitResult.errorValues.at(6)); // result: 2.23691155110776 0414 FuzzyCompare(fitResult.errorValues.at(6), 2.23691159816033, 1.e-7); 0415 DEBUG(std::setprecision(15) << fitResult.paramValues.at(7)); // result: -1.06221499687347 0416 FuzzyCompare(fitResult.paramValues.at(7), -1.06221498588947, 2.e-5); 0417 DEBUG(std::setprecision(15) << fitResult.errorValues.at(7)); // result: 0.221624317377432 0418 FuzzyCompare(fitResult.errorValues.at(7), 0.221624321934227, 1.e-7); 0419 DEBUG(std::setprecision(15) << fitResult.paramValues.at(8)); // result: -0.0670191161850038 0420 FuzzyCompare(fitResult.paramValues.at(8), -0.670191154593408E-01, 2.e-5); 0421 DEBUG(std::setprecision(15) << fitResult.errorValues.at(8)); // result: 0.0142363760310402 0422 FuzzyCompare(fitResult.errorValues.at(8), 0.142363763154724E-01, 1.e-7); 0423 DEBUG(std::setprecision(15) << fitResult.paramValues.at(9)); // result: -0.00246781081080665 0424 FuzzyCompare(fitResult.paramValues.at(9), -0.246781078275479E-02, 2.e-5); 0425 DEBUG(std::setprecision(15) << fitResult.errorValues.at(9)); // result: 0.000535617398555022 0426 FuzzyCompare(fitResult.errorValues.at(9), 0.535617408889821E-03, 1.e-7); 0427 DEBUG(std::setprecision(15) << fitResult.paramValues.at(10)); // result: -4.02962529900222e-05 0428 FuzzyCompare(fitResult.paramValues.at(10), -0.402962525080404E-04, 2.e-5); 0429 DEBUG(std::setprecision(15) << fitResult.errorValues.at(10)); // result: 8.96632820770946e-06 0430 FuzzyCompare(fitResult.errorValues.at(10), 0.896632837373868E-05, 1.e-7); 0431 0432 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.00334801050105949 0433 FuzzyCompare(fitResult.rsd, 0.334801051324544E-02, 1.e-7); 0434 DEBUG(std::setprecision(15) << fitResult.rsquare); // result: 0.996727416209443 0435 FuzzyCompare(fitResult.rsquare, 0.996727416185620, 1.e-9); 0436 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.00079585137637953 0437 FuzzyCompare(fitResult.sse, 0.795851382172941E-03, 1.e-7); 0438 DEBUG(std::setprecision(15) << fitResult.rms); // result: 1.12091743152047e-05 0439 FuzzyCompare(fitResult.rms, 0.112091743968020E-04, 1.e-7); 0440 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 2162.43960297897 0441 FuzzyCompare(fitResult.fdist_F, 2162.43954511489, 1.e-7); 0442 } 0443 0444 void FitTest::testLinearWampler1() { 0445 // NIST data for Wampler1 dataset 0446 QVector<int> xData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; 0447 QVector<int> yData = {1, 6, 63, 364, 1365, 3906, 9331, 19608, 37449, 66430, 111111, 0448 177156, 271453, 402234, 579195, 813616, 1118481, 1508598, 2000719, 2613660, 3368421}; 0449 0450 // data source columns 0451 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0452 xDataColumn.replaceInteger(0, xData); 0453 0454 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0455 yDataColumn.replaceInteger(0, yData); 0456 0457 XYFitCurve fitCurve(QStringLiteral("fit")); 0458 fitCurve.setXDataColumn(&xDataColumn); 0459 fitCurve.setYDataColumn(&yDataColumn); 0460 0461 // prepare the fit 0462 XYFitCurve::FitData fitData = fitCurve.fitData(); 0463 fitData.modelCategory = nsl_fit_model_basic; 0464 fitData.modelType = nsl_fit_model_polynomial; 0465 fitData.degree = 5; 0466 XYFitCurve::initFitData(fitData); 0467 fitCurve.setFitData(fitData); 0468 0469 // perform the fit 0470 fitCurve.recalculate(); 0471 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0472 0473 // check the results 0474 QCOMPARE(fitResult.available, true); 0475 QCOMPARE(fitResult.valid, true); 0476 0477 const int np = fitData.paramNames.size(); 0478 QCOMPARE(np, 6); 0479 0480 for (int i = 0; i < np; i++) { 0481 const double paramValue = fitResult.paramValues.at(i); 0482 const double errorValue = fitResult.errorValues.at(i); 0483 QCOMPARE(paramValue, 1.0); 0484 QCOMPARE(errorValue, 0.0); 0485 } 0486 0487 QCOMPARE(fitResult.rsd, 0.0); 0488 QCOMPARE(fitResult.rsquare, 1.0); 0489 QCOMPARE(fitResult.sse, 0.0); 0490 QCOMPARE(fitResult.rms, 0.0); 0491 QVERIFY(std::isinf(fitResult.fdist_F)); 0492 } 0493 0494 void FitTest::testLinearWampler2() { 0495 // NIST data for Wampler2 dataset 0496 QVector<int> xData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; 0497 QVector<double> yData = {1.00000, 1.11111, 1.24992, 1.42753, 1.65984, 1.96875, 2.38336, 2.94117, 3.68928, 4.68559, 6.00000, 0498 7.71561, 9.92992, 12.75603, 16.32384, 20.78125, 26.29536, 33.05367, 41.26528, 51.16209, 63.00000}; 0499 0500 // data source columns 0501 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0502 xDataColumn.replaceInteger(0, xData); 0503 0504 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0505 yDataColumn.replaceValues(0, yData); 0506 0507 XYFitCurve fitCurve(QStringLiteral("fit")); 0508 fitCurve.setXDataColumn(&xDataColumn); 0509 fitCurve.setYDataColumn(&yDataColumn); 0510 0511 // prepare the fit 0512 XYFitCurve::FitData fitData = fitCurve.fitData(); 0513 fitData.modelCategory = nsl_fit_model_basic; 0514 fitData.modelType = nsl_fit_model_polynomial; 0515 fitData.degree = 5; 0516 XYFitCurve::initFitData(fitData); 0517 fitCurve.setFitData(fitData); 0518 0519 // perform the fit 0520 fitCurve.recalculate(); 0521 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0522 0523 // check the results 0524 qDebug() << "STATUS " << fitResult.status; 0525 QCOMPARE(fitResult.available, true); 0526 QCOMPARE(fitResult.valid, true); 0527 0528 const int np = fitData.paramNames.size(); 0529 QCOMPARE(np, 6); 0530 0531 for (int i = 0; i < np; i++) { 0532 DEBUG(std::setprecision(15) << fitResult.paramValues.at(i)); 0533 } 0534 QCOMPARE(fitResult.paramValues.at(0), 1.0); 0535 QCOMPARE(fitResult.paramValues.at(1), 0.1); 0536 QCOMPARE(fitResult.paramValues.at(2), 0.01); 0537 QCOMPARE(fitResult.paramValues.at(3), 0.001); 0538 QCOMPARE(fitResult.paramValues.at(4), 0.0001); 0539 QCOMPARE(fitResult.paramValues.at(5), 0.00001); 0540 for (int i = 0; i < np; i++) { 0541 const double errorValue = fitResult.errorValues.at(i); 0542 DEBUG(std::setprecision(15) << errorValue); // max. result: 2.32794076549904e-15 0543 FuzzyCompare(errorValue, 0., 1.e-14); 0544 } 0545 0546 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 2.32458538254974e-15 0547 FuzzyCompare(fitResult.rsd, 0., 1.e-14); 0548 QCOMPARE(fitResult.rsquare, 1.); 0549 DEBUG(std::setprecision(15) << fitResult.sse); // result: 8.1055458011459e-29 0550 FuzzyCompare(fitResult.sse, 0., 1.e-15); 0551 DEBUG(std::setprecision(15) << fitResult.rms); // result: 5.40369720076393e-30 0552 FuzzyCompare(fitResult.rms, 0., 1.e-15); 0553 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 2.44385217688297e+32 0554 QVERIFY(fitResult.fdist_F > 1.e+32); 0555 } 0556 0557 void FitTest::testLinearWampler3() { 0558 // NIST data for Wampler3 dataset 0559 QVector<int> xData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; 0560 QVector<double> yData = {760., -2042., 2111., -1684., 3888., 1858., 11379., 17560., 39287., 64382., 113159., 0561 175108., 273291., 400186., 581243., 811568., 1121004., 1506550., 2002767., 2611612., 3369180.}; 0562 0563 // data source columns 0564 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0565 xDataColumn.replaceInteger(0, xData); 0566 0567 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0568 yDataColumn.replaceValues(0, yData); 0569 0570 XYFitCurve fitCurve(QStringLiteral("fit")); 0571 fitCurve.setXDataColumn(&xDataColumn); 0572 fitCurve.setYDataColumn(&yDataColumn); 0573 0574 // prepare the fit 0575 XYFitCurve::FitData fitData = fitCurve.fitData(); 0576 fitData.modelCategory = nsl_fit_model_basic; 0577 fitData.modelType = nsl_fit_model_polynomial; 0578 fitData.degree = 5; 0579 XYFitCurve::initFitData(fitData); 0580 fitCurve.setFitData(fitData); 0581 0582 // perform the fit 0583 fitCurve.recalculate(); 0584 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0585 0586 // check the results 0587 QCOMPARE(fitResult.available, true); 0588 QCOMPARE(fitResult.valid, true); 0589 0590 const int np = fitData.paramNames.size(); 0591 QCOMPARE(np, 6); 0592 0593 for (int i = 0; i < np; i++) { 0594 const double paramValue = fitResult.paramValues.at(i); 0595 QCOMPARE(paramValue, 1.0); 0596 } 0597 QCOMPARE(fitResult.errorValues.at(0), 2152.32624678170); 0598 QCOMPARE(fitResult.errorValues.at(1), 2363.55173469681); 0599 QCOMPARE(fitResult.errorValues.at(2), 779.343524331583); 0600 QCOMPARE(fitResult.errorValues.at(3), 101.475507550350); 0601 QCOMPARE(fitResult.errorValues.at(4), 5.64566512170752); 0602 QCOMPARE(fitResult.errorValues.at(5), 0.112324854679312); 0603 0604 QCOMPARE(fitResult.rsd, 2360.14502379268); 0605 QCOMPARE(fitResult.rsquare, 0.999995559025820); 0606 QCOMPARE(fitResult.sse, 83554268.0000000); 0607 QCOMPARE(fitResult.rms, 5570284.53333333); 0608 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 675524.458247789 0609 FuzzyCompare(fitResult.fdist_F, 675524.458240122, 1.e-7); 0610 } 0611 0612 void FitTest::testLinearWampler4() { 0613 // NIST data for Wampler4 dataset 0614 QVector<int> xData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; 0615 QVector<int> yData = {75901, -204794, 204863, -204436, 253665, -200894, 214131, -185192, 221249, -138370, 315911, 0616 -27644, 455253, 197434, 783995, 608816, 1370781, 1303798, 2205519, 2408860, 3444321}; 0617 0618 // data source columns 0619 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0620 xDataColumn.replaceInteger(0, xData); 0621 0622 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0623 yDataColumn.replaceInteger(0, yData); 0624 0625 XYFitCurve fitCurve(QStringLiteral("fit")); 0626 fitCurve.setXDataColumn(&xDataColumn); 0627 fitCurve.setYDataColumn(&yDataColumn); 0628 0629 // prepare the fit 0630 XYFitCurve::FitData fitData = fitCurve.fitData(); 0631 fitData.modelCategory = nsl_fit_model_basic; 0632 fitData.modelType = nsl_fit_model_polynomial; 0633 fitData.degree = 5; 0634 XYFitCurve::initFitData(fitData); 0635 fitCurve.setFitData(fitData); 0636 0637 // perform the fit 0638 fitCurve.recalculate(); 0639 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0640 0641 // check the results 0642 QCOMPARE(fitResult.available, true); 0643 QCOMPARE(fitResult.valid, true); 0644 0645 const int np = fitData.paramNames.size(); 0646 QCOMPARE(np, 6); 0647 0648 FuzzyCompare(fitResult.paramValues.at(0), 1.0, 3.e-9); // i386: 1.00000000223515 0649 FuzzyCompare(fitResult.paramValues.at(1), 1.0, 5.e-9); // i386: 0.999999995021441 0650 FuzzyCompare(fitResult.paramValues.at(2), 1.0, 2.e-9); // i386: 1.00000000188395 0651 FuzzyCompare(fitResult.paramValues.at(3), 1.0, 1.e-9); // i386: 0.999999999743725 0652 FuzzyCompare(fitResult.paramValues.at(4), 1.0, 2.e-11); // i386: 1.00000000001441 0653 FuzzyCompare(fitResult.paramValues.at(5), 1.0); // i386: 0.999999999999714 0654 0655 QCOMPARE(fitResult.errorValues.at(0), 215232.624678170); 0656 QCOMPARE(fitResult.errorValues.at(1), 236355.173469681); 0657 QCOMPARE(fitResult.errorValues.at(2), 77934.3524331583); 0658 QCOMPARE(fitResult.errorValues.at(3), 10147.5507550350); 0659 QCOMPARE(fitResult.errorValues.at(4), 564.566512170752); 0660 QCOMPARE(fitResult.errorValues.at(5), 11.2324854679312); 0661 0662 QCOMPARE(fitResult.rsd, 236014.502379268); 0663 QCOMPARE(fitResult.rsquare, 0.957478440825662); 0664 QCOMPARE(fitResult.sse, 835542680000.000); 0665 QCOMPARE(fitResult.rms, 55702845333.3333); 0666 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 67.5524458240122 0667 QCOMPARE(fitResult.fdist_F, 67.5524458240122); 0668 } 0669 0670 void FitTest::testLinearWampler5() { 0671 // NIST data for Wampler5 dataset 0672 QVector<int> xData = {0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20}; 0673 QVector<int> yData = {7590001, -20479994, 20480063, -20479636, 25231365, -20476094, 20489331, -20460392, 18417449, -20413570, 20591111, 0674 -20302844, 18651453, -20077766, 21059195, -19666384, 26348481, -18971402, 22480719, -17866340, 10958421}; 0675 0676 // data source columns 0677 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0678 xDataColumn.replaceInteger(0, xData); 0679 0680 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0681 yDataColumn.replaceInteger(0, yData); 0682 0683 XYFitCurve fitCurve(QStringLiteral("fit")); 0684 fitCurve.setXDataColumn(&xDataColumn); 0685 fitCurve.setYDataColumn(&yDataColumn); 0686 0687 // prepare the fit 0688 XYFitCurve::FitData fitData = fitCurve.fitData(); 0689 fitData.modelCategory = nsl_fit_model_basic; 0690 fitData.modelType = nsl_fit_model_polynomial; 0691 fitData.degree = 5; 0692 XYFitCurve::initFitData(fitData); 0693 fitCurve.setFitData(fitData); 0694 0695 // perform the fit 0696 fitCurve.recalculate(); 0697 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0698 0699 // check the results 0700 QCOMPARE(fitResult.available, true); 0701 QCOMPARE(fitResult.valid, true); 0702 0703 const int np = fitData.paramNames.size(); 0704 QCOMPARE(np, 6); 0705 0706 for (int i = 0; i < np; i++) { 0707 const double paramValue = fitResult.paramValues.at(i); 0708 DEBUG(std::setprecision(15) << paramValue); 0709 FuzzyCompare(paramValue, 1.0, 3.e-7); 0710 } 0711 QCOMPARE(fitResult.errorValues.at(0), 21523262.4678170); 0712 QCOMPARE(fitResult.errorValues.at(1), 23635517.3469681); 0713 QCOMPARE(fitResult.errorValues.at(2), 7793435.24331583); 0714 QCOMPARE(fitResult.errorValues.at(3), 1014755.07550350); 0715 QCOMPARE(fitResult.errorValues.at(4), 56456.6512170752); 0716 QCOMPARE(fitResult.errorValues.at(5), 1123.24854679312); 0717 0718 QCOMPARE(fitResult.rsd, 23601450.2379268); 0719 QCOMPARE(fitResult.rsquare, 0.224668921574940E-02); 0720 QCOMPARE(fitResult.sse, 0.835542680000000E+16); 0721 QCOMPARE(fitResult.rms, 557028453333333.); 0722 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 0.00675524458240069 0723 QCOMPARE(fitResult.fdist_F, 0.675524458240122E-02); 0724 } 0725 0726 // taken from https://en.wikipedia.org/wiki/Ordinary_least_squares 0727 void FitTest::testLinearWP_OLS() { 0728 // data from The World Almanac and Book of Facts, 1975 0729 QVector<double> xData = {1.47, 1.50, 1.52, 1.55, 1.57, 1.60, 1.63, 1.65, 1.68, 1.70, 1.73, 1.75, 1.78, 1.80, 1.83}; 0730 QVector<double> yData = {52.21, 53.12, 54.48, 55.84, 57.20, 58.57, 59.93, 61.29, 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46}; 0731 0732 // data source columns 0733 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0734 xDataColumn.replaceValues(0, xData); 0735 0736 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0737 yDataColumn.replaceValues(0, yData); 0738 0739 XYFitCurve fitCurve(QStringLiteral("fit")); 0740 fitCurve.setXDataColumn(&xDataColumn); 0741 fitCurve.setYDataColumn(&yDataColumn); 0742 0743 // prepare the fit 0744 XYFitCurve::FitData fitData = fitCurve.fitData(); 0745 fitData.modelCategory = nsl_fit_model_basic; 0746 fitData.modelType = nsl_fit_model_polynomial; 0747 fitData.degree = 2; 0748 XYFitCurve::initFitData(fitData); 0749 fitCurve.setFitData(fitData); 0750 0751 // perform the fit 0752 fitCurve.recalculate(); 0753 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0754 0755 // check the results 0756 QCOMPARE(fitResult.available, true); 0757 QCOMPARE(fitResult.valid, true); 0758 0759 const int np = fitData.paramNames.size(); 0760 QCOMPARE(np, 3); 0761 0762 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 128.812803578436 0763 FuzzyCompare(fitResult.paramValues.at(0), 128.8128, 1.e-7); 0764 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 16.3082821390367 0765 FuzzyCompare(fitResult.errorValues.at(0), 16.3083, 1.e-5); 0766 DEBUG(std::setprecision(15) << fitResult.tdist_tValues.at(0)); // result: 7.89861264848368 0767 FuzzyCompare(fitResult.tdist_tValues.at(0), 7.8986, 1.e-5); 0768 DEBUG(std::setprecision(15) << fitResult.tdist_pValues.at(0)); // result: 4.28330815316414e-06 0769 FuzzyCompare(fitResult.tdist_pValues.at(0), 0., 1.e-5); 0770 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -143.16202286476 0771 FuzzyCompare(fitResult.paramValues.at(1), -143.1620, 1.e-6); 0772 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 19.8331710430895 0773 FuzzyCompare(fitResult.errorValues.at(1), 19.8332, 1.e-5); 0774 DEBUG(std::setprecision(15) << fitResult.tdist_tValues.at(1)); // result: -7.21831231897945 0775 FuzzyCompare(fitResult.tdist_tValues.at(1), -7.2183, 1.e-5); 0776 DEBUG(std::setprecision(15) << fitResult.tdist_pValues.at(1)); // result: 1.05970640905074e-05 0777 FuzzyCompare(fitResult.tdist_pValues.at(1), 0., 2.e-5); 0778 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 61.9603254424724 0779 FuzzyCompare(fitResult.paramValues.at(2), 61.9603, 1.e-6); 0780 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 6.00842899301227 0781 FuzzyCompare(fitResult.errorValues.at(2), 6.0084, 1.e-5); 0782 DEBUG(std::setprecision(15) << fitResult.tdist_tValues.at(2)); // result: 10.3122339490958 0783 FuzzyCompare(fitResult.tdist_tValues.at(2), 10.3122, 1.e-5); 0784 DEBUG(std::setprecision(15) << fitResult.tdist_pValues.at(2)); // result: 2.56647515320682e-07 0785 FuzzyCompare(fitResult.tdist_pValues.at(2), 0., 1.e-6); 0786 0787 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.25158650082898 0788 FuzzyCompare(fitResult.rsd, 0.2516, 1.e-4); 0789 DEBUG(std::setprecision(15) << fitResult.rsquare); // result: 0.998904558436583 0790 FuzzyCompare(fitResult.rsquare, 0.9989, 1.e-5); 0791 DEBUG(std::setprecision(15) << fitResult.rsquareAdj); // result: 0.99860580164656 0792 FuzzyCompare(fitResult.rsquareAdj, 0.9987, 1.e-4); 0793 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.759549208792447 0794 FuzzyCompare(fitResult.sse, 0.7595, 1.e-4); 0795 // QCOMPARE(fitResult.rms, ???); // result: 0.0632958 0796 DEBUG(std::setprecision(15) << fitResult.chisq_p); // result: 0.999996987409119 0797 // FuzzyCompare(fitResult.chisq_p, ???, 1.e-8); 0798 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 5471.2433330734 0799 FuzzyCompare(fitResult.fdist_F, 5471.2, 1.e-5); 0800 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.0 0801 QCOMPARE(fitResult.fdist_p, 0.0); 0802 DEBUG(std::setprecision(15) << fitResult.logLik); // result: 1.0890247702592 0803 FuzzyCompare(fitResult.logLik, 1.0890, 3.e-5); 0804 DEBUG(std::setprecision(15) << fitResult.aic); // result: 5.82195045948161 0805 // not reproducable 0806 // FuzzyCompare(fitResult.aic, 0.2548, 2.e-6); 0807 DEBUG(std::setprecision(15) << fitResult.bic); // result: 8.65415126389045 0808 // not reproducable 0809 // FuzzyCompare(fitResult.bic, 0.3964, 2.e-6); 0810 } 0811 0812 // from http://sia.webpopix.org/polynomialRegression1.html 0813 void FitTest::testLinearR_lm2() { 0814 QVector<int> xData = {4, 4, 7, 7, 8, 9, 10, 10, 10, 11, 11, 12, 12, 12, 12, 13, 13, 13, 13, 14, 14, 14, 14, 15, 15, 0815 15, 16, 16, 17, 17, 17, 18, 18, 18, 18, 19, 19, 19, 20, 20, 20, 20, 20, 22, 23, 24, 24, 24, 24, 25}; 0816 QVector<int> yData = {2, 10, 4, 22, 16, 10, 18, 26, 34, 17, 28, 14, 20, 24, 28, 26, 34, 34, 46, 26, 36, 60, 80, 20, 26, 0817 54, 32, 40, 32, 40, 50, 42, 56, 76, 84, 36, 46, 68, 32, 48, 52, 56, 64, 66, 54, 70, 92, 93, 120, 85}; 0818 0819 // data source columns 0820 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0821 xDataColumn.replaceInteger(0, xData); 0822 0823 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Integer); 0824 yDataColumn.replaceInteger(0, yData); 0825 0826 XYFitCurve fitCurve(QStringLiteral("fit")); 0827 fitCurve.setXDataColumn(&xDataColumn); 0828 fitCurve.setYDataColumn(&yDataColumn); 0829 0830 // prepare the fit 0831 XYFitCurve::FitData fitData = fitCurve.fitData(); 0832 fitData.modelCategory = nsl_fit_model_basic; 0833 fitData.modelType = nsl_fit_model_polynomial; 0834 fitData.degree = 2; 0835 XYFitCurve::initFitData(fitData); 0836 fitCurve.setFitData(fitData); 0837 0838 // perform the fit 0839 fitCurve.recalculate(); 0840 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0841 0842 // check the results 0843 QCOMPARE(fitResult.available, true); 0844 QCOMPARE(fitResult.valid, true); 0845 0846 const int np = fitData.paramNames.size(); 0847 QCOMPARE(np, 3); 0848 0849 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 2.47013778506623 0850 FuzzyCompare(fitResult.paramValues.at(0), 2.47014, 1.e-6); 0851 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 14.8171647250237 0852 FuzzyCompare(fitResult.errorValues.at(0), 14.81716, 1.e-6); 0853 DEBUG(std::setprecision(15) << fitResult.tdist_tValues.at(0)); // result: 0.16670785746848 0854 FuzzyCompare(fitResult.tdist_tValues.at(0), 0.167, 2.e-3); 0855 DEBUG(std::setprecision(15) << fitResult.tdist_pValues.at(0)); // result: 0.868315075848582 0856 FuzzyCompare(fitResult.tdist_pValues.at(0), 0.868, 1.e-3); 0857 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.913287614242592 0858 FuzzyCompare(fitResult.paramValues.at(1), 0.91329, 1.e-5); 0859 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.03422044231195 0860 FuzzyCompare(fitResult.errorValues.at(1), 2.03422, 1.e-6); 0861 DEBUG(std::setprecision(15) << fitResult.tdist_tValues.at(1)); // result: 0.448961968548804 0862 FuzzyCompare(fitResult.tdist_tValues.at(1), 0.449, 1.e-4); 0863 DEBUG(std::setprecision(15) << fitResult.tdist_pValues.at(1)); // result: 0.655522449402813 0864 FuzzyCompare(fitResult.tdist_pValues.at(1), 0.656, 1.e-3); 0865 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 0.0999593020698437 0866 FuzzyCompare(fitResult.paramValues.at(2), 0.09996, 1.e-5); 0867 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.0659682106823392 0868 FuzzyCompare(fitResult.errorValues.at(2), 0.06597, 1.e-4); 0869 DEBUG(std::setprecision(15) << fitResult.tdist_tValues.at(2)); // result: 1.5152647166858 0870 FuzzyCompare(fitResult.tdist_tValues.at(2), 1.515, 1.e-3); 0871 DEBUG(std::setprecision(15) << fitResult.tdist_pValues.at(2)); // result: 0.136402432803739 0872 FuzzyCompare(fitResult.tdist_pValues.at(2), 0.136, 3.e-3); 0873 0874 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 15.1760701243277 0875 FuzzyCompare(fitResult.rsd, 15.18, 1.e-3); 0876 DEBUG(std::setprecision(15) << fitResult.rsquare); // result: 0.66733081652621 0877 FuzzyCompare(fitResult.rsquare, 0.6673, 1.e-4); 0878 DEBUG(std::setprecision(15) << fitResult.rsquareAdj); // result: 0.645635000212702 0879 DEBUG(std::setprecision(15) << 1. - (1. - fitResult.rsquare) * (50. - 1.) / (50. - np)); // result: 0.65317468105924 0880 // reference calculates 1-(1-R^2)(n-1)/(n-p) 0881 FuzzyCompare(1. - (1. - fitResult.rsquare) * (50. - 1.) / (50. - np), 0.6532, 1.e-4); 0882 DEBUG(std::setprecision(15) << fitResult.sse); // result: 10824.71590767 0883 FuzzyCompare(fitResult.sse, 10825, 1.e-4); 0884 DEBUG(std::setprecision(15) << fitResult.rms); // result: 230.313104418511 0885 // QCOMPARE(fitResult.rms, ???); 0886 DEBUG(std::setprecision(15) << fitResult.logLik); // result: -205.386034235309 0887 FuzzyCompare(fitResult.logLik, -205.386, 1.e-6); 0888 DEBUG(std::setprecision(15) << fitResult.chisq_p); // result: 0889 // FuzzyCompare(fitResult.chisq_p, ???, 1.e-8); 0890 DEBUG(std::setprecision(15) << fitResult.fdist_F); // result: 0891 // reference calculates sst/rms/np 0892 DEBUG(std::setprecision(15) << fitResult.sst / fitResult.rms / np); // result: 47.0938320858956 0893 FuzzyCompare(fitResult.sst / fitResult.rms / np, 47.14, 1.e-3); 0894 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0 0895 QCOMPARE(fitResult.fdist_p, 0.); // exact: 5.852e-12 0896 DEBUG(std::setprecision(15) << fitResult.aic); // result: 418.772068470618 0897 FuzzyCompare(fitResult.aic, 418.7721, 1.e-7); 0898 DEBUG(std::setprecision(15) << fitResult.bic); // result: 426.42016049233 0899 FuzzyCompare(fitResult.bic, 426.4202, 1.e-7); 0900 } 0901 0902 // ############################################################################## 0903 // ############# non-linear regression with NIST datasets ##################### 0904 // ############################################################################## 0905 0906 void FitTest::testNonLinearMisra1a() { 0907 // NIST data for Misra1a dataset 0908 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 0909 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 0910 0911 // data source columns 0912 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0913 xDataColumn.replaceValues(0, xData); 0914 0915 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0916 yDataColumn.replaceValues(0, yData); 0917 0918 XYFitCurve fitCurve(QStringLiteral("fit")); 0919 fitCurve.setXDataColumn(&xDataColumn); 0920 fitCurve.setYDataColumn(&yDataColumn); 0921 0922 // prepare the fit 0923 XYFitCurve::FitData fitData = fitCurve.fitData(); 0924 fitData.modelCategory = nsl_fit_model_custom; 0925 XYFitCurve::initFitData(fitData); 0926 fitData.model = QStringLiteral("b1*(1-exp(-b2*x))"); 0927 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 0928 fitData.eps = 1.e-12; 0929 const int np = fitData.paramNames.size(); 0930 fitData.paramStartValues << 500. << 0.0001; 0931 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 0932 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 0933 fitCurve.setFitData(fitData); 0934 0935 // perform the fit 0936 fitCurve.recalculate(); 0937 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0938 0939 // check the results 0940 QCOMPARE(fitResult.available, true); 0941 QCOMPARE(fitResult.valid, true); 0942 0943 QCOMPARE(np, 2); 0944 0945 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 238.942305251573 0946 FuzzyCompare(fitResult.paramValues.at(0), 2.3894212918E+02, 1.e-6); 0947 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 2.70651225218243 0948 FuzzyCompare(fitResult.errorValues.at(0), 2.7070075241E+00, 1.e-3); 0949 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000550155958419367 0950 FuzzyCompare(fitResult.paramValues.at(1), 5.5015643181E-04, 1.e-6); 0951 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 7.26565480949189e-06 0952 FuzzyCompare(fitResult.errorValues.at(1), 7.2668688436E-06, 1.e-3); 0953 0954 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.101878763320394 0955 FuzzyCompare(fitResult.rsd, 1.0187876330E-01, 1.e-9); 0956 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.124551388988316 0957 FuzzyCompare(fitResult.sse, 1.2455138894E-01, 1.e-9); 0958 } 0959 0960 void FitTest::testNonLinearMisra1a_2() { 0961 // NIST data for Misra1a dataset 0962 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 0963 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 0964 0965 // data source columns 0966 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0967 xDataColumn.replaceValues(0, xData); 0968 0969 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0970 yDataColumn.replaceValues(0, yData); 0971 0972 XYFitCurve fitCurve(QStringLiteral("fit")); 0973 fitCurve.setXDataColumn(&xDataColumn); 0974 fitCurve.setYDataColumn(&yDataColumn); 0975 0976 // prepare the fit 0977 XYFitCurve::FitData fitData = fitCurve.fitData(); 0978 fitData.modelCategory = nsl_fit_model_custom; 0979 XYFitCurve::initFitData(fitData); 0980 fitData.model = QStringLiteral("b1*(1-exp(-b2*x))"); 0981 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 0982 fitData.eps = 1.e-12; 0983 const int np = fitData.paramNames.size(); 0984 fitData.paramStartValues << 250. << 5.e-4; 0985 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 0986 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 0987 fitCurve.setFitData(fitData); 0988 0989 // perform the fit 0990 fitCurve.recalculate(); 0991 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 0992 0993 // check the results 0994 QCOMPARE(fitResult.available, true); 0995 QCOMPARE(fitResult.valid, true); 0996 0997 QCOMPARE(np, 2); 0998 0999 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 238.942305251573 1000 FuzzyCompare(fitResult.paramValues.at(0), 2.3894212918E+02, 1.e-6); 1001 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 2.70651225218243 1002 FuzzyCompare(fitResult.errorValues.at(0), 2.7070075241E+00, 1.e-3); 1003 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000550155958419367 1004 FuzzyCompare(fitResult.paramValues.at(1), 5.5015643181E-04, 1.e-6); 1005 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 7.26565480949189e-06 1006 FuzzyCompare(fitResult.errorValues.at(1), 7.2668688436E-06, 1.e-3); 1007 1008 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.101878763320394 1009 FuzzyCompare(fitResult.rsd, 1.0187876330E-01, 1.e-9); 1010 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.124551388988316 1011 FuzzyCompare(fitResult.sse, 1.2455138894E-01, 1.e-9); 1012 } 1013 1014 void FitTest::testNonLinearMisra1a_3() { 1015 // NIST data for Misra1a dataset 1016 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1017 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1018 1019 // data source columns 1020 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1021 xDataColumn.replaceValues(0, xData); 1022 1023 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1024 yDataColumn.replaceValues(0, yData); 1025 1026 XYFitCurve fitCurve(QStringLiteral("fit")); 1027 fitCurve.setXDataColumn(&xDataColumn); 1028 fitCurve.setYDataColumn(&yDataColumn); 1029 1030 // prepare the fit 1031 XYFitCurve::FitData fitData = fitCurve.fitData(); 1032 fitData.modelCategory = nsl_fit_model_custom; 1033 XYFitCurve::initFitData(fitData); 1034 fitData.model = QStringLiteral("b1*(1-exp(-b2*x))"); 1035 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1036 fitData.eps = 1.e-12; 1037 const int np = fitData.paramNames.size(); 1038 fitData.paramStartValues << 2.3894212918E+02 << 5.5015643181E-04; 1039 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1040 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1041 fitCurve.setFitData(fitData); 1042 1043 // perform the fit 1044 fitCurve.recalculate(); 1045 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1046 1047 // check the results 1048 QCOMPARE(fitResult.available, true); 1049 QCOMPARE(fitResult.valid, true); 1050 1051 QCOMPARE(np, 2); 1052 1053 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 238.942305251573 1054 FuzzyCompare(fitResult.paramValues.at(0), 2.3894212918E+02, 1.e-6); 1055 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 2.70651225218243 1056 FuzzyCompare(fitResult.errorValues.at(0), 2.7070075241E+00, 1.e-3); 1057 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000550155958419367 1058 FuzzyCompare(fitResult.paramValues.at(1), 5.5015643181E-04, 1.e-6); 1059 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 7.26565480949189e-06 1060 FuzzyCompare(fitResult.errorValues.at(1), 7.2668688436E-06, 1.e-3); 1061 1062 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.101878763320394 1063 FuzzyCompare(fitResult.rsd, 1.0187876330E-01, 1.e-9); 1064 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.124551388988316 1065 FuzzyCompare(fitResult.sse, 1.2455138894E-01, 1.e-9); 1066 } 1067 1068 void FitTest::testNonLinearMisra1b() { 1069 // NIST data for Misra1b dataset 1070 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1071 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1072 1073 // data source columns 1074 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1075 xDataColumn.replaceValues(0, xData); 1076 1077 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1078 yDataColumn.replaceValues(0, yData); 1079 1080 XYFitCurve fitCurve(QStringLiteral("fit")); 1081 fitCurve.setXDataColumn(&xDataColumn); 1082 fitCurve.setYDataColumn(&yDataColumn); 1083 1084 // prepare the fit 1085 XYFitCurve::FitData fitData = fitCurve.fitData(); 1086 fitData.modelCategory = nsl_fit_model_custom; 1087 XYFitCurve::initFitData(fitData); 1088 fitData.model = QStringLiteral("b1*(1-1/(1+b2*x/2)^2)"); 1089 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1090 fitData.eps = 1.e-12; 1091 const int np = fitData.paramNames.size(); 1092 fitData.paramStartValues << 500. << 0.0001; 1093 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1094 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1095 fitCurve.setFitData(fitData); 1096 1097 // perform the fit 1098 fitCurve.recalculate(); 1099 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1100 1101 // check the results 1102 QCOMPARE(fitResult.available, true); 1103 QCOMPARE(fitResult.valid, true); 1104 1105 QCOMPARE(np, 2); 1106 1107 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 337.99775062098 1108 FuzzyCompare(fitResult.paramValues.at(0), 3.3799746163E+02, 1.e-6); 1109 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 3.16358581006192 1110 FuzzyCompare(fitResult.errorValues.at(0), 3.1643950207E+00, 1.e-3); 1111 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000390390523934039 1112 FuzzyCompare(fitResult.paramValues.at(1), 3.9039091287E-04, 1.e-6); 1113 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 4.25373670682006e-06 1114 FuzzyCompare(fitResult.errorValues.at(1), 4.2547321834E-06, 1.e-3); 1115 1116 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0793014720259488 1117 FuzzyCompare(fitResult.rsd, 7.9301471998E-02, 1.e-9); 1118 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0754646815857881 1119 FuzzyCompare(fitResult.sse, 7.5464681533E-02, 1.e-9); 1120 } 1121 1122 void FitTest::testNonLinearMisra1b_2() { 1123 // NIST data for Misra1b dataset 1124 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1125 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1126 1127 // data source columns 1128 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1129 xDataColumn.replaceValues(0, xData); 1130 1131 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1132 yDataColumn.replaceValues(0, yData); 1133 1134 XYFitCurve fitCurve(QStringLiteral("fit")); 1135 fitCurve.setXDataColumn(&xDataColumn); 1136 fitCurve.setYDataColumn(&yDataColumn); 1137 1138 // prepare the fit 1139 XYFitCurve::FitData fitData = fitCurve.fitData(); 1140 fitData.modelCategory = nsl_fit_model_custom; 1141 XYFitCurve::initFitData(fitData); 1142 fitData.model = QStringLiteral("b1*(1-1/(1+b2*x/2)^2)"); 1143 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1144 fitData.eps = 1.e-12; 1145 const int np = fitData.paramNames.size(); 1146 fitData.paramStartValues << 300. << 2.e-4; 1147 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1148 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1149 fitCurve.setFitData(fitData); 1150 1151 // perform the fit 1152 fitCurve.recalculate(); 1153 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1154 1155 // check the results 1156 QCOMPARE(fitResult.available, true); 1157 QCOMPARE(fitResult.valid, true); 1158 1159 QCOMPARE(np, 2); 1160 1161 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 337.99775062098 1162 FuzzyCompare(fitResult.paramValues.at(0), 3.3799746163E+02, 1.e-6); 1163 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 3.16358581006192 1164 FuzzyCompare(fitResult.errorValues.at(0), 3.1643950207E+00, 1.e-3); 1165 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000390390523934039 1166 FuzzyCompare(fitResult.paramValues.at(1), 3.9039091287E-04, 1.e-5); 1167 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 4.25373670682006e-06 1168 FuzzyCompare(fitResult.errorValues.at(1), 4.2547321834E-06, 1.e-3); 1169 1170 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0793014720259488 1171 FuzzyCompare(fitResult.rsd, 7.9301471998E-02, 1.e-9); 1172 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0754646815857881 1173 FuzzyCompare(fitResult.sse, 7.5464681533E-02, 1.e-9); 1174 } 1175 1176 void FitTest::testNonLinearMisra1b_3() { 1177 // NIST data for Misra1b dataset 1178 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1179 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1180 1181 // data source columns 1182 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1183 xDataColumn.replaceValues(0, xData); 1184 1185 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1186 yDataColumn.replaceValues(0, yData); 1187 1188 XYFitCurve fitCurve(QStringLiteral("fit")); 1189 fitCurve.setXDataColumn(&xDataColumn); 1190 fitCurve.setYDataColumn(&yDataColumn); 1191 1192 // prepare the fit 1193 XYFitCurve::FitData fitData = fitCurve.fitData(); 1194 fitData.modelCategory = nsl_fit_model_custom; 1195 XYFitCurve::initFitData(fitData); 1196 fitData.model = QStringLiteral("b1*(1-1/(1+b2*x/2)^2)"); 1197 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1198 fitData.eps = 1.e-12; 1199 const int np = fitData.paramNames.size(); 1200 fitData.paramStartValues << 3.3799746163E+02 << 3.9039091287E-04; 1201 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1202 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1203 fitCurve.setFitData(fitData); 1204 1205 // perform the fit 1206 fitCurve.recalculate(); 1207 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1208 1209 // check the results 1210 QCOMPARE(fitResult.available, true); 1211 QCOMPARE(fitResult.valid, true); 1212 1213 QCOMPARE(np, 2); 1214 1215 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 337.99775062098 1216 FuzzyCompare(fitResult.paramValues.at(0), 3.3799746163E+02, 1.e-6); 1217 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 3.16358581006192 1218 FuzzyCompare(fitResult.errorValues.at(0), 3.1643950207E+00, 1.e-3); 1219 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000390390523934039 1220 FuzzyCompare(fitResult.paramValues.at(1), 3.9039091287E-04, 1.e-6); 1221 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 4.25373670682006e-06 1222 FuzzyCompare(fitResult.errorValues.at(1), 4.2547321834E-06, 1.e-3); 1223 1224 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0793014720259488 1225 FuzzyCompare(fitResult.rsd, 7.9301471998E-02, 1.e-9); 1226 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0754646815857881 1227 FuzzyCompare(fitResult.sse, 7.5464681533E-02, 1.e-9); 1228 } 1229 1230 void FitTest::testNonLinearMisra1c() { 1231 // NIST data for Misra1c dataset 1232 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1233 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1234 1235 // data source columns 1236 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1237 xDataColumn.replaceValues(0, xData); 1238 1239 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1240 yDataColumn.replaceValues(0, yData); 1241 1242 XYFitCurve fitCurve(QStringLiteral("fit")); 1243 fitCurve.setXDataColumn(&xDataColumn); 1244 fitCurve.setYDataColumn(&yDataColumn); 1245 1246 // prepare the fit 1247 XYFitCurve::FitData fitData = fitCurve.fitData(); 1248 fitData.modelCategory = nsl_fit_model_custom; 1249 XYFitCurve::initFitData(fitData); 1250 fitData.model = QStringLiteral("b1*(1-1/sqrt(1+2*b2*x))"); 1251 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1252 fitData.eps = 1.e-12; 1253 const int np = fitData.paramNames.size(); 1254 fitData.paramStartValues << 500. << 0.0001; 1255 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1256 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1257 fitCurve.setFitData(fitData); 1258 1259 // perform the fit 1260 fitCurve.recalculate(); 1261 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1262 1263 // check the results 1264 QCOMPARE(fitResult.available, true); 1265 QCOMPARE(fitResult.valid, true); 1266 1267 QCOMPARE(np, 2); 1268 1269 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 636.427904767969 1270 FuzzyCompare(fitResult.paramValues.at(0), 6.3642725809E+02, 1.e-5); 1271 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 4.66168062054875 1272 FuzzyCompare(fitResult.errorValues.at(0), 4.6638326572E+00, 1.e-3); 1273 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000208136026420746 1274 FuzzyCompare(fitResult.paramValues.at(1), 2.0813627256E-04, 1.e-5); 1275 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 1.77209416674174e-06 1276 FuzzyCompare(fitResult.errorValues.at(1), 1.7728423155E-06, 1.e-3); 1277 1278 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0584286153041661 1279 FuzzyCompare(fitResult.rsd, 5.8428615257E-02, 1.e-9); 1280 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0409668370363468 1281 FuzzyCompare(fitResult.sse, 4.0966836971E-02, 1.e-8); 1282 } 1283 1284 void FitTest::testNonLinearMisra1c_2() { 1285 // NIST data for Misra1c dataset 1286 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1287 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1288 1289 // data source columns 1290 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1291 xDataColumn.replaceValues(0, xData); 1292 1293 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1294 yDataColumn.replaceValues(0, yData); 1295 1296 XYFitCurve fitCurve(QStringLiteral("fit")); 1297 fitCurve.setXDataColumn(&xDataColumn); 1298 fitCurve.setYDataColumn(&yDataColumn); 1299 1300 // prepare the fit 1301 XYFitCurve::FitData fitData = fitCurve.fitData(); 1302 fitData.modelCategory = nsl_fit_model_custom; 1303 XYFitCurve::initFitData(fitData); 1304 fitData.model = QStringLiteral("b1*(1-1/sqrt(1+2*b2*x))"); 1305 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1306 fitData.eps = 1.e-12; 1307 const int np = fitData.paramNames.size(); 1308 fitData.paramStartValues << 600. << 2.e-4; 1309 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1310 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1311 fitCurve.setFitData(fitData); 1312 1313 // perform the fit 1314 fitCurve.recalculate(); 1315 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1316 1317 // check the results 1318 QCOMPARE(fitResult.available, true); 1319 QCOMPARE(fitResult.valid, true); 1320 1321 QCOMPARE(np, 2); 1322 1323 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 636.427904767969 1324 FuzzyCompare(fitResult.paramValues.at(0), 6.3642725809E+02, 1.e-5); 1325 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 4.66168062054875 1326 FuzzyCompare(fitResult.errorValues.at(0), 4.6638326572E+00, 1.e-3); 1327 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000208136026420746 1328 FuzzyCompare(fitResult.paramValues.at(1), 2.0813627256E-04, 1.e-5); 1329 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 1.77209416674174e-06 1330 FuzzyCompare(fitResult.errorValues.at(1), 1.7728423155E-06, 1.e-3); 1331 1332 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0584286153041661 (WIN: 0.0584286153252961) 1333 FuzzyCompare(fitResult.rsd, 5.8428615257E-02, 1.e-8); 1334 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0409668370363468 1335 FuzzyCompare(fitResult.sse, 4.0966836971E-02, 1.e-8); 1336 } 1337 1338 void FitTest::testNonLinearMisra1c_3() { 1339 // NIST data for Misra1c dataset 1340 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1341 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1342 1343 // data source columns 1344 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1345 xDataColumn.replaceValues(0, xData); 1346 1347 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1348 yDataColumn.replaceValues(0, yData); 1349 1350 XYFitCurve fitCurve(QStringLiteral("fit")); 1351 fitCurve.setXDataColumn(&xDataColumn); 1352 fitCurve.setYDataColumn(&yDataColumn); 1353 1354 // prepare the fit 1355 XYFitCurve::FitData fitData = fitCurve.fitData(); 1356 fitData.modelCategory = nsl_fit_model_custom; 1357 XYFitCurve::initFitData(fitData); 1358 fitData.model = QStringLiteral("b1*(1-1/sqrt(1+2*b2*x))"); 1359 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1360 fitData.eps = 1.e-12; 1361 const int np = fitData.paramNames.size(); 1362 fitData.paramStartValues << 6.3642725809E+02 << 2.0813627256E-04; 1363 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1364 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1365 fitCurve.setFitData(fitData); 1366 1367 // perform the fit 1368 fitCurve.recalculate(); 1369 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1370 1371 // check the results 1372 QCOMPARE(fitResult.available, true); 1373 QCOMPARE(fitResult.valid, true); 1374 1375 QCOMPARE(np, 2); 1376 1377 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 636.427904767969 1378 FuzzyCompare(fitResult.paramValues.at(0), 6.3642725809E+02, 1.e-5); 1379 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 4.66168062054875 1380 FuzzyCompare(fitResult.errorValues.at(0), 4.6638326572E+00, 1.e-3); 1381 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000208136026420746 1382 FuzzyCompare(fitResult.paramValues.at(1), 2.0813627256E-04, 1.e-5); 1383 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 1.77209416674174e-06 1384 FuzzyCompare(fitResult.errorValues.at(1), 1.7728423155E-06, 1.e-3); 1385 1386 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0584286153041661 1387 FuzzyCompare(fitResult.rsd, 5.8428615257E-02, 1.e-9); 1388 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0409668370363468 1389 FuzzyCompare(fitResult.sse, 4.0966836971E-02, 1.e-8); 1390 } 1391 1392 void FitTest::testNonLinearMisra1d() { 1393 // NIST data for Misra1d dataset 1394 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1395 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1396 1397 // data source columns 1398 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1399 xDataColumn.replaceValues(0, xData); 1400 1401 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1402 yDataColumn.replaceValues(0, yData); 1403 1404 XYFitCurve fitCurve(QStringLiteral("fit")); 1405 fitCurve.setXDataColumn(&xDataColumn); 1406 fitCurve.setYDataColumn(&yDataColumn); 1407 1408 // prepare the fit 1409 XYFitCurve::FitData fitData = fitCurve.fitData(); 1410 fitData.modelCategory = nsl_fit_model_custom; 1411 XYFitCurve::initFitData(fitData); 1412 fitData.model = QStringLiteral("b1*b2*x/(1+b2*x)"); 1413 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1414 fitData.eps = 1.e-12; 1415 const int np = fitData.paramNames.size(); 1416 fitData.paramStartValues << 500. << 0.0001; 1417 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1418 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1419 fitCurve.setFitData(fitData); 1420 1421 // perform the fit 1422 fitCurve.recalculate(); 1423 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1424 1425 // check the results 1426 QCOMPARE(fitResult.available, true); 1427 QCOMPARE(fitResult.valid, true); 1428 1429 QCOMPARE(np, 2); 1430 1431 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 437.370039987725 1432 FuzzyCompare(fitResult.paramValues.at(0), 4.3736970754E+02, 1.e-6); 1433 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 3.64772833062694 1434 FuzzyCompare(fitResult.errorValues.at(0), 3.6489174345E+00, 1.e-3); 1435 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000302272976784709 1436 FuzzyCompare(fitResult.paramValues.at(1), 3.0227324449E-04, 1.e-6); 1437 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.93256059733558e-06 1438 FuzzyCompare(fitResult.errorValues.at(1), 2.9334354479E-06, 1.e-3); 1439 1440 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.068568272134244 1441 FuzzyCompare(fitResult.rsd, 6.8568272111E-02, 1.e-9); 1442 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.056419295321709 (new: 0.0564192953613416) 1443 FuzzyCompare(fitResult.sse, 5.6419295283E-02, 1.e-8); 1444 } 1445 1446 void FitTest::testNonLinearMisra1d_2() { 1447 // NIST data for Misra1d dataset 1448 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1449 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1450 1451 // data source columns 1452 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1453 xDataColumn.replaceValues(0, xData); 1454 1455 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1456 yDataColumn.replaceValues(0, yData); 1457 1458 XYFitCurve fitCurve(QStringLiteral("fit")); 1459 fitCurve.setXDataColumn(&xDataColumn); 1460 fitCurve.setYDataColumn(&yDataColumn); 1461 1462 // prepare the fit 1463 XYFitCurve::FitData fitData = fitCurve.fitData(); 1464 fitData.modelCategory = nsl_fit_model_custom; 1465 XYFitCurve::initFitData(fitData); 1466 fitData.model = QStringLiteral("b1*b2*x/(1+b2*x)"); 1467 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1468 fitData.eps = 1.e-12; 1469 const int np = fitData.paramNames.size(); 1470 fitData.paramStartValues << 450. << 3.e-4; 1471 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1472 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1473 fitCurve.setFitData(fitData); 1474 1475 // perform the fit 1476 fitCurve.recalculate(); 1477 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1478 1479 // check the results 1480 QCOMPARE(fitResult.available, true); 1481 QCOMPARE(fitResult.valid, true); 1482 1483 QCOMPARE(np, 2); 1484 1485 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 437.370039987725 1486 FuzzyCompare(fitResult.paramValues.at(0), 4.3736970754E+02, 1.e-5); 1487 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 3.64772833062694 1488 FuzzyCompare(fitResult.errorValues.at(0), 3.6489174345E+00, 1.e-3); 1489 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000302272976784709 1490 FuzzyCompare(fitResult.paramValues.at(1), 3.0227324449E-04, 1.e-5); 1491 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.93256059733558e-06 1492 FuzzyCompare(fitResult.errorValues.at(1), 2.9334354479E-06, 1.e-3); 1493 1494 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.068568272134244 1495 FuzzyCompare(fitResult.rsd, 6.8568272111E-02, 1.e-9); 1496 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.056419295321709 1497 FuzzyCompare(fitResult.sse, 5.6419295283E-02, 1.e-8); 1498 } 1499 1500 void FitTest::testNonLinearMisra1d_3() { 1501 // NIST data for Misra1d dataset 1502 QVector<double> xData = {77.6E0, 114.9E0, 141.1E0, 190.8E0, 239.9E0, 289.0E0, 332.8E0, 378.4E0, 434.8E0, 477.3E0, 536.8E0, 593.1E0, 689.1E0, 760.0E0}; 1503 QVector<double> yData = {10.07E0, 14.73E0, 17.94E0, 23.93E0, 29.61E0, 35.18E0, 40.02E0, 44.82E0, 50.76E0, 55.05E0, 61.01E0, 66.40E0, 75.47E0, 81.78E0}; 1504 1505 // data source columns 1506 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1507 xDataColumn.replaceValues(0, xData); 1508 1509 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1510 yDataColumn.replaceValues(0, yData); 1511 1512 XYFitCurve fitCurve(QStringLiteral("fit")); 1513 fitCurve.setXDataColumn(&xDataColumn); 1514 fitCurve.setYDataColumn(&yDataColumn); 1515 1516 // prepare the fit 1517 XYFitCurve::FitData fitData = fitCurve.fitData(); 1518 fitData.modelCategory = nsl_fit_model_custom; 1519 XYFitCurve::initFitData(fitData); 1520 fitData.model = QStringLiteral("b1*b2*x/(1+b2*x)"); 1521 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2"); 1522 fitData.eps = 1.e-12; 1523 const int np = fitData.paramNames.size(); 1524 fitData.paramStartValues << 4.3736970754E+02 << 3.0227324449E-04; 1525 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1526 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1527 fitCurve.setFitData(fitData); 1528 1529 // perform the fit 1530 fitCurve.recalculate(); 1531 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1532 1533 // check the results 1534 QCOMPARE(fitResult.available, true); 1535 QCOMPARE(fitResult.valid, true); 1536 1537 QCOMPARE(np, 2); 1538 1539 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 437.370039987725 1540 FuzzyCompare(fitResult.paramValues.at(0), 4.3736970754E+02, 1.e-6); 1541 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 3.64772833062694 1542 FuzzyCompare(fitResult.errorValues.at(0), 3.6489174345E+00, 1.e-3); 1543 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.000302272976784709 1544 FuzzyCompare(fitResult.paramValues.at(1), 3.0227324449E-04, 1.e-6); 1545 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.93256059733558e-06 1546 FuzzyCompare(fitResult.errorValues.at(1), 2.9334354479E-06, 1.e-3); 1547 1548 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.068568272134244 1549 FuzzyCompare(fitResult.rsd, 6.8568272111E-02, 1.e-9); 1550 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.056419295321709 1551 FuzzyCompare(fitResult.sse, 5.6419295283E-02, 1.e-9); 1552 } 1553 1554 void FitTest::testNonLinearMGH09() { 1555 // NIST data for MGH09 dataset 1556 QVector<double> xData = {4.000000E+00, 1557 2.000000E+00, 1558 1.000000E+00, 1559 5.000000E-01, 1560 2.500000E-01, 1561 1.670000E-01, 1562 1.250000E-01, 1563 1.000000E-01, 1564 8.330000E-02, 1565 7.140000E-02, 1566 6.250000E-02}; 1567 QVector<double> yData = {1.957000E-01, 1568 1.947000E-01, 1569 1.735000E-01, 1570 1.600000E-01, 1571 8.440000E-02, 1572 6.270000E-02, 1573 4.560000E-02, 1574 3.420000E-02, 1575 3.230000E-02, 1576 2.350000E-02, 1577 2.460000E-02}; 1578 1579 // data source columns 1580 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1581 xDataColumn.replaceValues(0, xData); 1582 1583 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1584 yDataColumn.replaceValues(0, yData); 1585 1586 XYFitCurve fitCurve(QStringLiteral("fit")); 1587 fitCurve.setXDataColumn(&xDataColumn); 1588 fitCurve.setYDataColumn(&yDataColumn); 1589 1590 // prepare the fit 1591 XYFitCurve::FitData fitData = fitCurve.fitData(); 1592 fitData.modelCategory = nsl_fit_model_custom; 1593 XYFitCurve::initFitData(fitData); 1594 fitData.model = QStringLiteral("b1*(x^2 + b2*x)/(x^2 + x*b3 + b4)"); 1595 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3") << QStringLiteral("b4"); 1596 // fitData.eps = 1.e-12; 1597 const int np = fitData.paramNames.size(); 1598 fitData.paramStartValues << 2.5000000000E+01 << 3.9000000000E+01 << 4.1500000000E+01 << 3.9000000000E+01; 1599 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() 1600 << -std::numeric_limits<double>::max(); 1601 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() 1602 << std::numeric_limits<double>::max(); 1603 fitCurve.setFitData(fitData); 1604 1605 // perform the fit 1606 fitCurve.recalculate(); 1607 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1608 1609 // check the results 1610 QCOMPARE(fitResult.available, true); 1611 QCOMPARE(fitResult.valid, true); 1612 1613 QCOMPARE(np, 4); 1614 1615 // TODO: fit does not find global minimum 1616 /* DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 1617 FuzzyCompare(fitResult.paramValues.at(0), 1.9280693458E-01, 1.e-6); 1618 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 1619 FuzzyCompare(fitResult.errorValues.at(0), 1.1435312227E-02, 1.e-3); 1620 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 1621 FuzzyCompare(fitResult.paramValues.at(1), 1.9128232873E-01, 1.e-6); 1622 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 1623 FuzzyCompare(fitResult.errorValues.at(1), 1.9633220911E-01, 1.e-3); 1624 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 1625 FuzzyCompare(fitResult.paramValues.at(2), 1.2305650693E-01, 1.e-6); 1626 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 1627 FuzzyCompare(fitResult.errorValues.at(2), 8.0842031232E-02, 1.e-3); 1628 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: 1629 FuzzyCompare(fitResult.paramValues.at(3), 1.3606233068E-01, 1.e-6); 1630 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 1631 FuzzyCompare(fitResult.errorValues.at(3), 9.0025542308E-02, 1.e-3); 1632 1633 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1634 FuzzyCompare(fitResult.rsd, 6.6279236551E-03, 1.e-9); 1635 DEBUG(std::setprecision(15) << fitResult.sse); // result: 1636 FuzzyCompare(fitResult.sse, 3.0750560385E-04, 1.e-9); 1637 */ 1638 } 1639 1640 void FitTest::testNonLinearMGH09_2() { 1641 // NIST data for MGH09 dataset 1642 QVector<double> xData = {4.000000E+00, 1643 2.000000E+00, 1644 1.000000E+00, 1645 5.000000E-01, 1646 2.500000E-01, 1647 1.670000E-01, 1648 1.250000E-01, 1649 1.000000E-01, 1650 8.330000E-02, 1651 7.140000E-02, 1652 6.250000E-02}; 1653 QVector<double> yData = {1.957000E-01, 1654 1.947000E-01, 1655 1.735000E-01, 1656 1.600000E-01, 1657 8.440000E-02, 1658 6.270000E-02, 1659 4.560000E-02, 1660 3.420000E-02, 1661 3.230000E-02, 1662 2.350000E-02, 1663 2.460000E-02}; 1664 1665 // data source columns 1666 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1667 xDataColumn.replaceValues(0, xData); 1668 1669 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1670 yDataColumn.replaceValues(0, yData); 1671 1672 XYFitCurve fitCurve(QStringLiteral("fit")); 1673 fitCurve.setXDataColumn(&xDataColumn); 1674 fitCurve.setYDataColumn(&yDataColumn); 1675 1676 // prepare the fit 1677 XYFitCurve::FitData fitData = fitCurve.fitData(); 1678 fitData.modelCategory = nsl_fit_model_custom; 1679 XYFitCurve::initFitData(fitData); 1680 fitData.model = QStringLiteral("b1*(x^2 + b2*x)/(x^2 + x*b3 + b4)"); 1681 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3") << QStringLiteral("b4"); 1682 // fitData.eps = 1.e-12; 1683 const int np = fitData.paramNames.size(); 1684 fitData.paramStartValues << 2.5000000000E-01 << 3.9000000000E-01 << 4.1500000000E-01 << 3.9000000000E-01; 1685 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() 1686 << -std::numeric_limits<double>::max(); 1687 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() 1688 << std::numeric_limits<double>::max(); 1689 fitCurve.setFitData(fitData); 1690 1691 // perform the fit 1692 fitCurve.recalculate(); 1693 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1694 1695 // check the results 1696 QCOMPARE(fitResult.available, true); 1697 QCOMPARE(fitResult.valid, true); 1698 1699 QCOMPARE(np, 4); 1700 1701 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 1702 FuzzyCompare(fitResult.paramValues.at(0), 1.9280693458E-01, 1.e-5); 1703 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 1704 FuzzyCompare(fitResult.errorValues.at(0), 1.1435312227E-02, 1.e-4); 1705 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 1706 FuzzyCompare(fitResult.paramValues.at(1), 1.9128232873E-01, 1.e-3); 1707 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: (new: 0.196361378435283) 1708 FuzzyCompare(fitResult.errorValues.at(1), 1.9633220911E-01, 1.e-3); 1709 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 1710 FuzzyCompare(fitResult.paramValues.at(2), 1.2305650693E-01, 1.e-4); 1711 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 1712 FuzzyCompare(fitResult.errorValues.at(2), 8.0842031232E-02, 1.e-4); 1713 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: 1714 FuzzyCompare(fitResult.paramValues.at(3), 1.3606233068E-01, 1.e-4); 1715 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 1716 FuzzyCompare(fitResult.errorValues.at(3), 9.0025542308E-02, 1.e-4); 1717 1718 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1719 FuzzyCompare(fitResult.rsd, 6.6279236551E-03, 1.e-8); 1720 DEBUG(std::setprecision(15) << fitResult.sse); // result: 1721 FuzzyCompare(fitResult.sse, 3.0750560385E-04, 1.e-8); 1722 } 1723 1724 void FitTest::testNonLinearMGH09_3() { 1725 // NIST data for MGH09 dataset 1726 QVector<double> xData = {4.000000E+00, 1727 2.000000E+00, 1728 1.000000E+00, 1729 5.000000E-01, 1730 2.500000E-01, 1731 1.670000E-01, 1732 1.250000E-01, 1733 1.000000E-01, 1734 8.330000E-02, 1735 7.140000E-02, 1736 6.250000E-02}; 1737 QVector<double> yData = {1.957000E-01, 1738 1.947000E-01, 1739 1.735000E-01, 1740 1.600000E-01, 1741 8.440000E-02, 1742 6.270000E-02, 1743 4.560000E-02, 1744 3.420000E-02, 1745 3.230000E-02, 1746 2.350000E-02, 1747 2.460000E-02}; 1748 1749 // data source columns 1750 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1751 xDataColumn.replaceValues(0, xData); 1752 1753 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1754 yDataColumn.replaceValues(0, yData); 1755 1756 XYFitCurve fitCurve(QStringLiteral("fit")); 1757 fitCurve.setXDataColumn(&xDataColumn); 1758 fitCurve.setYDataColumn(&yDataColumn); 1759 1760 // prepare the fit 1761 XYFitCurve::FitData fitData = fitCurve.fitData(); 1762 fitData.modelCategory = nsl_fit_model_custom; 1763 XYFitCurve::initFitData(fitData); 1764 fitData.model = QStringLiteral("b1*(x^2 + b2*x)/(x^2 + x*b3 + b4)"); 1765 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3") << QStringLiteral("b4"); 1766 // fitData.eps = 1.e-12; 1767 const int np = fitData.paramNames.size(); 1768 fitData.paramStartValues << 1.9280693458E-01 << 1.9128232873E-01 << 1.2305650693E-01 << 1.3606233068E-01; 1769 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() 1770 << -std::numeric_limits<double>::max(); 1771 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() 1772 << std::numeric_limits<double>::max(); 1773 fitCurve.setFitData(fitData); 1774 1775 // perform the fit 1776 fitCurve.recalculate(); 1777 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1778 1779 // check the results 1780 QCOMPARE(fitResult.available, true); 1781 QCOMPARE(fitResult.valid, true); 1782 1783 QCOMPARE(np, 4); 1784 1785 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 1786 FuzzyCompare(fitResult.paramValues.at(0), 1.9280693458E-01, 1.e-9); 1787 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 1788 FuzzyCompare(fitResult.errorValues.at(0), 1.1435312227E-02, 1.e-5); 1789 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 1790 FuzzyCompare(fitResult.paramValues.at(1), 1.9128232873E-01, 1.e-9); 1791 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 1792 FuzzyCompare(fitResult.errorValues.at(1), 1.9633220911E-01, 1.e-5); 1793 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 1794 FuzzyCompare(fitResult.paramValues.at(2), 1.2305650693E-01, 1.e-9); 1795 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 1796 FuzzyCompare(fitResult.errorValues.at(2), 8.0842031232E-02, 1.e-5); 1797 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: 1798 FuzzyCompare(fitResult.paramValues.at(3), 1.3606233068E-01, 1.e-9); 1799 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 1800 FuzzyCompare(fitResult.errorValues.at(3), 9.0025542308E-02, 1.e-5); 1801 1802 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1803 FuzzyCompare(fitResult.rsd, 6.6279236551E-03, 1.e-9); 1804 DEBUG(std::setprecision(15) << fitResult.sse); // result: 1805 FuzzyCompare(fitResult.sse, 3.0750560385E-04, 1.e-9); 1806 } 1807 1808 void FitTest::testNonLinearMGH10() { 1809 // NIST data for MGH10 dataset 1810 QVector<double> xData = {5.000000E+01, 1811 5.500000E+01, 1812 6.000000E+01, 1813 6.500000E+01, 1814 7.000000E+01, 1815 7.500000E+01, 1816 8.000000E+01, 1817 8.500000E+01, 1818 9.000000E+01, 1819 9.500000E+01, 1820 1.000000E+02, 1821 1.050000E+02, 1822 1.100000E+02, 1823 1.150000E+02, 1824 1.200000E+02, 1825 1.250000E+02}; 1826 QVector<double> yData = {3.478000E+04, 1827 2.861000E+04, 1828 2.365000E+04, 1829 1.963000E+04, 1830 1.637000E+04, 1831 1.372000E+04, 1832 1.154000E+04, 1833 9.744000E+03, 1834 8.261000E+03, 1835 7.030000E+03, 1836 6.005000E+03, 1837 5.147000E+03, 1838 4.427000E+03, 1839 3.820000E+03, 1840 3.307000E+03, 1841 2.872000E+03}; 1842 1843 // data source columns 1844 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1845 xDataColumn.replaceValues(0, xData); 1846 1847 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1848 yDataColumn.replaceValues(0, yData); 1849 1850 XYFitCurve fitCurve(QStringLiteral("fit")); 1851 fitCurve.setXDataColumn(&xDataColumn); 1852 fitCurve.setYDataColumn(&yDataColumn); 1853 1854 // prepare the fit 1855 XYFitCurve::FitData fitData = fitCurve.fitData(); 1856 fitData.modelCategory = nsl_fit_model_custom; 1857 XYFitCurve::initFitData(fitData); 1858 fitData.model = QStringLiteral("b1*exp(b2/(x+b3))"); 1859 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3"); 1860 // fitData.eps = 1.e-12; 1861 const int np = fitData.paramNames.size(); 1862 fitData.paramStartValues << 2.0000000000E+00 << 4.0000000000E+05 << 2.5000000000E+04; 1863 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1864 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1865 fitCurve.setFitData(fitData); 1866 1867 // perform the fit 1868 fitCurve.recalculate(); 1869 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1870 1871 // check the results 1872 QCOMPARE(fitResult.available, true); 1873 QCOMPARE(fitResult.valid, true); 1874 1875 QCOMPARE(np, 3); 1876 1877 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 0.00560963848336205 (Windows: 0.00560964247264364) 1878 FuzzyCompare(fitResult.paramValues.at(0), 5.6096364710E-03, 1.e-5); 1879 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.000156888682057687 1880 FuzzyCompare(fitResult.errorValues.at(0), 1.5687892471E-04, 1.e-4); 1881 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 6181.34604697191 (Windows: 6181.34545410281) 1882 FuzzyCompare(fitResult.paramValues.at(1), 6.1813463463E+03, 1.e-6); 1883 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 23.3105479190063 1884 FuzzyCompare(fitResult.errorValues.at(1), 2.3309021107E+01, 1.e-4); 1885 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 345.223624540718 (Windows: 345.223579103645) 1886 FuzzyCompare(fitResult.paramValues.at(2), 3.4522363462E+02, 1.e-6); 1887 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.784915645388214 1888 FuzzyCompare(fitResult.errorValues.at(2), 7.8486103508E-01, 1.e-4); 1889 1890 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 2.6009740064923 (Windows: 2.60097400662837, 2.60097400697918) 1891 FuzzyCompare(fitResult.rsd, 2.6009740065E+00, 1.e-9); 1892 DEBUG(std::setprecision(15) << fitResult.sse); // result: 87.9458551718321 (FreeBSD: 87.9458551726946, Windows: 87.9458551810338) 1893 FuzzyCompare(fitResult.sse, 8.7945855171E+01, 1.e-9); 1894 } 1895 1896 void FitTest::testNonLinearMGH10_2() { 1897 // NIST data for MGH10 dataset 1898 QVector<double> xData = {5.000000E+01, 1899 5.500000E+01, 1900 6.000000E+01, 1901 6.500000E+01, 1902 7.000000E+01, 1903 7.500000E+01, 1904 8.000000E+01, 1905 8.500000E+01, 1906 9.000000E+01, 1907 9.500000E+01, 1908 1.000000E+02, 1909 1.050000E+02, 1910 1.100000E+02, 1911 1.150000E+02, 1912 1.200000E+02, 1913 1.250000E+02}; 1914 QVector<double> yData = {3.478000E+04, 1915 2.861000E+04, 1916 2.365000E+04, 1917 1.963000E+04, 1918 1.637000E+04, 1919 1.372000E+04, 1920 1.154000E+04, 1921 9.744000E+03, 1922 8.261000E+03, 1923 7.030000E+03, 1924 6.005000E+03, 1925 5.147000E+03, 1926 4.427000E+03, 1927 3.820000E+03, 1928 3.307000E+03, 1929 2.872000E+03}; 1930 1931 // data source columns 1932 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 1933 xDataColumn.replaceValues(0, xData); 1934 1935 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 1936 yDataColumn.replaceValues(0, yData); 1937 1938 XYFitCurve fitCurve(QStringLiteral("fit")); 1939 fitCurve.setXDataColumn(&xDataColumn); 1940 fitCurve.setYDataColumn(&yDataColumn); 1941 1942 // prepare the fit 1943 XYFitCurve::FitData fitData = fitCurve.fitData(); 1944 fitData.modelCategory = nsl_fit_model_custom; 1945 XYFitCurve::initFitData(fitData); 1946 fitData.model = QStringLiteral("b1*exp(b2/(x+b3))"); 1947 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3"); 1948 // fitData.eps = 1.e-12; 1949 const int np = fitData.paramNames.size(); 1950 fitData.paramStartValues << 2.0000000000E-02 << 4.0000000000E+03 << 2.5000000000E+02; 1951 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 1952 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 1953 fitCurve.setFitData(fitData); 1954 1955 // perform the fit 1956 fitCurve.recalculate(); 1957 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 1958 1959 // check the results 1960 QCOMPARE(fitResult.available, true); 1961 QCOMPARE(fitResult.valid, true); 1962 1963 QCOMPARE(np, 3); 1964 1965 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 0.00560963848336205 1966 FuzzyCompare(fitResult.paramValues.at(0), 5.6096364710E-03, 1.e-5); 1967 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.000156888586677272 1968 FuzzyCompare(fitResult.errorValues.at(0), 1.5687892471E-04, 1.e-4); 1969 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 6181.34604697191 1970 FuzzyCompare(fitResult.paramValues.at(1), 6.1813463463E+03, 1.e-6); 1971 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 23.3105167849511 1972 FuzzyCompare(fitResult.errorValues.at(1), 2.3309021107E+01, 1.e-4); 1973 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 345.223624540718 1974 FuzzyCompare(fitResult.paramValues.at(2), 3.4522363462E+02, 2.e-7); 1975 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.784914752553929 1976 FuzzyCompare(fitResult.errorValues.at(2), 7.8486103508E-01, 1.e-4); 1977 1978 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 2.6009740064923 1979 FuzzyCompare(fitResult.rsd, 2.6009740065E+00, 2.e-10); 1980 DEBUG(std::setprecision(15) << fitResult.sse); // result: 87.9458551718321 1981 FuzzyCompare(fitResult.sse, 8.7945855171E+01, 1.e-9); 1982 } 1983 1984 void FitTest::testNonLinearMGH10_3() { 1985 // NIST data for MGH10 dataset 1986 QVector<double> xData = {5.000000E+01, 1987 5.500000E+01, 1988 6.000000E+01, 1989 6.500000E+01, 1990 7.000000E+01, 1991 7.500000E+01, 1992 8.000000E+01, 1993 8.500000E+01, 1994 9.000000E+01, 1995 9.500000E+01, 1996 1.000000E+02, 1997 1.050000E+02, 1998 1.100000E+02, 1999 1.150000E+02, 2000 1.200000E+02, 2001 1.250000E+02}; 2002 QVector<double> yData = {3.478000E+04, 2003 2.861000E+04, 2004 2.365000E+04, 2005 1.963000E+04, 2006 1.637000E+04, 2007 1.372000E+04, 2008 1.154000E+04, 2009 9.744000E+03, 2010 8.261000E+03, 2011 7.030000E+03, 2012 6.005000E+03, 2013 5.147000E+03, 2014 4.427000E+03, 2015 3.820000E+03, 2016 3.307000E+03, 2017 2.872000E+03}; 2018 2019 // data source columns 2020 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2021 xDataColumn.replaceValues(0, xData); 2022 2023 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2024 yDataColumn.replaceValues(0, yData); 2025 2026 XYFitCurve fitCurve(QStringLiteral("fit")); 2027 fitCurve.setXDataColumn(&xDataColumn); 2028 fitCurve.setYDataColumn(&yDataColumn); 2029 2030 // prepare the fit 2031 XYFitCurve::FitData fitData = fitCurve.fitData(); 2032 fitData.modelCategory = nsl_fit_model_custom; 2033 XYFitCurve::initFitData(fitData); 2034 fitData.model = QStringLiteral("b1*exp(b2/(x+b3))"); 2035 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3"); 2036 // fitData.eps = 1.e-12; 2037 const int np = fitData.paramNames.size(); 2038 fitData.paramStartValues << 5.6096364710E-03 << 6.1813463463E+03 << 3.4522363462E+02; 2039 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max(); 2040 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max(); 2041 fitCurve.setFitData(fitData); 2042 2043 // perform the fit 2044 fitCurve.recalculate(); 2045 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2046 2047 // check the results 2048 QCOMPARE(fitResult.available, true); 2049 QCOMPARE(fitResult.valid, true); 2050 2051 QCOMPARE(np, 3); 2052 2053 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 0.00560963848336205 2054 FuzzyCompare(fitResult.paramValues.at(0), 5.6096364710E-03, 1.e-6); 2055 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.000156888348998521 2056 FuzzyCompare(fitResult.errorValues.at(0), 1.5687892471E-04, 1.e-4); 2057 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 6181.34604697191 2058 FuzzyCompare(fitResult.paramValues.at(1), 6.1813463463E+03, 1.e-7); 2059 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 23.310508065631 2060 FuzzyCompare(fitResult.errorValues.at(1), 2.3309021107E+01, 1.e-4); 2061 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 345.223624540718 2062 FuzzyCompare(fitResult.paramValues.at(2), 3.4522363462E+02, 1.e-7); 2063 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.784914424350028 2064 FuzzyCompare(fitResult.errorValues.at(2), 7.8486103508E-01, 1.e-4); 2065 2066 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 2.6009740064923 2067 FuzzyCompare(fitResult.rsd, 2.6009740065E+00, 1.e-11); 2068 DEBUG(std::setprecision(15) << fitResult.sse); // result: 87.9458551718321 2069 FuzzyCompare(fitResult.sse, 8.7945855171E+01, 1.e-11); 2070 } 2071 2072 void FitTest::testNonLinearRat43() { 2073 // NIST data for Rat43 dataset 2074 QVector<double> xData = {1.0E0, 2.0E0, 3.0E0, 4.0E0, 5.0E0, 6.0E0, 7.0E0, 8.0E0, 9.0E0, 10.0E0, 11.0E0, 12.0E0, 13.0E0, 14.0E0, 15.0E0}; 2075 QVector<double> yData = 2076 {16.08E0, 33.83E0, 65.80E0, 97.20E0, 191.55E0, 326.20E0, 386.87E0, 520.53E0, 590.03E0, 651.92E0, 724.93E0, 699.56E0, 689.96E0, 637.56E0, 717.41E0}; 2077 2078 // data source columns 2079 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2080 xDataColumn.replaceValues(0, xData); 2081 2082 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2083 yDataColumn.replaceValues(0, yData); 2084 2085 XYFitCurve fitCurve(QStringLiteral("fit")); 2086 fitCurve.setXDataColumn(&xDataColumn); 2087 fitCurve.setYDataColumn(&yDataColumn); 2088 2089 // prepare the fit 2090 XYFitCurve::FitData fitData = fitCurve.fitData(); 2091 fitData.modelCategory = nsl_fit_model_custom; 2092 XYFitCurve::initFitData(fitData); 2093 fitData.model = QStringLiteral("b1/pow(1 + exp(b2-b3*x); 1/b4)"); 2094 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3") << QStringLiteral("b4"); 2095 fitData.eps = 1.e-9; 2096 const int np = fitData.paramNames.size(); 2097 fitData.paramStartValues << 1.0000000000E+02 << 1.0000000000E+01 << 1.0000000000E+00 << 1.0000000000E+00; 2098 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() 2099 << -std::numeric_limits<double>::max(); 2100 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() 2101 << std::numeric_limits<double>::max(); 2102 fitCurve.setFitData(fitData); 2103 2104 // perform the fit 2105 fitCurve.recalculate(); 2106 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2107 2108 // check the results 2109 QCOMPARE(fitResult.available, true); 2110 QCOMPARE(fitResult.valid, true); 2111 2112 QCOMPARE(np, 4); 2113 2114 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 699.641340982193 2115 FuzzyCompare(fitResult.paramValues.at(0), 6.9964151270E+02, 1.e-6); 2116 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 16.3022524293302 2117 FuzzyCompare(fitResult.errorValues.at(0), 1.6302297817E+01, 1.e-5); 2118 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 5.2771555758844 2119 FuzzyCompare(fitResult.paramValues.at(1), 5.2771253025E+00, 1.e-5); 2120 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.08290034908325 2121 FuzzyCompare(fitResult.errorValues.at(1), 2.0828735829E+00, 1.e-4); 2122 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 0.759632366113637 2123 FuzzyCompare(fitResult.paramValues.at(2), 7.5962938329E-01, 1.e-5); 2124 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.195664372178938 2125 FuzzyCompare(fitResult.errorValues.at(2), 1.9566123451E-01, 1.e-4); 2126 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: 1.27925748993867 2127 FuzzyCompare(fitResult.paramValues.at(3), 1.2792483859E+00, 1.e-5); 2128 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 0.687627478905195 2129 FuzzyCompare(fitResult.errorValues.at(3), 6.8761936385E-01, 1.e-4); 2130 2131 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 28.2624146626284 2132 FuzzyCompare(fitResult.rsd, 2.8262414662E+01, 1.e-10); 2133 DEBUG(std::setprecision(15) << fitResult.sse); // result: 8786.4049081859 2134 FuzzyCompare(fitResult.sse, 8.7864049080E+03, 1.e-10); 2135 } 2136 2137 void FitTest::testNonLinearRat43_2() { 2138 // NIST data for Rat43 dataset 2139 QVector<double> xData = {1.0E0, 2.0E0, 3.0E0, 4.0E0, 5.0E0, 6.0E0, 7.0E0, 8.0E0, 9.0E0, 10.0E0, 11.0E0, 12.0E0, 13.0E0, 14.0E0, 15.0E0}; 2140 QVector<double> yData = 2141 {16.08E0, 33.83E0, 65.80E0, 97.20E0, 191.55E0, 326.20E0, 386.87E0, 520.53E0, 590.03E0, 651.92E0, 724.93E0, 699.56E0, 689.96E0, 637.56E0, 717.41E0}; 2142 2143 // data source columns 2144 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2145 xDataColumn.replaceValues(0, xData); 2146 2147 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2148 yDataColumn.replaceValues(0, yData); 2149 2150 XYFitCurve fitCurve(QStringLiteral("fit")); 2151 fitCurve.setXDataColumn(&xDataColumn); 2152 fitCurve.setYDataColumn(&yDataColumn); 2153 2154 // prepare the fit 2155 XYFitCurve::FitData fitData = fitCurve.fitData(); 2156 fitData.modelCategory = nsl_fit_model_custom; 2157 XYFitCurve::initFitData(fitData); 2158 fitData.model = QStringLiteral("b1/pow(1 + exp(b2-b3*x); 1/b4)"); 2159 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3") << QStringLiteral("b4"); 2160 fitData.eps = 1.e-10; 2161 const int np = fitData.paramNames.size(); 2162 fitData.paramStartValues << 7.0000000000E+02 << 5.0000000000E+00 << 7.5000000000E-01 << 1.3000000000E+00; 2163 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() 2164 << -std::numeric_limits<double>::max(); 2165 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() 2166 << std::numeric_limits<double>::max(); 2167 fitCurve.setFitData(fitData); 2168 2169 // perform the fit 2170 fitCurve.recalculate(); 2171 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2172 2173 // check the results 2174 QCOMPARE(fitResult.available, true); 2175 QCOMPARE(fitResult.valid, true); 2176 2177 QCOMPARE(np, 4); 2178 2179 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 699.641340982193 2180 FuzzyCompare(fitResult.paramValues.at(0), 6.9964151270E+02, 1.e-6); 2181 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 16.3023134145464 (FreeBSD: 16.3023141645004) 2182 FuzzyCompare(fitResult.errorValues.at(0), 1.6302297817E+01, 1.e-5); 2183 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 5.2771555758844 2184 FuzzyCompare(fitResult.paramValues.at(1), 5.2771253025E+00, 1.e-5); 2185 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.08288970703906 2186 FuzzyCompare(fitResult.errorValues.at(1), 2.0828735829E+00, 1.e-5); 2187 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 0.759632366113637 2188 FuzzyCompare(fitResult.paramValues.at(2), 7.5962938329E-01, 1.e-5); 2189 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.195662802156063 2190 FuzzyCompare(fitResult.errorValues.at(2), 1.9566123451E-01, 1.e-5); 2191 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: 1.27925748993867 2192 FuzzyCompare(fitResult.paramValues.at(3), 1.2792483859E+00, 1.e-5); 2193 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 0.687623222160242 2194 FuzzyCompare(fitResult.errorValues.at(3), 6.8761936385E-01, 1.e-5); 2195 2196 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 28.2624146626284 2197 FuzzyCompare(fitResult.rsd, 2.8262414662E+01, 1.e-10); 2198 DEBUG(std::setprecision(15) << fitResult.sse); // result: 8786.4049081859 2199 FuzzyCompare(fitResult.sse, 8.7864049080E+03, 1.e-11); 2200 } 2201 2202 void FitTest::testNonLinearRat43_3() { 2203 // NIST data for Rat43 dataset 2204 QVector<double> xData = {1.0E0, 2.0E0, 3.0E0, 4.0E0, 5.0E0, 6.0E0, 7.0E0, 8.0E0, 9.0E0, 10.0E0, 11.0E0, 12.0E0, 13.0E0, 14.0E0, 15.0E0}; 2205 QVector<double> yData = 2206 {16.08E0, 33.83E0, 65.80E0, 97.20E0, 191.55E0, 326.20E0, 386.87E0, 520.53E0, 590.03E0, 651.92E0, 724.93E0, 699.56E0, 689.96E0, 637.56E0, 717.41E0}; 2207 2208 // data source columns 2209 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2210 xDataColumn.replaceValues(0, xData); 2211 2212 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2213 yDataColumn.replaceValues(0, yData); 2214 2215 XYFitCurve fitCurve(QStringLiteral("fit")); 2216 fitCurve.setXDataColumn(&xDataColumn); 2217 fitCurve.setYDataColumn(&yDataColumn); 2218 2219 // prepare the fit 2220 XYFitCurve::FitData fitData = fitCurve.fitData(); 2221 fitData.modelCategory = nsl_fit_model_custom; 2222 XYFitCurve::initFitData(fitData); 2223 fitData.model = QStringLiteral("b1/pow(1 + exp(b2-b3*x); 1/b4)"); 2224 fitData.paramNames << QStringLiteral("b1") << QStringLiteral("b2") << QStringLiteral("b3") << QStringLiteral("b4"); 2225 // fitData.eps = 1.e-12; 2226 const int np = fitData.paramNames.size(); 2227 fitData.paramStartValues << 6.9964151270E+02 << 5.2771253025E+00 << 7.5962938329E-01 << 1.2792483859E+00; 2228 fitData.paramLowerLimits << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() << -std::numeric_limits<double>::max() 2229 << -std::numeric_limits<double>::max(); 2230 fitData.paramUpperLimits << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() << std::numeric_limits<double>::max() 2231 << std::numeric_limits<double>::max(); 2232 fitCurve.setFitData(fitData); 2233 2234 // perform the fit 2235 fitCurve.recalculate(); 2236 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2237 2238 // check the results 2239 QCOMPARE(fitResult.available, true); 2240 QCOMPARE(fitResult.valid, true); 2241 2242 QCOMPARE(np, 4); 2243 2244 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 699.641340982193 2245 FuzzyCompare(fitResult.paramValues.at(0), 6.9964151270E+02, 1.e-8); 2246 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 16.3022905400761 2247 FuzzyCompare(fitResult.errorValues.at(0), 1.6302297817E+01, 1.e-6); 2248 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 5.2771555758844 2249 FuzzyCompare(fitResult.paramValues.at(1), 5.2771253025E+00, 1.e-8); 2250 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 2.08289316520407 2251 FuzzyCompare(fitResult.errorValues.at(1), 2.0828735829E+00, 1.e-5); 2252 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: 0.759632366113637 2253 FuzzyCompare(fitResult.paramValues.at(2), 7.5962938329E-01, 1.e-8); 2254 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 0.195663312668779 2255 FuzzyCompare(fitResult.errorValues.at(2), 1.9566123451E-01, 1.e-4); 2256 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: 1.27925748993867 2257 FuzzyCompare(fitResult.paramValues.at(3), 1.2792483859E+00, 1.e-8); 2258 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 0.687624541478887 2259 FuzzyCompare(fitResult.errorValues.at(3), 6.8761936385E-01, 1.e-5); 2260 2261 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 28.2624146626284 2262 FuzzyCompare(fitResult.rsd, 2.8262414662E+01, 1.e-11); 2263 DEBUG(std::setprecision(15) << fitResult.sse); // result: 8786.4049081859 2264 FuzzyCompare(fitResult.sse, 8.7864049080E+03, 1.e-11); 2265 } 2266 2267 // https://bugs.kde.org/show_bug.cgi?id=393213 2268 void FitTest::testNonLinearMichaelis_Menten() { 2269 // generic data 2270 QVector<double> xData = {0.0, 0.2, 0.4, 0.6, 0.8, 1.0, 1.2, 1.4, 1.6, 1.8, 2.0}; 2271 QVector<double> yData = {0.0, 0.6, 0.65, 0.7, 0.75, 0.75, 0.8, 0.9, 0.85, 0.95, 0.9}; 2272 2273 // data source columns 2274 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2275 xDataColumn.replaceValues(0, xData); 2276 2277 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2278 yDataColumn.replaceValues(0, yData); 2279 2280 XYFitCurve fitCurve(QStringLiteral("fit")); 2281 fitCurve.setXDataColumn(&xDataColumn); 2282 fitCurve.setYDataColumn(&yDataColumn); 2283 2284 // prepare the fit 2285 XYFitCurve::FitData fitData = fitCurve.fitData(); 2286 fitData.modelCategory = nsl_fit_model_custom; 2287 XYFitCurve::initFitData(fitData); 2288 fitData.model = QStringLiteral("Vm * x/(Km + x)"); 2289 fitData.paramNames << QStringLiteral("Vm") << QStringLiteral("Km"); 2290 fitData.eps = 1.e-12; 2291 const int np = fitData.paramNames.size(); 2292 fitData.paramStartValues << 1.0 << 1.0; 2293 for (int i = 0; i < np; i++) { 2294 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2295 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2296 } 2297 fitCurve.setFitData(fitData); 2298 2299 // perform the fit 2300 fitCurve.recalculate(); 2301 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2302 2303 // check the results 2304 QCOMPARE(fitResult.available, true); 2305 QCOMPARE(fitResult.valid, true); 2306 2307 QCOMPARE(np, 2); 2308 2309 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 0.945561082955744 2310 FuzzyCompare(fitResult.paramValues.at(0), 0.94556434933256, 1.e-5); 2311 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.0388724403232334 2312 FuzzyCompare(fitResult.errorValues.at(0), 0.0388803714011844, 3.e-4); 2313 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 0.159396945453528 2314 FuzzyCompare(fitResult.paramValues.at(1), 0.159400761666661, 3.e-5); 2315 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0388244491752518 2316 FuzzyCompare(fitResult.errorValues.at(1), 0.0388429738447119, 5.e-4); 2317 2318 DEBUG(std::setprecision(15) << fitResult.rms); // result: 0.00280486748619082 2319 FuzzyCompare(fitResult.rms, 0.00280486748877263, 1.e-9); 2320 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.0529609996713697 2321 FuzzyCompare(fitResult.rsd, 0.0529609996957444, 1.e-9); 2322 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.0252438073757174 2323 FuzzyCompare(fitResult.sse, 0.0252438073989537, 1.e-9); 2324 } 2325 // ############################################################################## 2326 // ######################### Fits with weights ################################# 2327 // ############################################################################## 2328 2329 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2330 void FitTest::testNonLinearGP_lcdemo() { 2331 // data from https://github.com/gnuplot/gnuplot/blob/master/demo/lcdemo.dat 2332 QVector<double> xData = {39.471, 40.091, 40.602, 41.058, 41.438, 41.880, 42.437, 42.836, 43.209, 43.599, 43.997, 44.313, 44.908, 2333 45.169, 45.594, 45.743, 45.796, 45.816, 45.841, 45.876, 45.908, 45.959, 46.008, 46.040, 46.060, 46.096, 2334 46.126, 46.149, 46.372, 46.625, 46.945, 47.326, 47.708, 48.095, 48.540, 48.927, 49.314}; 2335 QVector<double> yData = {1.03307, 1.03246, 1.03197, 1.03153, 1.03117, 1.03074, 1.03021, 1.02982, 1.02946, 1.02907, 1.02867, 1.02833, 1.02765, 2336 1.02735, 1.02683, 1.02661, 1.02650, 1.02644, 1.02634, 1.02623, 1.02611, 1.02592, 1.02561, 1.02526, 1.02506, 1.02500, 2337 1.02496, 1.02494, 1.02474, 1.02452, 1.02425, 1.02393, 1.02361, 1.02329, 1.02293, 1.02262, 1.02231}; 2338 QVector<double> yError = {0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 2339 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.010, 0.001, 0.001, 0.001, 0.001, 2340 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001, 0.001}; 2341 2342 // data source columns 2343 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2344 xDataColumn.replaceValues(0, xData); 2345 2346 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2347 yDataColumn.replaceValues(0, yData); 2348 2349 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2350 yErrorColumn.replaceValues(0, yError); 2351 2352 XYFitCurve fitCurve(QStringLiteral("fit")); 2353 fitCurve.setXDataColumn(&xDataColumn); 2354 fitCurve.setYDataColumn(&yDataColumn); 2355 fitCurve.setYErrorColumn(&yErrorColumn); 2356 2357 // prepare the fit 2358 XYFitCurve::FitData fitData = fitCurve.fitData(); 2359 fitData.modelCategory = nsl_fit_model_custom; 2360 XYFitCurve::initFitData(fitData); 2361 // x > Tc : d + mh(x-Tc) 2362 // x < Tc : d + ml(x-Tc) + b tanh(g(Tc-x)) 2363 fitData.model = QStringLiteral("d + theta(x-Tc)*mh*(x-Tc) + theta(Tc-x)*(ml*(x-Tc)+b*tanh(g*(Tc-x)))"); 2364 fitData.paramNames << QStringLiteral("d") << QStringLiteral("Tc") << QStringLiteral("mh") << QStringLiteral("ml") << QStringLiteral("b") 2365 << QStringLiteral("g"); 2366 fitData.eps = 1.e-12; 2367 const int np = fitData.paramNames.size(); 2368 fitData.paramStartValues << 1.02 << 45. << -0.0005 << -0.0005 << 0.01002 << 1.0; 2369 for (int i = 0; i < np; i++) { 2370 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2371 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2372 } 2373 fitData.yWeightsType = nsl_fit_weight_instrumental; 2374 fitCurve.setFitData(fitData); 2375 2376 // perform the fit 2377 fitCurve.recalculate(); 2378 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2379 2380 // check the results 2381 QCOMPARE(fitResult.available, true); 2382 QCOMPARE(fitResult.valid, true); 2383 2384 QCOMPARE(np, 6); 2385 2386 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 1.02499979307627 (Windows: 1.02561781433026) 2387 FuzzyCompare(fitResult.paramValues.at(0), 1.02499621370905, 1.e-3); 2388 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 4.81672854812941e-06 2389 // TODO FuzzyCompare(fitResult.errorValues.at(0), 7.27819513635249e-06, 1.e-6); 2390 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 46.0647953740441 (Windows: 45.4871250830364) 2391 FuzzyCompare(fitResult.paramValues.at(1), 46.0665367045608, 2.e-2); 2392 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 9.90288940612482 2393 // TODO FuzzyCompare(fitResult.errorValues.at(1), 0.00159887430059728, 1.e-6); 2394 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); // result: -0.000835023995828296 (Windows: -0.000883960665773456) 2395 FuzzyCompare(fitResult.paramValues.at(2), -0.0008340717673769, 1.e-1); 2396 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); // result: 2397 // TODO FuzzyCompare(fitResult.errorValues.at(2), , 1.e-6); 2398 DEBUG(std::setprecision(15) << fitResult.paramValues.at(3)); // result: -0.000987547207638997 2399 FuzzyCompare(fitResult.paramValues.at(3), -0.00103152542276233, 1.e-1); 2400 DEBUG(std::setprecision(15) << fitResult.errorValues.at(3)); // result: 2401 // TODO FuzzyCompare(fitResult.errorValues.at(3), , 1.e-6); 2402 DEBUG(std::setprecision(15) << fitResult.paramValues.at(4)); // result: 0.00158880319355268 2403 FuzzyCompare(fitResult.paramValues.at(4), 0.00139548391000006, 1.5e-1); 2404 DEBUG(std::setprecision(15) << fitResult.errorValues.at(4)); // result: 2405 // TODO FuzzyCompare(fitResult.errorValues.at(4), , 1.e-6); 2406 DEBUG(std::setprecision(15) << fitResult.paramValues.at(5)); // result: 6.34254053273612 (Windows: 4.45482397068125) 2407 // FuzzyCompare(fitResult.paramValues.at(5), 6.92493866108287, 1.e-1); 2408 DEBUG(std::setprecision(15) << fitResult.errorValues.at(5)); // result: 2409 // TODO FuzzyCompare(fitResult.errorValues.at(5), , 1.e-6); 2410 2411 DEBUG(std::setprecision(15) << fitResult.rms); // result: 98.0672185899393 2412 // FuzzyCompare(fitResult.rms, 0.000188776, 1.e-11); 2413 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 9.90288940612482 2414 // FuzzyCompare(fitResult.rsd, 0.0137395924378767, 1.e-11); 2415 DEBUG(std::setprecision(15) << fitResult.sse); // result: 3040.08377628812 2416 // FuzzyCompare(fitResult.sse, 0.00585206841112775, 1.e-11); 2417 } 2418 2419 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2420 void FitTest::testLinearGP_PY_noerror() { 2421 // Pearson's data and York's weights 2422 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2423 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2424 // QVector<double> xError = {1000.,1000.,500.,800.,200.,80.,60.,20.,1.8,1.0}; 2425 // QVector<double> yError = {1.0,1.8,4.,8.,20.,20.,70.,70.,100.,500.}; 2426 2427 // data source columns 2428 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2429 xDataColumn.replaceValues(0, xData); 2430 2431 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2432 yDataColumn.replaceValues(0, yData); 2433 2434 // Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2435 // yErrorColumn.replaceValues(0, yError); 2436 2437 XYFitCurve fitCurve(QStringLiteral("fit")); 2438 fitCurve.setXDataColumn(&xDataColumn); 2439 fitCurve.setYDataColumn(&yDataColumn); 2440 // fitCurve.setYErrorColumn(&yErrorColumn); 2441 2442 // prepare the fit 2443 XYFitCurve::FitData fitData = fitCurve.fitData(); 2444 fitData.modelCategory = nsl_fit_model_custom; 2445 XYFitCurve::initFitData(fitData); 2446 fitData.model = QStringLiteral("a1 + a2 * x"); 2447 fitData.paramNames << QStringLiteral("a1") << QStringLiteral("a2"); 2448 fitData.eps = 1.e-9; 2449 const int np = fitData.paramNames.size(); 2450 fitData.paramStartValues << 5. << -0.5; 2451 for (int i = 0; i < np; i++) { 2452 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2453 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2454 } 2455 // fitData.yWeightsType = nsl_fit_weight_instrumental; 2456 fitCurve.setFitData(fitData); 2457 2458 // perform the fit 2459 fitCurve.recalculate(); 2460 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2461 2462 // check the results 2463 QCOMPARE(fitResult.available, true); 2464 QCOMPARE(fitResult.valid, true); 2465 2466 QCOMPARE(np, 2); 2467 2468 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 5.76118518568804 2469 FuzzyCompare(fitResult.paramValues.at(0), 5.76118519043878, 1.e-9); 2470 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.189485192391863 2471 FuzzyCompare(fitResult.errorValues.at(0), 0.189485195921141, 1.e-7); 2472 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.539577274076964 2473 FuzzyCompare(fitResult.paramValues.at(1), -0.539577274983977, 1.e-8); 2474 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0421265487265946 2475 FuzzyCompare(fitResult.errorValues.at(1), 0.0421265483886995, 1.e-8); 2476 2477 DEBUG(std::setprecision(15) << fitResult.rms); // result: 0.100082940279452 2478 QCOMPARE(fitResult.rms, 0.100082940279452); 2479 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 0.316358878932538 2480 QCOMPARE(fitResult.rsd, 0.316358878932538); 2481 DEBUG(std::setprecision(15) << fitResult.sse); // result: 0.800663522235619 2482 QCOMPARE(fitResult.sse, 0.800663522235619); 2483 } 2484 2485 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2486 void FitTest::testLinearGP_PY_yerror_polynomial() { 2487 // Pearson's data and York's weights 2488 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2489 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2490 // QVector<double> xError = {1000.,1000.,500.,800.,200.,80.,60.,20.,1.8,1.0}; 2491 QVector<double> yError = {1.0, 1.8, 4., 8., 20., 20., 70., 70., 100., 500.}; 2492 2493 // data source columns 2494 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2495 xDataColumn.replaceValues(0, xData); 2496 2497 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2498 yDataColumn.replaceValues(0, yData); 2499 2500 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2501 yErrorColumn.replaceValues(0, yError); 2502 2503 XYFitCurve fitCurve(QStringLiteral("fit")); 2504 fitCurve.setXDataColumn(&xDataColumn); 2505 fitCurve.setYDataColumn(&yDataColumn); 2506 fitCurve.setYErrorColumn(&yErrorColumn); 2507 2508 // prepare the fit 2509 XYFitCurve::FitData fitData = fitCurve.fitData(); 2510 fitData.modelCategory = nsl_fit_model_basic; 2511 fitData.modelType = nsl_fit_model_polynomial; 2512 fitData.degree = 1; 2513 XYFitCurve::initFitData(fitData); 2514 // fitData.eps = 1.e-12; 2515 const int np = fitData.paramNames.size(); 2516 fitData.paramStartValues << 5. << -0.5; 2517 fitData.yWeightsType = nsl_fit_weight_direct; 2518 fitCurve.setFitData(fitData); 2519 2520 // perform the fit 2521 fitCurve.recalculate(); 2522 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2523 2524 // check the results 2525 QCOMPARE(fitResult.available, true); 2526 QCOMPARE(fitResult.valid, true); 2527 2528 QCOMPARE(np, 2); 2529 2530 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 6.10010931666575 2531 FuzzyCompare(fitResult.paramValues.at(0), 6.10010931635002, 1.e-10); 2532 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.424059452104775, i386: 0.424059429083679 2533 FuzzyCompare(fitResult.errorValues.at(0), 0.424059452104785, 1.e-10); 2534 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.610812956583933, i386: -0.610812954591566 2535 FuzzyCompare(fitResult.paramValues.at(1), -0.610812956537254, 1.e-9); 2536 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0623409539388997, i386: 0.0623409508171503 2537 FuzzyCompare(fitResult.errorValues.at(1), 0.0623409539389024, 1.e-10); 2538 2539 QCOMPARE(fitResult.rms, 4.29315093729054); 2540 QCOMPARE(fitResult.rsd, 2.07199202153158); 2541 QCOMPARE(fitResult.sse, 34.3452074983243); 2542 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.000101015996328551 2543 // TODO QCOMPARE(fitResult.fdist_p, 3.51725605201025e-05); 2544 } 2545 2546 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2547 void FitTest::testLinearGP_PY_yerror_custom() { 2548 // Pearson's data and York's weights 2549 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2550 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2551 // QVector<double> xError = {1000.,1000.,500.,800.,200.,80.,60.,20.,1.8,1.0}; 2552 QVector<double> yError = {1.0, 1.8, 4., 8., 20., 20., 70., 70., 100., 500.}; 2553 2554 // data source columns 2555 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2556 xDataColumn.replaceValues(0, xData); 2557 2558 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2559 yDataColumn.replaceValues(0, yData); 2560 2561 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2562 yErrorColumn.replaceValues(0, yError); 2563 2564 XYFitCurve fitCurve(QStringLiteral("fit")); 2565 fitCurve.setXDataColumn(&xDataColumn); 2566 fitCurve.setYDataColumn(&yDataColumn); 2567 fitCurve.setYErrorColumn(&yErrorColumn); 2568 2569 // prepare the fit 2570 XYFitCurve::FitData fitData = fitCurve.fitData(); 2571 fitData.modelCategory = nsl_fit_model_custom; 2572 XYFitCurve::initFitData(fitData); 2573 fitData.model = QStringLiteral("a1 + a2 * x"); 2574 fitData.paramNames << QStringLiteral("a1") << QStringLiteral("a2"); 2575 fitData.eps = 1.e-9; 2576 const int np = fitData.paramNames.size(); 2577 fitData.paramStartValues << 5. << -0.5; 2578 for (int i = 0; i < np; i++) { 2579 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2580 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2581 } 2582 2583 fitData.yWeightsType = nsl_fit_weight_direct; 2584 fitCurve.setFitData(fitData); 2585 2586 // perform the fit 2587 fitCurve.recalculate(); 2588 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2589 2590 // check the results 2591 QCOMPARE(fitResult.available, true); 2592 QCOMPARE(fitResult.valid, true); 2593 2594 QCOMPARE(np, 2); 2595 2596 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 6.10010932451396 2597 FuzzyCompare(fitResult.paramValues.at(0), 6.10010931635002, 1.e-8); 2598 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.424059453530443 (new: 0.424059492144904) 2599 FuzzyCompare(fitResult.errorValues.at(0), 0.424059452104785, 1.e-7); 2600 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.610812957040808 (new: -0.610812955065274) 2601 FuzzyCompare(fitResult.paramValues.at(1), -0.610812956537254, 1.e-8); 2602 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0623409543258892 (new: 0.0623409596911536) 2603 FuzzyCompare(fitResult.errorValues.at(1), 0.0623409539389024, 1.e-7); 2604 2605 QCOMPARE(fitResult.rms, 4.29315093729054); 2606 QCOMPARE(fitResult.rsd, 2.07199202153158); 2607 QCOMPARE(fitResult.sse, 34.3452074983243); 2608 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.000101015996328551 2609 // TODO QCOMPARE(fitResult.fdist_p, 3.51725605201025e-05); 2610 } 2611 2612 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2613 void FitTest::testLinearGP_PY_xyerror_polynomial() { 2614 // Pearson's data and York's weights 2615 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2616 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2617 QVector<double> xError = {1000., 1000., 500., 800., 200., 80., 60., 20., 1.8, 1.0}; 2618 QVector<double> yError = {1.0, 1.8, 4., 8., 20., 20., 70., 70., 100., 500.}; 2619 2620 // data source columns 2621 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2622 xDataColumn.replaceValues(0, xData); 2623 2624 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2625 yDataColumn.replaceValues(0, yData); 2626 2627 Column xErrorColumn(QStringLiteral("xerr"), AbstractColumn::ColumnMode::Double); 2628 xErrorColumn.replaceValues(0, xError); 2629 2630 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2631 yErrorColumn.replaceValues(0, yError); 2632 2633 XYFitCurve fitCurve(QStringLiteral("fit")); 2634 fitCurve.setXDataColumn(&xDataColumn); 2635 fitCurve.setYDataColumn(&yDataColumn); 2636 fitCurve.setXErrorColumn(&xErrorColumn); 2637 fitCurve.setYErrorColumn(&yErrorColumn); 2638 2639 // prepare the fit 2640 XYFitCurve::FitData fitData = fitCurve.fitData(); 2641 fitData.modelCategory = nsl_fit_model_basic; 2642 fitData.modelType = nsl_fit_model_polynomial; 2643 fitData.degree = 1; 2644 XYFitCurve::initFitData(fitData); 2645 fitData.eps = 1.e-12; 2646 const int np = fitData.paramNames.size(); 2647 fitData.paramStartValues << 5. << -0.5; 2648 fitData.xWeightsType = nsl_fit_weight_direct; 2649 fitData.yWeightsType = nsl_fit_weight_direct; 2650 fitCurve.setFitData(fitData); 2651 2652 // perform the fit 2653 fitCurve.recalculate(); 2654 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2655 2656 // check the results 2657 QCOMPARE(fitResult.available, true); 2658 QCOMPARE(fitResult.valid, true); 2659 2660 QCOMPARE(np, 2); 2661 2662 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 5.3960522989993 2663 FuzzyCompare(fitResult.paramValues.at(0), 5.39749958415886, 3.e-4); // gnuplot result ("effective variance" method) 2664 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.361458387983792 2665 FuzzyCompare(fitResult.errorValues.at(0), 0.361439886824914, 1.e-4); // -""- 2666 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.463448925094435 2667 FuzzyCompare(fitResult.paramValues.at(1), -0.463744669606207, 1.e-3); // -""- 2668 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0706627287153768 2669 FuzzyCompare(fitResult.errorValues.at(1), 0.0706637562101211, 1.e-4); // -""- 2670 2671 DEBUG(std::setprecision(15) << fitResult.rms); // result: 1.49455608152396 2672 FuzzyCompare(fitResult.rms, 1.49417194665446, 1.e-3); // gnuplot result ("effective variance" method) 2673 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1.22252038082151 2674 FuzzyCompare(fitResult.rsd, 1.22236326296828, 1.e-3); // -""- 2675 DEBUG(std::setprecision(15) << fitResult.sse); // result: 11.9564486521917 2676 FuzzyCompare(fitResult.sse, 11.9533755732357, 1.e-3); // -""- 2677 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.00441031749154456 2678 // TODO QCOMPARE(fitResult.fdist_p, 0.153296328355244); 2679 } 2680 2681 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2682 void FitTest::testLinearGP_PY_xyerror_custom() { 2683 // Pearson's data and York's weights 2684 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2685 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2686 QVector<double> xError = {1000., 1000., 500., 800., 200., 80., 60., 20., 1.8, 1.0}; 2687 QVector<double> yError = {1.0, 1.8, 4., 8., 20., 20., 70., 70., 100., 500.}; 2688 2689 // data source columns 2690 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2691 xDataColumn.replaceValues(0, xData); 2692 2693 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2694 yDataColumn.replaceValues(0, yData); 2695 2696 Column xErrorColumn(QStringLiteral("xerr"), AbstractColumn::ColumnMode::Double); 2697 xErrorColumn.replaceValues(0, xError); 2698 2699 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2700 yErrorColumn.replaceValues(0, yError); 2701 2702 XYFitCurve fitCurve(QStringLiteral("fit")); 2703 fitCurve.setXDataColumn(&xDataColumn); 2704 fitCurve.setYDataColumn(&yDataColumn); 2705 fitCurve.setXErrorColumn(&xErrorColumn); 2706 fitCurve.setYErrorColumn(&yErrorColumn); 2707 2708 // prepare the fit 2709 XYFitCurve::FitData fitData = fitCurve.fitData(); 2710 fitData.modelCategory = nsl_fit_model_custom; 2711 XYFitCurve::initFitData(fitData); 2712 fitData.model = QStringLiteral("a1 + a2 * x"); 2713 fitData.paramNames << QStringLiteral("a1") << QStringLiteral("a2"); 2714 fitData.eps = 1.e-12; 2715 const int np = fitData.paramNames.size(); 2716 fitData.paramStartValues << 5. << -0.5; 2717 for (int i = 0; i < np; i++) { 2718 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2719 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2720 } 2721 2722 fitData.xWeightsType = nsl_fit_weight_direct; 2723 fitData.yWeightsType = nsl_fit_weight_direct; 2724 fitCurve.setFitData(fitData); 2725 2726 // perform the fit 2727 fitCurve.recalculate(); 2728 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2729 2730 // check the results 2731 QCOMPARE(fitResult.available, true); 2732 QCOMPARE(fitResult.valid, true); 2733 2734 QCOMPARE(np, 2); 2735 2736 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 5.39605223831693 2737 FuzzyCompare(fitResult.paramValues.at(0), 5.39749958415886, 3.e-4); // gnuplot result ("effective variance" method) 2738 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.361458369696386 2739 FuzzyCompare(fitResult.errorValues.at(0), 0.361439886824914, 1.e-4); // -""- 2740 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.463448913528306 2741 FuzzyCompare(fitResult.paramValues.at(1), -0.463744669606207, 1.e-3); // -""- 2742 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0706627257036884 2743 FuzzyCompare(fitResult.errorValues.at(1), 0.0706637562101211, 1.e-4); // -""- 2744 2745 DEBUG(std::setprecision(15) << fitResult.rms); // result: 1.49455596317092 2746 FuzzyCompare(fitResult.rms, 1.49417194665446, 1.e-3); // gnuplot result ("effective variance" method) 2747 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1.22252033241616 2748 FuzzyCompare(fitResult.rsd, 1.22236326296828, 1.e-3); // -""- 2749 DEBUG(std::setprecision(15) << fitResult.sse); // result: 11.9564477053674 2750 FuzzyCompare(fitResult.sse, 11.9533755732357, 1.e-3); // -""- 2751 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.00441031645455255 2752 // TODO QCOMPARE(fitResult.fdist_p, 0.153296328355244); 2753 } 2754 2755 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2756 void FitTest::testLinearGP_PY_xyerror_custom_instrumental_weight() { 2757 // Pearson's data and York's weights 2758 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2759 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2760 QVector<double> xError = {1000., 1000., 500., 800., 200., 80., 60., 20., 1.8, 1.0}; 2761 QVector<double> yError = {1.0, 1.8, 4., 8., 20., 20., 70., 70., 100., 500.}; 2762 2763 // w_i -> s_i 2764 for (int i = 0; i < xError.size(); i++) { 2765 xError[i] = 1. / sqrt(xError[i]); 2766 yError[i] = 1. / sqrt(yError[i]); 2767 } 2768 2769 // data source columns 2770 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2771 xDataColumn.replaceValues(0, xData); 2772 2773 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2774 yDataColumn.replaceValues(0, yData); 2775 2776 Column xErrorColumn(QStringLiteral("xerr"), AbstractColumn::ColumnMode::Double); 2777 xErrorColumn.replaceValues(0, xError); 2778 2779 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2780 yErrorColumn.replaceValues(0, yError); 2781 2782 XYFitCurve fitCurve(QStringLiteral("fit")); 2783 fitCurve.setXDataColumn(&xDataColumn); 2784 fitCurve.setYDataColumn(&yDataColumn); 2785 fitCurve.setXErrorColumn(&xErrorColumn); 2786 fitCurve.setYErrorColumn(&yErrorColumn); 2787 2788 // prepare the fit 2789 XYFitCurve::FitData fitData = fitCurve.fitData(); 2790 fitData.modelCategory = nsl_fit_model_custom; 2791 XYFitCurve::initFitData(fitData); 2792 fitData.model = QStringLiteral("a1 + a2 * x"); 2793 fitData.paramNames << QStringLiteral("a1") << QStringLiteral("a2"); 2794 // fitData.eps = 1.e-12; 2795 const int np = fitData.paramNames.size(); 2796 fitData.paramStartValues << 5. << -0.5; 2797 for (int i = 0; i < np; i++) { 2798 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2799 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2800 } 2801 2802 fitData.xWeightsType = nsl_fit_weight_instrumental; 2803 fitData.yWeightsType = nsl_fit_weight_instrumental; 2804 fitCurve.setFitData(fitData); 2805 2806 // perform the fit 2807 fitCurve.recalculate(); 2808 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2809 2810 // check the results 2811 QCOMPARE(fitResult.available, true); 2812 QCOMPARE(fitResult.valid, true); 2813 2814 QCOMPARE(np, 2); 2815 2816 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 5.3960521880058 2817 FuzzyCompare(fitResult.paramValues.at(0), 5.39749958415886, 3.e-4); // gnuplot result ("effective variance" method) 2818 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.361458367406729 2819 FuzzyCompare(fitResult.errorValues.at(0), 0.361439886824914, 1.e-4); // -""- 2820 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.463448904801834 2821 FuzzyCompare(fitResult.paramValues.at(1), -0.463744669606207, 1.e-3); // -""- 2822 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0706627229337577 2823 FuzzyCompare(fitResult.errorValues.at(1), 0.0706637562101211, 1.e-4); // -""- 2824 2825 DEBUG(std::setprecision(15) << fitResult.rms); // result: 1.49455610878403 2826 FuzzyCompare(fitResult.rms, 1.49417194665446, 1.e-3); // gnuplot result ("effective variance" method) 2827 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1.22252039197063 2828 FuzzyCompare(fitResult.rsd, 1.22236326296828, 1.e-3); // -""- 2829 DEBUG(std::setprecision(15) << fitResult.sse); // result: 11.9564488702722 2830 FuzzyCompare(fitResult.sse, 11.9533755732357, 1.e-3); // -""- 2831 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.00441031773039329 2832 // TODO QCOMPARE(fitResult.fdist_p, 0.153296328355244); 2833 } 2834 2835 // see http://gnuplot.sourceforge.net/demo_5.2/fit.html 2836 void FitTest::testLinearGP_PY_xyerror_custom_inverse_weight() { 2837 // Pearson's data and York's weights 2838 QVector<double> xData = {0.0, 0.9, 1.8, 2.6, 3.3, 4.4, 5.2, 6.1, 6.5, 7.4}; 2839 QVector<double> yData = {5.9, 5.4, 4.4, 4.6, 3.5, 3.7, 2.8, 2.8, 2.4, 1.5}; 2840 QVector<double> xError = {1000., 1000., 500., 800., 200., 80., 60., 20., 1.8, 1.0}; 2841 QVector<double> yError = {1.0, 1.8, 4., 8., 20., 20., 70., 70., 100., 500.}; 2842 2843 // w_i -> 1/w_i 2844 for (int i = 0; i < xError.size(); i++) { 2845 xError[i] = 1. / xError[i]; 2846 yError[i] = 1. / yError[i]; 2847 } 2848 2849 // data source columns 2850 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2851 xDataColumn.replaceValues(0, xData); 2852 2853 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2854 yDataColumn.replaceValues(0, yData); 2855 2856 Column xErrorColumn(QStringLiteral("xerr"), AbstractColumn::ColumnMode::Double); 2857 xErrorColumn.replaceValues(0, xError); 2858 2859 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2860 yErrorColumn.replaceValues(0, yError); 2861 2862 XYFitCurve fitCurve(QStringLiteral("fit")); 2863 fitCurve.setXDataColumn(&xDataColumn); 2864 fitCurve.setYDataColumn(&yDataColumn); 2865 fitCurve.setXErrorColumn(&xErrorColumn); 2866 fitCurve.setYErrorColumn(&yErrorColumn); 2867 2868 // prepare the fit 2869 XYFitCurve::FitData fitData = fitCurve.fitData(); 2870 fitData.modelCategory = nsl_fit_model_custom; 2871 XYFitCurve::initFitData(fitData); 2872 fitData.model = QStringLiteral("a1 + a2 * x"); 2873 fitData.paramNames << QStringLiteral("a1") << QStringLiteral("a2"); 2874 // fitData.eps = 1.e-12; 2875 const int np = fitData.paramNames.size(); 2876 fitData.paramStartValues << 5. << -0.5; 2877 for (int i = 0; i < np; i++) { 2878 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2879 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2880 } 2881 2882 fitData.xWeightsType = nsl_fit_weight_inverse; 2883 fitData.yWeightsType = nsl_fit_weight_inverse; 2884 fitCurve.setFitData(fitData); 2885 2886 // perform the fit 2887 fitCurve.recalculate(); 2888 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2889 2890 // check the results 2891 QCOMPARE(fitResult.available, true); 2892 QCOMPARE(fitResult.valid, true); 2893 2894 QCOMPARE(np, 2); 2895 2896 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 5.39605219384715 2897 FuzzyCompare(fitResult.paramValues.at(0), 5.39749958415886, 3.e-4); // gnuplot result ("effective variance" method) 2898 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 0.361458367208767 2899 FuzzyCompare(fitResult.errorValues.at(0), 0.361439886824914, 1.e-4); // -""- 2900 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: -0.463448906090293 2901 FuzzyCompare(fitResult.paramValues.at(1), -0.463744669606207, 1.e-3); // -""- 2902 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 0.0706627222052917 2903 FuzzyCompare(fitResult.errorValues.at(1), 0.0706637562101211, 1.e-4); // -""- 2904 2905 DEBUG(std::setprecision(15) << fitResult.rms); // result: 1.49455610679827 2906 FuzzyCompare(fitResult.rms, 1.49417194665446, 1.e-3); // gnuplot result ("effective variance" method) 2907 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1.22252039115847 2908 FuzzyCompare(fitResult.rsd, 1.22236326296828, 1.e-3); // -""- 2909 DEBUG(std::setprecision(15) << fitResult.sse); // result: 11.9564488543861 2910 FuzzyCompare(fitResult.sse, 11.9533755732357, 1.e-3); // -""- 2911 DEBUG(std::setprecision(15) << fitResult.fdist_p); // result: 0.00441031771299435 2912 // TODO QCOMPARE(fitResult.fdist_p, 0.153296328355244); 2913 } 2914 2915 // see https://bugs.kde.org/show_bug.cgi?id=408535 2916 void FitTest::testNonLinear_yerror_zero_bug408535() { 2917 QVector<double> xData = {0.0, 320., 320., 360., 360., 400., 400., 440., 440., 480., 480., 520., 520., 560., 560., 600., 600., 640., 2918 640., 680., 680., 720., 720., 760., 760., 800., 800., 840., 840., 880., 880., 1200., 1200., 1200., 1200.}; 2919 QVector<double> yData = {0.0, 160., 120., 190., 120., 210., 140., 220., 170., 230., 190., 240., 210., 250., 230., 270., 240., 260., 2920 270., 290., 240., 310., 270., 320., 290., 330., 290., 320., 300., 330., 310., 370., 390., 390., 400.}; 2921 QVector<double> yError = {0.0, 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 2922 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15., 15.}; 2923 2924 // data source columns 2925 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 2926 xDataColumn.replaceValues(0, xData); 2927 2928 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 2929 yDataColumn.replaceValues(0, yData); 2930 2931 Column yErrorColumn(QStringLiteral("yerr"), AbstractColumn::ColumnMode::Double); 2932 yErrorColumn.replaceValues(0, yError); 2933 2934 XYFitCurve fitCurve(QStringLiteral("fit")); 2935 fitCurve.setXDataColumn(&xDataColumn); 2936 fitCurve.setYDataColumn(&yDataColumn); 2937 fitCurve.setYErrorColumn(&yErrorColumn); 2938 2939 // prepare the fit 2940 XYFitCurve::FitData fitData = fitCurve.fitData(); 2941 fitData.modelCategory = nsl_fit_model_custom; 2942 XYFitCurve::initFitData(fitData); 2943 fitData.model = QStringLiteral("A*exp(-B/x)"); 2944 fitData.paramNames << QStringLiteral("A") << QStringLiteral("B"); 2945 // fitData.eps = 1.e-12; 2946 const int np = fitData.paramNames.size(); 2947 fitData.paramStartValues << 100. << 100.; 2948 for (int i = 0; i < np; i++) { 2949 fitData.paramLowerLimits << -std::numeric_limits<double>::max(); 2950 fitData.paramUpperLimits << std::numeric_limits<double>::max(); 2951 } 2952 2953 fitData.yWeightsType = nsl_fit_weight_instrumental; 2954 fitCurve.setFitData(fitData); 2955 2956 // perform the fit 2957 fitCurve.recalculate(); 2958 const XYFitCurve::FitResult& fitResult = fitCurve.fitResult(); 2959 2960 // check the results 2961 QCOMPARE(fitResult.available, true); 2962 QCOMPARE(fitResult.valid, true); 2963 2964 QCOMPARE(np, 2); 2965 2966 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); // result: 557.463875234563, Win: 557.463888957409 2967 FuzzyCompare(fitResult.paramValues.at(0), 557.463875234563, 1.e-7); 2968 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); // result: 22.0490332546127, FreeBSD: 22.0490429285665 2969 FuzzyCompare(fitResult.errorValues.at(0), 22.0490332546127, 1.e-6); 2970 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); // result: 468.319724706721, Win: 468.319742522772 2971 FuzzyCompare(fitResult.paramValues.at(1), 468.319724706721, 1.e-7); 2972 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); // result: 26.5105791274139, FreeBSD: 26.510591238283 2973 FuzzyCompare(fitResult.errorValues.at(1), 26.5105791274139, 1.e-6); 2974 2975 DEBUG(std::setprecision(15) << fitResult.rms); // result: 1.96172656494138 2976 FuzzyCompare(fitResult.rms, 1.96172656494138, 1.e-9); 2977 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 1.4006164945985 2978 FuzzyCompare(fitResult.rsd, 1.4006164945985, 1.e-9); 2979 DEBUG(std::setprecision(15) << fitResult.sse); // result: 64.7369766430654 2980 FuzzyCompare(fitResult.sse, 64.7369766430654, 1.e-9); 2981 DEBUG(std::setprecision(15) << fitResult.rsquare); // result: 0.999740417228134 2982 FuzzyCompare(fitResult.rsquare, 0.999740417228134, 1.e-9); 2983 DEBUG(std::setprecision(15) << fitResult.rsquareAdj); // result: 0.999724193304893 2984 FuzzyCompare(fitResult.rsquareAdj, 0.999724193304893, 1.e-9); 2985 } 2986 2987 void FitTest::testHistogramFit() { 2988 Project project; 2989 project.load(QFINDTESTDATA(QLatin1String("data/TestHistogramFit.lml"))); 2990 2991 auto* aspect = project.child<AbstractAspect>(0); 2992 QVERIFY(aspect != nullptr); 2993 QCOMPARE(aspect->name(), QLatin1String("Spreadsheet")); 2994 QVERIFY(aspect->type() == AspectType::Spreadsheet); 2995 aspect = project.child<AbstractAspect>(1); 2996 QVERIFY(aspect != nullptr); 2997 2998 QCOMPARE(aspect->name(), QLatin1String("Worksheet - Spreadsheet")); 2999 QVERIFY(aspect->type() == AspectType::Worksheet); 3000 auto w = dynamic_cast<Worksheet*>(aspect); 3001 if (!w) 3002 return; 3003 3004 auto plot = dynamic_cast<CartesianPlot*>(aspect->child<CartesianPlot>(0)); 3005 QVERIFY(plot != nullptr); 3006 3007 QCOMPARE(plot->name(), QLatin1String("Plot - Spreadsheet")); 3008 auto hist = dynamic_cast<Histogram*>(plot->child<Histogram>(0)); 3009 QVERIFY(hist != nullptr); 3010 3011 QCOMPARE(hist->name(), QLatin1String("2")); 3012 // Do the fit 3013 plot->addHistogramFit(hist, nsl_sf_stats_gaussian); 3014 3015 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3016 QVERIFY(fit != nullptr); 3017 3018 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to '2'")); 3019 // get results 3020 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3021 3022 QCOMPARE(fitResult.available, true); 3023 QCOMPARE(fitResult.valid, true); 3024 3025 // ML results 3026 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); 3027 QCOMPARE(fitResult.paramValues.at(0), 1.); 3028 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); 3029 QCOMPARE(fitResult.paramValues.at(1), 0.999776858937); 3030 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); 3031 QCOMPARE(fitResult.paramValues.at(2), -0.0294045302042); 3032 3033 /* LM results 3034 DEBUG(std::setprecision(15) << fitResult.paramValues.at(0)); 3035 QCOMPARE(fitResult.paramValues.at(0), 0.999829585605626); 3036 DEBUG(std::setprecision(15) << fitResult.errorValues.at(0)); 3037 QCOMPARE(fitResult.errorValues.at(0), 0.0313884775124071); 3038 DEBUG(std::setprecision(15) << fitResult.paramValues.at(1)); 3039 QCOMPARE(fitResult.paramValues.at(1), 0.988871409810129); 3040 DEBUG(std::setprecision(15) << fitResult.errorValues.at(1)); 3041 QCOMPARE(fitResult.errorValues.at(1), 0.0358652107488108); 3042 DEBUG(std::setprecision(15) << fitResult.paramValues.at(2)); 3043 QCOMPARE(fitResult.paramValues.at(2), -0.138053471452345); 3044 DEBUG(std::setprecision(15) << fitResult.errorValues.at(2)); 3045 QCOMPARE(fitResult.errorValues.at(2), 0.0358379697268546); 3046 3047 DEBUG(std::setprecision(15) << fitResult.rms); // result: 3048 QCOMPARE(fitResult.rms, 0.000890023253844838); 3049 DEBUG(std::setprecision(15) << fitResult.rsd); // result: 3050 QCOMPARE(fitResult.rsd, 0.0298332575131318); 3051 DEBUG(std::setprecision(15) << fitResult.sse); // result: 3052 QCOMPARE(fitResult.sse, 0.0249206511076555); 3053 DEBUG(std::setprecision(15) << fitResult.rsquare); // result: 3054 QCOMPARE(fitResult.rsquare, 0.961753741845289); 3055 DEBUG(std::setprecision(15) << fitResult.rsquareAdj); // result: 3056 QCOMPARE(fitResult.rsquareAdj, 0.957504157605876); 3057 */ 3058 } 3059 3060 void FitTest::testHistogramGaussianML() { 3061 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3062 AsciiFilter filter; 3063 3064 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Gaussian.dat")); 3065 3066 filter.setHeaderEnabled(false); 3067 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3068 3069 QCOMPARE(spreadsheet.rowCount(), 1000); 3070 QCOMPARE(spreadsheet.columnCount(), 1); 3071 3072 Worksheet worksheet(QStringLiteral("test"), false); 3073 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3074 worksheet.addChild(plot); 3075 3076 auto* hist = new Histogram(QStringLiteral("Histogram")); 3077 plot->addChild(hist); 3078 hist->setDataColumn(spreadsheet.column(0)); 3079 3080 // Do the fit 3081 plot->addHistogramFit(hist, nsl_sf_stats_gaussian); 3082 3083 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3084 QVERIFY(fit != nullptr); 3085 3086 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3087 // get results 3088 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3089 3090 QCOMPARE(fitResult.available, true); 3091 QCOMPARE(fitResult.valid, true); 3092 3093 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3094 QCOMPARE(fitResult.paramValues.at(0), 210.380459328); 3095 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3096 QCOMPARE(fitResult.paramValues.at(1), 0.999776858937); 3097 WARN(std::setprecision(15) << fitResult.errorValues.at(1)); 3098 QCOMPARE(fitResult.errorValues.at(1), 0.0223507017166885); 3099 WARN(std::setprecision(15) << fitResult.paramValues.at(1) - fitResult.marginValues.at(1)); 3100 QCOMPARE(fitResult.paramValues.at(1) - fitResult.marginValues.at(1), 0.955917043549699); 3101 WARN(std::setprecision(15) << fitResult.paramValues.at(1) + fitResult.marginValues.at(1)); 3102 QCOMPARE(fitResult.paramValues.at(1) + fitResult.marginValues.at(1), 1.0436366743251); 3103 3104 WARN(std::setprecision(15) << fitResult.paramValues.at(2)); 3105 QCOMPARE(fitResult.paramValues.at(2), -0.0294045302042); 3106 WARN(std::setprecision(15) << fitResult.errorValues.at(2)); 3107 QCOMPARE(fitResult.errorValues.at(2), 0.0316157202617); 3108 WARN(std::setprecision(15) << fitResult.paramValues.at(2) - fitResult.marginValues.at(2)); 3109 QCOMPARE(fitResult.paramValues.at(2) - fitResult.marginValues.at(2), -0.0914455198610062); 3110 WARN(std::setprecision(15) << fitResult.paramValues.at(2) + fitResult.marginValues.at(2)); 3111 QCOMPARE(fitResult.paramValues.at(2) + fitResult.marginValues.at(2), 0.0326364594526431); 3112 } 3113 3114 void FitTest::testHistogramExponentialML() { 3115 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3116 AsciiFilter filter; 3117 3118 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Exponential.dat")); 3119 3120 filter.setHeaderEnabled(false); 3121 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3122 3123 QCOMPARE(spreadsheet.rowCount(), 100); 3124 QCOMPARE(spreadsheet.columnCount(), 1); 3125 3126 Worksheet worksheet(QStringLiteral("test"), false); 3127 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3128 worksheet.addChild(plot); 3129 3130 auto* hist = new Histogram(QStringLiteral("Histogram")); 3131 plot->addChild(hist); 3132 hist->setDataColumn(spreadsheet.column(0)); 3133 3134 // Do the fit 3135 plot->addHistogramFit(hist, nsl_sf_stats_exponential); 3136 3137 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3138 QVERIFY(fit != nullptr); 3139 3140 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3141 // get results 3142 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3143 3144 QCOMPARE(fitResult.available, true); 3145 QCOMPARE(fitResult.valid, true); 3146 3147 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3148 QCOMPARE(fitResult.paramValues.at(0), 41.6543778722); 3149 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3150 QCOMPARE(fitResult.paramValues.at(1), 1.93906050400681); 3151 WARN(std::setprecision(15) << fitResult.errorValues.at(1)); 3152 QCOMPARE(fitResult.errorValues.at(1), 0.195884683568035); 3153 WARN(std::setprecision(15) << fitResult.paramValues.at(1) - fitResult.marginValues.at(1)); 3154 QCOMPARE(fitResult.paramValues.at(1) - fitResult.marginValues.at(1), 1.5740096363284); 3155 WARN(std::setprecision(15) << fitResult.paramValues.at(1) + fitResult.margin2Values.at(1)); 3156 QCOMPARE(fitResult.paramValues.at(1) + fitResult.margin2Values.at(1), 2.34119114746796); 3157 WARN(std::setprecision(15) << fitResult.paramValues.at(2)); 3158 QCOMPARE(fitResult.paramValues.at(2), 5.01032231564491); 3159 } 3160 3161 void FitTest::testHistogramLaplaceML() { 3162 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3163 AsciiFilter filter; 3164 3165 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Laplace.dat")); 3166 3167 filter.setHeaderEnabled(false); 3168 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3169 3170 QCOMPARE(spreadsheet.rowCount(), 100); 3171 QCOMPARE(spreadsheet.columnCount(), 1); 3172 3173 Worksheet worksheet(QStringLiteral("test"), false); 3174 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3175 worksheet.addChild(plot); 3176 3177 auto* hist = new Histogram(QStringLiteral("Histogram")); 3178 plot->addChild(hist); 3179 hist->setDataColumn(spreadsheet.column(0)); 3180 3181 // Do the fit 3182 plot->addHistogramFit(hist, nsl_sf_stats_laplace); 3183 3184 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3185 QVERIFY(fit != nullptr); 3186 3187 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3188 // get results 3189 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3190 3191 QCOMPARE(fitResult.available, true); 3192 QCOMPARE(fitResult.valid, true); 3193 3194 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3195 QCOMPARE(fitResult.paramValues.at(0), 145.64147805241); 3196 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3197 QCOMPARE(fitResult.paramValues.at(1), 1.99538835213796); 3198 WARN(std::setprecision(15) << fitResult.paramValues.at(2)); 3199 QCOMPARE(fitResult.paramValues.at(2), 4.95890340967321); 3200 } 3201 3202 void FitTest::testHistogramCauchyML() { 3203 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3204 AsciiFilter filter; 3205 3206 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Cauchy.dat")); 3207 3208 filter.setHeaderEnabled(false); 3209 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3210 3211 QCOMPARE(spreadsheet.rowCount(), 1000); 3212 QCOMPARE(spreadsheet.columnCount(), 1); 3213 3214 Worksheet worksheet(QStringLiteral("test"), false); 3215 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3216 worksheet.addChild(plot); 3217 3218 auto* hist = new Histogram(QStringLiteral("Histogram")); 3219 plot->addChild(hist); 3220 hist->setDataColumn(spreadsheet.column(0)); 3221 3222 // Do the fit 3223 plot->addHistogramFit(hist, nsl_sf_stats_cauchy_lorentz); 3224 3225 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3226 QVERIFY(fit != nullptr); 3227 3228 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3229 // get results 3230 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3231 3232 QCOMPARE(fitResult.available, true); 3233 QCOMPARE(fitResult.valid, true); 3234 3235 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3236 QCOMPARE(fitResult.paramValues.at(0), 34973.659700564); 3237 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3238 QCOMPARE(fitResult.paramValues.at(1), 1.87876026823743); 3239 WARN(std::setprecision(15) << fitResult.paramValues.at(2)); 3240 QCOMPARE(fitResult.paramValues.at(2), 5.09155507540282); 3241 } 3242 3243 void FitTest::testHistogramLognormalML() { 3244 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3245 AsciiFilter filter; 3246 3247 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Lognormal.dat")); 3248 3249 filter.setHeaderEnabled(false); 3250 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3251 3252 QCOMPARE(spreadsheet.rowCount(), 1000); 3253 QCOMPARE(spreadsheet.columnCount(), 1); 3254 3255 Worksheet worksheet(QStringLiteral("test"), false); 3256 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3257 worksheet.addChild(plot); 3258 3259 auto* hist = new Histogram(QStringLiteral("Histogram")); 3260 plot->addChild(hist); 3261 hist->setDataColumn(spreadsheet.column(0)); 3262 3263 // Do the fit 3264 plot->addHistogramFit(hist, nsl_sf_stats_lognormal); 3265 3266 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3267 QVERIFY(fit != nullptr); 3268 3269 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3270 // get results 3271 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3272 3273 QCOMPARE(fitResult.available, true); 3274 QCOMPARE(fitResult.valid, true); 3275 3276 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3277 QCOMPARE(fitResult.paramValues.at(0), 4714813.91602); 3278 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3279 QCOMPARE(fitResult.paramValues.at(1), 2.07876791650682); 3280 WARN(std::setprecision(15) << fitResult.paramValues.at(2)); 3281 QCOMPARE(fitResult.paramValues.at(2), 5.01070949852617); 3282 } 3283 3284 void FitTest::testHistogramPoissonML() { 3285 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3286 AsciiFilter filter; 3287 3288 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Poisson.dat")); 3289 3290 filter.setHeaderEnabled(false); 3291 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3292 3293 QCOMPARE(spreadsheet.rowCount(), 100); 3294 QCOMPARE(spreadsheet.columnCount(), 1); 3295 3296 Worksheet worksheet(QStringLiteral("test"), false); 3297 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3298 worksheet.addChild(plot); 3299 3300 auto* hist = new Histogram(QStringLiteral("Histogram")); 3301 plot->addChild(hist); 3302 hist->setDataColumn(spreadsheet.column(0)); 3303 3304 // Do the fit 3305 plot->addHistogramFit(hist, nsl_sf_stats_poisson); 3306 3307 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3308 QVERIFY(fit != nullptr); 3309 3310 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3311 // get results 3312 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3313 3314 QCOMPARE(fitResult.available, true); 3315 QCOMPARE(fitResult.valid, true); 3316 3317 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3318 QCOMPARE(fitResult.paramValues.at(0), 150.); 3319 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3320 QCOMPARE(fitResult.paramValues.at(1), 9.55); 3321 WARN(std::setprecision(15) << fitResult.errorValues.at(1)); 3322 QCOMPARE(fitResult.errorValues.at(1), 0.309030742807249); 3323 WARN(std::setprecision(15) << fitResult.paramValues.at(1) - fitResult.marginValues.at(1)); 3324 QCOMPARE(fitResult.paramValues.at(1) - fitResult.marginValues.at(1), 8.95383732390823); 3325 WARN(std::setprecision(15) << fitResult.paramValues.at(1) + fitResult.margin2Values.at(1)); 3326 QCOMPARE(fitResult.paramValues.at(1) + fitResult.margin2Values.at(1), 10.1754213697868); 3327 } 3328 3329 void FitTest::testHistogramBinomialML() { 3330 Spreadsheet spreadsheet(QStringLiteral("test"), false); 3331 AsciiFilter filter; 3332 3333 const QString& fileName = QFINDTESTDATA(QLatin1String("data/Binomial.dat")); 3334 3335 filter.setHeaderEnabled(false); 3336 filter.readDataFromFile(fileName, &spreadsheet, AbstractFileFilter::ImportMode::Replace); 3337 3338 QCOMPARE(spreadsheet.rowCount(), 100); 3339 QCOMPARE(spreadsheet.columnCount(), 1); 3340 3341 Worksheet worksheet(QStringLiteral("test"), false); 3342 auto* plot = new CartesianPlot(QStringLiteral("plot")); 3343 worksheet.addChild(plot); 3344 3345 auto* hist = new Histogram(QStringLiteral("Histogram")); 3346 plot->addChild(hist); 3347 hist->setDataColumn(spreadsheet.column(0)); 3348 3349 // Do the fit 3350 plot->addHistogramFit(hist, nsl_sf_stats_binomial); 3351 3352 auto fit = dynamic_cast<XYFitCurve*>(plot->child<XYFitCurve>(0)); 3353 QVERIFY(fit != nullptr); 3354 3355 QCOMPARE(fit->name(), QLatin1String("Distribution Fit to 'Histogram'")); 3356 // get results 3357 const XYFitCurve::FitResult& fitResult = fit->fitResult(); 3358 3359 QCOMPARE(fitResult.available, true); 3360 QCOMPARE(fitResult.valid, true); 3361 3362 WARN(std::setprecision(15) << fitResult.paramValues.at(0)); 3363 QCOMPARE(fitResult.paramValues.at(0), 270.); 3364 WARN(std::setprecision(15) << fitResult.paramValues.at(1)); 3365 QCOMPARE(fitResult.paramValues.at(1), 0.4931); 3366 WARN(std::setprecision(15) << fitResult.errorValues.at(1)); 3367 QCOMPARE(fitResult.errorValues.at(1), 0.0499952387733072); 3368 WARN(std::setprecision(15) << fitResult.paramValues.at(1) - fitResult.marginValues.at(1)); 3369 QCOMPARE(fitResult.paramValues.at(1) - fitResult.marginValues.at(1), 0.482953993308348); 3370 WARN(std::setprecision(15) << fitResult.paramValues.at(1) + fitResult.margin2Values.at(1)); 3371 QCOMPARE(fitResult.paramValues.at(1) + fitResult.margin2Values.at(1), 0.503287947118723); 3372 3373 QCOMPARE(fitResult.paramValues.at(2), spreadsheet.rowCount()); 3374 } 3375 3376 QTEST_MAIN(FitTest)