File indexing completed on 2024-05-05 03:48:24
0001 /* 0002 File : DifferentiationTest.cpp 0003 Project : LabPlot 0004 Description : Tests for numerical differentiation 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2018-2022 Stefan Gerlach <stefan.gerlach@uni.kn> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "DifferentiationTest.h" 0012 #include "backend/core/column/Column.h" 0013 #include "backend/worksheet/plots/cartesian/XYDifferentiationCurve.h" 0014 0015 // ############################################################################## 0016 0017 void DifferentiationTest::testLinear() { 0018 // data 0019 QVector<int> xData = {1, 2, 3, 4}; 0020 QVector<double> yData = {1., 2., 3., 4.}; 0021 0022 // data source columns 0023 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0024 xDataColumn.replaceInteger(0, xData); 0025 0026 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0027 yDataColumn.replaceValues(0, yData); 0028 0029 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0030 differentiationCurve.setXDataColumn(&xDataColumn); 0031 differentiationCurve.setYDataColumn(&yDataColumn); 0032 0033 // prepare the differentiation 0034 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0035 differentiationCurve.setDifferentiationData(differentiationData); 0036 0037 // perform the differentiation 0038 differentiationCurve.recalculate(); 0039 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0040 0041 // check the results 0042 QCOMPARE(differentiationResult.available, true); 0043 QCOMPARE(differentiationResult.valid, true); 0044 0045 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0046 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0047 0048 const int np = resultXDataColumn->rowCount(); 0049 QCOMPARE(np, 4); 0050 0051 for (int i = 0; i < np; i++) 0052 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0053 0054 QCOMPARE(resultYDataColumn->valueAt(0), 1.); 0055 QCOMPARE(resultYDataColumn->valueAt(1), 1.); 0056 QCOMPARE(resultYDataColumn->valueAt(2), 1.); 0057 QCOMPARE(resultYDataColumn->valueAt(3), 1.); 0058 } 0059 0060 void DifferentiationTest::testLinearNonEquidistant() { 0061 // data 0062 QVector<double> xData = {1., 1.5, 3., 5.}; 0063 QVector<double> yData = {1., 1.5, 3., 5.}; 0064 0065 // data source columns 0066 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0067 xDataColumn.replaceValues(0, xData); 0068 0069 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0070 yDataColumn.replaceValues(0, yData); 0071 0072 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0073 differentiationCurve.setXDataColumn(&xDataColumn); 0074 differentiationCurve.setYDataColumn(&yDataColumn); 0075 0076 // prepare the differentiation 0077 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0078 differentiationCurve.setDifferentiationData(differentiationData); 0079 0080 // perform the differentiation 0081 differentiationCurve.recalculate(); 0082 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0083 0084 // check the results 0085 QCOMPARE(differentiationResult.available, true); 0086 QCOMPARE(differentiationResult.valid, true); 0087 0088 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0089 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0090 0091 const int np = resultXDataColumn->rowCount(); 0092 QCOMPARE(np, 4); 0093 0094 for (int i = 0; i < np; i++) 0095 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0096 0097 QCOMPARE(resultYDataColumn->valueAt(0), 1.); 0098 QCOMPARE(resultYDataColumn->valueAt(1), 1.); 0099 QCOMPARE(resultYDataColumn->valueAt(2), 1.); 0100 QCOMPARE(resultYDataColumn->valueAt(3), 1.); 0101 } 0102 0103 void DifferentiationTest::testQuadratic() { 0104 // data 0105 QVector<double> xData = {1., 2., 3., 4.}; 0106 QVector<double> yData = {1., 4., 9., 16.}; 0107 0108 // data source columns 0109 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0110 xDataColumn.replaceValues(0, xData); 0111 0112 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0113 yDataColumn.replaceValues(0, yData); 0114 0115 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0116 differentiationCurve.setXDataColumn(&xDataColumn); 0117 differentiationCurve.setYDataColumn(&yDataColumn); 0118 0119 // prepare the differentiation 0120 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0121 differentiationCurve.setDifferentiationData(differentiationData); 0122 0123 // perform the differentiation 0124 differentiationCurve.recalculate(); 0125 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0126 0127 // check the results 0128 QCOMPARE(differentiationResult.available, true); 0129 QCOMPARE(differentiationResult.valid, true); 0130 0131 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0132 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0133 0134 const int np = resultXDataColumn->rowCount(); 0135 QCOMPARE(np, 4); 0136 0137 for (int i = 0; i < np; i++) 0138 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0139 0140 QCOMPARE(resultYDataColumn->valueAt(0), 2.); 0141 QCOMPARE(resultYDataColumn->valueAt(1), 4.); 0142 QCOMPARE(resultYDataColumn->valueAt(2), 6.); 0143 QCOMPARE(resultYDataColumn->valueAt(3), 8.); 0144 } 0145 0146 void DifferentiationTest::testQuadraticNonEquidistant() { 0147 // data 0148 QVector<double> xData = {1., 1.5, 3., 5.}; 0149 QVector<double> yData = {1., 2.25, 9., 25.}; 0150 0151 // data source columns 0152 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0153 xDataColumn.replaceValues(0, xData); 0154 0155 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0156 yDataColumn.replaceValues(0, yData); 0157 0158 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0159 differentiationCurve.setXDataColumn(&xDataColumn); 0160 differentiationCurve.setYDataColumn(&yDataColumn); 0161 0162 // prepare the differentiation 0163 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0164 differentiationCurve.setDifferentiationData(differentiationData); 0165 0166 // perform the differentiation 0167 differentiationCurve.recalculate(); 0168 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0169 0170 // check the results 0171 QCOMPARE(differentiationResult.available, true); 0172 QCOMPARE(differentiationResult.valid, true); 0173 0174 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0175 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0176 0177 const int np = resultXDataColumn->rowCount(); 0178 QCOMPARE(np, 4); 0179 0180 for (int i = 0; i < np; i++) 0181 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0182 0183 QCOMPARE(resultYDataColumn->valueAt(0), 2.); 0184 QCOMPARE(resultYDataColumn->valueAt(1), 3.); 0185 QCOMPARE(resultYDataColumn->valueAt(2), 6.); 0186 QCOMPARE(resultYDataColumn->valueAt(3), 10.); 0187 } 0188 0189 void DifferentiationTest::testQuadraticSecondOrder() { 0190 // data 0191 QVector<double> xData = {1., 2., 3., 4.}; 0192 QVector<double> yData = {1., 4., 9., 16.}; 0193 0194 // data source columns 0195 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0196 xDataColumn.replaceValues(0, xData); 0197 0198 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0199 yDataColumn.replaceValues(0, yData); 0200 0201 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0202 differentiationCurve.setXDataColumn(&xDataColumn); 0203 differentiationCurve.setYDataColumn(&yDataColumn); 0204 0205 // prepare the differentiation 0206 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0207 differentiationData.derivOrder = nsl_diff_deriv_order_second; 0208 differentiationCurve.setDifferentiationData(differentiationData); 0209 0210 // perform the differentiation 0211 differentiationCurve.recalculate(); 0212 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0213 0214 // check the results 0215 QCOMPARE(differentiationResult.available, true); 0216 QCOMPARE(differentiationResult.valid, true); 0217 0218 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0219 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0220 0221 const int np = resultXDataColumn->rowCount(); 0222 QCOMPARE(np, 4); 0223 0224 for (int i = 0; i < np; i++) 0225 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0226 0227 QCOMPARE(resultYDataColumn->valueAt(0), 2.); 0228 QCOMPARE(resultYDataColumn->valueAt(1), 2.); 0229 QCOMPARE(resultYDataColumn->valueAt(2), 2.); 0230 QCOMPARE(resultYDataColumn->valueAt(3), 2.); 0231 } 0232 0233 void DifferentiationTest::testCubicSecondOrder() { 0234 // data 0235 QVector<double> xData = {1., 2., 3., 4.}; 0236 QVector<double> yData = {1., 8., 27., 64.}; 0237 0238 // data source columns 0239 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0240 xDataColumn.replaceValues(0, xData); 0241 0242 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0243 yDataColumn.replaceValues(0, yData); 0244 0245 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0246 differentiationCurve.setXDataColumn(&xDataColumn); 0247 differentiationCurve.setYDataColumn(&yDataColumn); 0248 0249 // prepare the differentiation 0250 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0251 differentiationData.derivOrder = nsl_diff_deriv_order_second; 0252 differentiationCurve.setDifferentiationData(differentiationData); 0253 0254 // perform the differentiation 0255 differentiationCurve.recalculate(); 0256 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0257 0258 // check the results 0259 QCOMPARE(differentiationResult.available, true); 0260 QCOMPARE(differentiationResult.valid, true); 0261 0262 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0263 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0264 0265 const int np = resultXDataColumn->rowCount(); 0266 QCOMPARE(np, 4); 0267 0268 for (int i = 0; i < np; i++) 0269 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0270 0271 QCOMPARE(resultYDataColumn->valueAt(0), 6.); 0272 QCOMPARE(resultYDataColumn->valueAt(1), 12.); 0273 QCOMPARE(resultYDataColumn->valueAt(2), 18.); 0274 QCOMPARE(resultYDataColumn->valueAt(3), 24.); 0275 } 0276 0277 void DifferentiationTest::testCubicThirdOrder() { 0278 // data 0279 QVector<double> xData = {1., 2., 3., 4., 5.}; 0280 QVector<double> yData = {1., 8., 27., 64., 125.}; 0281 0282 // data source columns 0283 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Double); 0284 xDataColumn.replaceValues(0, xData); 0285 0286 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0287 yDataColumn.replaceValues(0, yData); 0288 0289 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0290 differentiationCurve.setXDataColumn(&xDataColumn); 0291 differentiationCurve.setYDataColumn(&yDataColumn); 0292 0293 // prepare the differentiation 0294 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0295 differentiationData.derivOrder = nsl_diff_deriv_order_third; 0296 differentiationCurve.setDifferentiationData(differentiationData); 0297 0298 // perform the differentiation 0299 differentiationCurve.recalculate(); 0300 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0301 0302 // check the results 0303 QCOMPARE(differentiationResult.available, true); 0304 QCOMPARE(differentiationResult.valid, true); 0305 0306 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0307 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0308 0309 const int np = resultXDataColumn->rowCount(); 0310 QCOMPARE(np, 5); 0311 0312 for (int i = 0; i < np; i++) 0313 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0314 0315 QCOMPARE(resultYDataColumn->valueAt(0), 6.); 0316 QCOMPARE(resultYDataColumn->valueAt(1), 6.); 0317 QCOMPARE(resultYDataColumn->valueAt(2), 6.); 0318 QCOMPARE(resultYDataColumn->valueAt(3), 6.); 0319 QCOMPARE(resultYDataColumn->valueAt(4), 6.); 0320 } 0321 0322 void DifferentiationTest::testLinearDuplicateX() { 0323 // data 0324 QVector<int> xData = {1, 1, 2, 2, 3, 4, 4, 4, 5, 5}; 0325 QVector<double> yData = {1., 2., 3., 4., 5., 6., 7., 8., 9., 10.}; 0326 0327 // data source columns 0328 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0329 xDataColumn.replaceInteger(0, xData); 0330 0331 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0332 yDataColumn.replaceValues(0, yData); 0333 0334 XYDifferentiationCurve differentiationCurve(QStringLiteral("differentiation")); 0335 differentiationCurve.setXDataColumn(&xDataColumn); 0336 differentiationCurve.setYDataColumn(&yDataColumn); 0337 0338 // prepare the differentiation 0339 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0340 differentiationCurve.setDifferentiationData(differentiationData); 0341 0342 // perform the differentiation 0343 differentiationCurve.recalculate(); 0344 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0345 0346 /*for (int i = 0; i < 5; i++) 0347 QCOMPARE(xDataColumn.valueAt(i), (double)i + 1); 0348 0349 QCOMPARE(yDataColumn.valueAt(0), 1.5); 0350 QCOMPARE(yDataColumn.valueAt(1), 3.5); 0351 QCOMPARE(yDataColumn.valueAt(2), 5.); 0352 QCOMPARE(yDataColumn.valueAt(3), 7.); 0353 QCOMPARE(yDataColumn.valueAt(4), 9.5); 0354 */ 0355 0356 // check the results 0357 QCOMPARE(differentiationResult.available, true); 0358 QCOMPARE(differentiationResult.valid, true); 0359 0360 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0361 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0362 0363 const int np = resultXDataColumn->rowCount(); 0364 QCOMPARE(np, 5); 0365 0366 for (int i = 0; i < np; i++) 0367 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0368 0369 QCOMPARE(resultYDataColumn->valueAt(0), 2.25); 0370 QCOMPARE(resultYDataColumn->valueAt(1), 1.75); 0371 QCOMPARE(resultYDataColumn->valueAt(2), 3.); 0372 QCOMPARE(resultYDataColumn->valueAt(3), 2.5); 0373 QCOMPARE(resultYDataColumn->valueAt(4), -1.5); 0374 } 0375 0376 QTEST_MAIN(DifferentiationTest)