File indexing completed on 2024-05-05 03:48:44

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