File indexing completed on 2024-05-05 16:00:20

0001 /***************************************************************************
0002     File                 : NSLDiffTest.cpp
0003     Project              : LabPlot
0004     Description          : NSL Tests for numerical differentiation
0005     --------------------------------------------------------------------
0006     Copyright            : (C) 2019 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 "NSLDiffTest.h"
0029 #include <QScopedArrayPointer>
0030 
0031 extern "C" {
0032 #include "backend/nsl/nsl_diff.h"
0033 }
0034 
0035 //##############################################################################
0036 //#################  first derivative tests
0037 //##############################################################################
0038 
0039 const int N = 7;
0040 double xdata[] = {1, 2, 4, 8, 16, 32, 64};
0041 
0042 void NSLDiffTest::testFirst_order2() {
0043     double ydata[] = {1, 4, 16, 64, 256, 1024, 4096};
0044 
0045     int status = nsl_diff_first_deriv(xdata, ydata, N, 2);
0046     QCOMPARE(status, 0);
0047     for (unsigned int i = 0; i < N; i++)
0048         QCOMPARE(ydata[i], 2 * xdata[i]);
0049 }
0050 
0051 void NSLDiffTest::testFirst_order4() {
0052     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0053 
0054     int status = nsl_diff_first_deriv(xdata, ydata, N, 4);
0055     QCOMPARE(status, 0);
0056     for (unsigned int i = 0; i < N; i++)
0057         QCOMPARE(ydata[i], 3 * xdata[i]*xdata[i]);
0058 }
0059 
0060 void NSLDiffTest::testFirst_avg() {
0061     double ydata[] = {1, 4, 16, 64, 256, 1024, 4096};
0062     double result[] = {3, 4.5, 9, 18, 36, 72, 96};
0063 
0064     int status = nsl_diff_first_deriv_avg(xdata, ydata, N);
0065     QCOMPARE(status, 0);
0066     for (unsigned int i = 0; i < N; i++)
0067         QCOMPARE(ydata[i], result[i]);
0068 }
0069 
0070 //##############################################################################
0071 //#################  second derivative tests
0072 //##############################################################################
0073 
0074 void NSLDiffTest::testSecond_order1() {
0075     double ydata[] = {1, 4, 16, 64, 256, 1024, 4096};
0076 
0077     int status = nsl_diff_second_deriv(xdata, ydata, N, 1);
0078     QCOMPARE(status, 0);
0079     for (double d : ydata)
0080         QCOMPARE(d, 2.);
0081 }
0082 
0083 void NSLDiffTest::testSecond_order2() {
0084     double ydata[] = {1, 4, 16, 64, 256, 1024, 4096};
0085 
0086     int status = nsl_diff_second_deriv(xdata, ydata, N, 2);
0087     QCOMPARE(status, 0);
0088     for (double d : ydata)
0089         QCOMPARE(d, 2.);
0090 }
0091 
0092 void NSLDiffTest::testSecond_order3() {
0093     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0094 
0095     int status = nsl_diff_second_deriv(xdata, ydata, N, 3);
0096     QCOMPARE(status, 0);
0097     for (unsigned int i = 0; i < N; i++)
0098         QCOMPARE(ydata[i], 6. * xdata[i]);
0099 }
0100 
0101 //##############################################################################
0102 //#################  higher derivative tests
0103 //##############################################################################
0104 
0105 void NSLDiffTest::testThird_order2() {
0106     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0107 
0108     int status = nsl_diff_third_deriv(xdata, ydata, N, 2);
0109     QCOMPARE(status, 0);
0110     for (double d : ydata)
0111         QCOMPARE(d, 6.);
0112 }
0113 
0114 void NSLDiffTest::testFourth_order1() {
0115     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0116 
0117     int status = nsl_diff_fourth_deriv(xdata, ydata, N, 1);
0118     QCOMPARE(status, 0);
0119     for (double d : ydata)
0120         QCOMPARE(d, 0.);
0121 }
0122 
0123 void NSLDiffTest::testFourth_order3() {
0124     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0125 
0126     int status = nsl_diff_fourth_deriv(xdata, ydata, N, 3);
0127     QCOMPARE(status, 0);
0128     for (double d : ydata)
0129         QCOMPARE(d + 1., 1.);
0130 }
0131 
0132 void NSLDiffTest::testFifth_order2() {
0133     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0134 
0135     int status = nsl_diff_fifth_deriv(xdata, ydata, N, 2);
0136     QCOMPARE(status, 0);
0137     for (double d : ydata)
0138         QCOMPARE(d + 1., 1.);
0139 }
0140 
0141 void NSLDiffTest::testSixth_order1() {
0142     double ydata[] = {1, 8, 64, 512, 4096, 32768, 262144};
0143 
0144     int status = nsl_diff_sixth_deriv(xdata, ydata, N, 1);
0145     QCOMPARE(status, 0);
0146     for (double d : ydata)
0147         QCOMPARE(d + 1., 1.);
0148 }
0149 
0150 //##############################################################################
0151 //#################  performance
0152 //##############################################################################
0153 
0154 void NSLDiffTest::testPerformance_first() {
0155     const int NN = 1e6;
0156     QScopedArrayPointer<double> xdata(new double[NN]);
0157     QScopedArrayPointer<double> ydata(new double[NN]);
0158 
0159     for (int i = 0;  i < NN; i++)
0160         xdata[i] = ydata[i] = (double)i;
0161 
0162     QBENCHMARK {
0163         int status = nsl_diff_first_deriv(xdata.data(), ydata.data(), NN, 2);
0164         QCOMPARE(status, 0);
0165     }
0166 }
0167 
0168 void NSLDiffTest::testPerformance_second() {
0169     const int NN = 1e6;
0170     QScopedArrayPointer<double> xdata(new double[NN]);
0171     QScopedArrayPointer<double> ydata(new double[NN]);
0172 
0173     for (int i = 0;  i < NN; i++)
0174         xdata[i] = ydata[i] = (double)i;
0175 
0176     QBENCHMARK {
0177         int status = nsl_diff_second_deriv(xdata.data(), ydata.data(), NN, 2);
0178         QCOMPARE(status, 0);
0179     }
0180 }
0181 
0182 void NSLDiffTest::testPerformance_third() {
0183     const int NN = 1e6;
0184     QScopedArrayPointer<double> xdata(new double[NN]);
0185     QScopedArrayPointer<double> ydata(new double[NN]);
0186 
0187     for (int i = 0;  i < NN; i++)
0188         xdata[i] = ydata[i] = (double)i;
0189     
0190     QBENCHMARK {
0191         int status = nsl_diff_third_deriv(xdata.data(), ydata.data(), NN, 2);
0192         QCOMPARE(status, 0);
0193     }
0194 }
0195 
0196 QTEST_MAIN(NSLDiffTest)