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)