File indexing completed on 2024-05-05 16:00:14
0001 /*************************************************************************** 0002 File : DifferentiationTest.cpp 0003 Project : LabPlot 0004 Description : Tests for numerical differentiation 0005 -------------------------------------------------------------------- 0006 Copyright : (C) 2018 Stefan Gerlach (stefan.gerlach@uni.kn) 0007 ***************************************************************************/ 0008 0009 /*************************************************************************** 0010 * * 0011 * This program is free software; you can redistribute it and/or modify * 0012 * it under the terms of the GNU General Public License as published by * 0013 * the Free Software Foundation; either version 2 of the License, or * 0014 * (at your option) any later version. * 0015 * * 0016 * This program is distributed in the hope that it will be useful, * 0017 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 0018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 0019 * GNU General Public License for more details. * 0020 * * 0021 * You should have received a copy of the GNU General Public License * 0022 * along with this program; if not, write to the Free Software * 0023 * Foundation, Inc., 51 Franklin Street, Fifth Floor, * 0024 * Boston, MA 02110-1301 USA * 0025 * * 0026 ***************************************************************************/ 0027 0028 #include "DifferentiationTest.h" 0029 #include "backend/core/column/Column.h" 0030 #include "backend/worksheet/plots/cartesian/XYDifferentiationCurve.h" 0031 0032 //############################################################################## 0033 0034 void DifferentiationTest::testLinear() { 0035 // data 0036 QVector<int> xData = {1,2,3,4}; 0037 QVector<double> yData = {1.,2.,3.,4.}; 0038 0039 //data source columns 0040 Column xDataColumn("x", AbstractColumn::ColumnMode::Integer); 0041 xDataColumn.replaceInteger(0, xData); 0042 0043 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0044 yDataColumn.replaceValues(0, yData); 0045 0046 XYDifferentiationCurve differentiationCurve("differentiation"); 0047 differentiationCurve.setXDataColumn(&xDataColumn); 0048 differentiationCurve.setYDataColumn(&yDataColumn); 0049 0050 //prepare the differentiation 0051 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0052 differentiationCurve.setDifferentiationData(differentiationData); 0053 0054 //perform the differentiation 0055 differentiationCurve.recalculate(); 0056 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0057 0058 //check the results 0059 QCOMPARE(differentiationResult.available, true); 0060 QCOMPARE(differentiationResult.valid, true); 0061 0062 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0063 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0064 0065 const int np = resultXDataColumn->rowCount(); 0066 QCOMPARE(np, 4); 0067 0068 for (int i = 0; i < np; i++) 0069 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0070 0071 QCOMPARE(resultYDataColumn->valueAt(0), 1.); 0072 QCOMPARE(resultYDataColumn->valueAt(1), 1.); 0073 QCOMPARE(resultYDataColumn->valueAt(2), 1.); 0074 QCOMPARE(resultYDataColumn->valueAt(3), 1.); 0075 } 0076 0077 void DifferentiationTest::testLinearNonEquidistant() { 0078 // data 0079 QVector<double> xData = {1.,1.5,3.,5.}; 0080 QVector<double> yData = {1.,1.5,3.,5.}; 0081 0082 //data source columns 0083 Column xDataColumn("x", AbstractColumn::ColumnMode::Numeric); 0084 xDataColumn.replaceValues(0, xData); 0085 0086 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0087 yDataColumn.replaceValues(0, yData); 0088 0089 XYDifferentiationCurve differentiationCurve("differentiation"); 0090 differentiationCurve.setXDataColumn(&xDataColumn); 0091 differentiationCurve.setYDataColumn(&yDataColumn); 0092 0093 //prepare the differentiation 0094 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0095 differentiationCurve.setDifferentiationData(differentiationData); 0096 0097 //perform the differentiation 0098 differentiationCurve.recalculate(); 0099 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0100 0101 //check the results 0102 QCOMPARE(differentiationResult.available, true); 0103 QCOMPARE(differentiationResult.valid, true); 0104 0105 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0106 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0107 0108 const int np = resultXDataColumn->rowCount(); 0109 QCOMPARE(np, 4); 0110 0111 for (int i = 0; i < np; i++) 0112 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0113 0114 QCOMPARE(resultYDataColumn->valueAt(0), 1.); 0115 QCOMPARE(resultYDataColumn->valueAt(1), 1.); 0116 QCOMPARE(resultYDataColumn->valueAt(2), 1.); 0117 QCOMPARE(resultYDataColumn->valueAt(3), 1.); 0118 } 0119 0120 void DifferentiationTest::testQuadratic() { 0121 // data 0122 QVector<double> xData = {1.,2.,3.,4.}; 0123 QVector<double> yData = {1.,4.,9.,16.}; 0124 0125 //data source columns 0126 Column xDataColumn("x", AbstractColumn::ColumnMode::Numeric); 0127 xDataColumn.replaceValues(0, xData); 0128 0129 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0130 yDataColumn.replaceValues(0, yData); 0131 0132 XYDifferentiationCurve differentiationCurve("differentiation"); 0133 differentiationCurve.setXDataColumn(&xDataColumn); 0134 differentiationCurve.setYDataColumn(&yDataColumn); 0135 0136 //prepare the differentiation 0137 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0138 differentiationCurve.setDifferentiationData(differentiationData); 0139 0140 //perform the differentiation 0141 differentiationCurve.recalculate(); 0142 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0143 0144 //check the results 0145 QCOMPARE(differentiationResult.available, true); 0146 QCOMPARE(differentiationResult.valid, true); 0147 0148 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0149 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0150 0151 const int np = resultXDataColumn->rowCount(); 0152 QCOMPARE(np, 4); 0153 0154 for (int i = 0; i < np; i++) 0155 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0156 0157 QCOMPARE(resultYDataColumn->valueAt(0), 2.); 0158 QCOMPARE(resultYDataColumn->valueAt(1), 4.); 0159 QCOMPARE(resultYDataColumn->valueAt(2), 6.); 0160 QCOMPARE(resultYDataColumn->valueAt(3), 8.); 0161 } 0162 0163 void DifferentiationTest::testQuadraticNonEquidistant() { 0164 // data 0165 QVector<double> xData = {1.,1.5,3.,5.}; 0166 QVector<double> yData = {1.,2.25,9.,25.}; 0167 0168 //data source columns 0169 Column xDataColumn("x", AbstractColumn::ColumnMode::Numeric); 0170 xDataColumn.replaceValues(0, xData); 0171 0172 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0173 yDataColumn.replaceValues(0, yData); 0174 0175 XYDifferentiationCurve differentiationCurve("differentiation"); 0176 differentiationCurve.setXDataColumn(&xDataColumn); 0177 differentiationCurve.setYDataColumn(&yDataColumn); 0178 0179 //prepare the differentiation 0180 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0181 differentiationCurve.setDifferentiationData(differentiationData); 0182 0183 //perform the differentiation 0184 differentiationCurve.recalculate(); 0185 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0186 0187 //check the results 0188 QCOMPARE(differentiationResult.available, true); 0189 QCOMPARE(differentiationResult.valid, true); 0190 0191 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0192 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0193 0194 const int np = resultXDataColumn->rowCount(); 0195 QCOMPARE(np, 4); 0196 0197 for (int i = 0; i < np; i++) 0198 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0199 0200 QCOMPARE(resultYDataColumn->valueAt(0), 2.); 0201 QCOMPARE(resultYDataColumn->valueAt(1), 3.); 0202 QCOMPARE(resultYDataColumn->valueAt(2), 6.); 0203 QCOMPARE(resultYDataColumn->valueAt(3), 10.); 0204 } 0205 0206 void DifferentiationTest::testQuadraticSecondOrder() { 0207 // data 0208 QVector<double> xData = {1.,2.,3.,4.}; 0209 QVector<double> yData = {1.,4.,9.,16.}; 0210 0211 //data source columns 0212 Column xDataColumn("x", AbstractColumn::ColumnMode::Numeric); 0213 xDataColumn.replaceValues(0, xData); 0214 0215 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0216 yDataColumn.replaceValues(0, yData); 0217 0218 XYDifferentiationCurve differentiationCurve("differentiation"); 0219 differentiationCurve.setXDataColumn(&xDataColumn); 0220 differentiationCurve.setYDataColumn(&yDataColumn); 0221 0222 //prepare the differentiation 0223 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0224 differentiationData.derivOrder = nsl_diff_deriv_order_second; 0225 differentiationCurve.setDifferentiationData(differentiationData); 0226 0227 //perform the differentiation 0228 differentiationCurve.recalculate(); 0229 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0230 0231 //check the results 0232 QCOMPARE(differentiationResult.available, true); 0233 QCOMPARE(differentiationResult.valid, true); 0234 0235 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0236 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0237 0238 const int np = resultXDataColumn->rowCount(); 0239 QCOMPARE(np, 4); 0240 0241 for (int i = 0; i < np; i++) 0242 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0243 0244 QCOMPARE(resultYDataColumn->valueAt(0), 2.); 0245 QCOMPARE(resultYDataColumn->valueAt(1), 2.); 0246 QCOMPARE(resultYDataColumn->valueAt(2), 2.); 0247 QCOMPARE(resultYDataColumn->valueAt(3), 2.); 0248 } 0249 0250 void DifferentiationTest::testCubicSecondOrder() { 0251 // data 0252 QVector<double> xData = {1.,2.,3.,4.}; 0253 QVector<double> yData = {1.,8.,27.,64.}; 0254 0255 //data source columns 0256 Column xDataColumn("x", AbstractColumn::ColumnMode::Numeric); 0257 xDataColumn.replaceValues(0, xData); 0258 0259 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0260 yDataColumn.replaceValues(0, yData); 0261 0262 XYDifferentiationCurve differentiationCurve("differentiation"); 0263 differentiationCurve.setXDataColumn(&xDataColumn); 0264 differentiationCurve.setYDataColumn(&yDataColumn); 0265 0266 //prepare the differentiation 0267 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0268 differentiationData.derivOrder = nsl_diff_deriv_order_second; 0269 differentiationCurve.setDifferentiationData(differentiationData); 0270 0271 //perform the differentiation 0272 differentiationCurve.recalculate(); 0273 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0274 0275 //check the results 0276 QCOMPARE(differentiationResult.available, true); 0277 QCOMPARE(differentiationResult.valid, true); 0278 0279 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0280 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0281 0282 const int np = resultXDataColumn->rowCount(); 0283 QCOMPARE(np, 4); 0284 0285 for (int i = 0; i < np; i++) 0286 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0287 0288 QCOMPARE(resultYDataColumn->valueAt(0), 6.); 0289 QCOMPARE(resultYDataColumn->valueAt(1), 12.); 0290 QCOMPARE(resultYDataColumn->valueAt(2), 18.); 0291 QCOMPARE(resultYDataColumn->valueAt(3), 24.); 0292 } 0293 0294 void DifferentiationTest::testCubicThirdOrder() { 0295 // data 0296 QVector<double> xData = {1.,2.,3.,4.,5.}; 0297 QVector<double> yData = {1.,8.,27.,64.,125.}; 0298 0299 //data source columns 0300 Column xDataColumn("x", AbstractColumn::ColumnMode::Numeric); 0301 xDataColumn.replaceValues(0, xData); 0302 0303 Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric); 0304 yDataColumn.replaceValues(0, yData); 0305 0306 XYDifferentiationCurve differentiationCurve("differentiation"); 0307 differentiationCurve.setXDataColumn(&xDataColumn); 0308 differentiationCurve.setYDataColumn(&yDataColumn); 0309 0310 //prepare the differentiation 0311 XYDifferentiationCurve::DifferentiationData differentiationData = differentiationCurve.differentiationData(); 0312 differentiationData.derivOrder = nsl_diff_deriv_order_third; 0313 differentiationCurve.setDifferentiationData(differentiationData); 0314 0315 //perform the differentiation 0316 differentiationCurve.recalculate(); 0317 const XYDifferentiationCurve::DifferentiationResult& differentiationResult = differentiationCurve.differentiationResult(); 0318 0319 //check the results 0320 QCOMPARE(differentiationResult.available, true); 0321 QCOMPARE(differentiationResult.valid, true); 0322 0323 const AbstractColumn* resultXDataColumn = differentiationCurve.xColumn(); 0324 const AbstractColumn* resultYDataColumn = differentiationCurve.yColumn(); 0325 0326 const int np = resultXDataColumn->rowCount(); 0327 QCOMPARE(np, 5); 0328 0329 for (int i = 0; i < np; i++) 0330 QCOMPARE(resultXDataColumn->valueAt(i), xData[i]); 0331 0332 QCOMPARE(resultYDataColumn->valueAt(0), 6.); 0333 QCOMPARE(resultYDataColumn->valueAt(1), 6.); 0334 QCOMPARE(resultYDataColumn->valueAt(2), 6.); 0335 QCOMPARE(resultYDataColumn->valueAt(3), 6.); 0336 QCOMPARE(resultYDataColumn->valueAt(4), 6.); 0337 } 0338 0339 QTEST_MAIN(DifferentiationTest)