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)