File indexing completed on 2024-05-12 03:49:33
0001 /* 0002 File : NSLDFTTest.cpp 0003 Project : LabPlot 0004 Description : NSL Tests for DFT 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 "NSLDFTTest.h" 0012 #include "backend/lib/macros.h" 0013 0014 extern "C" { 0015 #include "backend/nsl/nsl_dft.h" 0016 } 0017 0018 #define ONESIDED 0 0019 #define TWOSIDED 1 0020 const int N = 10; 0021 0022 // ############################################################################## 0023 // ################# one sided tests 0024 // ############################################################################## 0025 0026 void NSLDFTTest::testOnesided_real() { 0027 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0028 const double result[] = {10, 2, -5.85410196624968, 2, 0.854101966249685}; 0029 0030 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_real); 0031 for (unsigned int i = 0; i < N / 2; i++) 0032 QCOMPARE(data[i], result[i]); 0033 } 0034 0035 void NSLDFTTest::testOnesided_imag() { 0036 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0037 const double result[] = {0, -4.97979656976556, 0, 0.449027976579585, 0}; 0038 0039 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_imag); 0040 for (unsigned int i = 0; i < N / 2; i++) { 0041 DEBUG(std::setprecision(15) << data[i]); 0042 if (i == 2) 0043 QCOMPARE(data[i] + 1., 1.); // -1.11022302462516e-16 (Win) 0044 else 0045 QCOMPARE(data[i], result[i]); 0046 } 0047 } 0048 0049 void NSLDFTTest::testOnesided_magnitude() { 0050 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0051 const double result[] = {10, 5.36641163872553, 5.85410196624968, 2.04978684837013, 0.854101966249685}; 0052 0053 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_magnitude); 0054 for (unsigned int i = 0; i < N / 2; i++) 0055 QCOMPARE(data[i], result[i]); 0056 } 0057 0058 void NSLDFTTest::testOnesided_amplitude() { 0059 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0060 const double result[] = {1, 1.07328232774511, 1.17082039324994, 0.409957369674026, 0.170820393249937}; 0061 0062 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_amplitude); 0063 for (unsigned int i = 0; i < N / 2; i++) 0064 QCOMPARE(data[i], result[i]); 0065 } 0066 0067 void NSLDFTTest::testOnesided_power() { 0068 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0069 const double result[] = {10, 5.75967477524977, 6.85410196624968, 0.840325224750231, 0.145898033750316}; 0070 0071 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_power); 0072 for (unsigned int i = 0; i < N / 2; i++) 0073 QCOMPARE(data[i], result[i]); 0074 } 0075 0076 void NSLDFTTest::testOnesided_phase() { 0077 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0078 const double result[] = {0, 1.18889174012102, -3.14159265358979, -0.220851801285041, 0}; 0079 0080 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_phase); 0081 for (unsigned int i = 0; i < N / 2; i++) { 0082 DEBUG(std::setprecision(15) << data[i]); 0083 if (i == 2) // sign can be + or - 0084 QCOMPARE(fabs(data[i]), fabs(result[i])); 0085 else 0086 QCOMPARE(data[i], result[i]); 0087 } 0088 } 0089 0090 void NSLDFTTest::testOnesided_dB() { 0091 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0092 const double result[] = {0, 0.614279569861449, 1.36980556663896, -7.7452260401377, -15.3492056533593}; 0093 0094 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_dB); 0095 for (unsigned int i = 0; i < N / 2; i++) 0096 QCOMPARE(data[i], result[i]); 0097 } 0098 0099 void NSLDFTTest::testOnesided_squaremagnitude() { 0100 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0101 const double result[] = {100, 28.7983738762488, 34.2705098312484, 4.20162612375116, 0.729490168751578}; 0102 0103 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_squaremagnitude); 0104 for (unsigned int i = 0; i < N / 2; i++) 0105 QCOMPARE(data[i], result[i]); 0106 } 0107 0108 void NSLDFTTest::testOnesided_squareamplitude() { 0109 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0110 const double result[] = {1, 1.15193495504995, 1.37082039324994, 0.168065044950046, 0.0291796067500631}; 0111 0112 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_squareamplitude); 0113 for (unsigned int i = 0; i < N / 2; i++) 0114 QCOMPARE(data[i], result[i]); 0115 } 0116 0117 void NSLDFTTest::testOnesided_normdB() { 0118 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0119 const double result[] = {-1.36980556663896, -0.755525996777514, 0, -9.11503160677666, -16.7190112199983}; 0120 0121 nsl_dft_transform(data, 1, N, ONESIDED, nsl_dft_result_normdB); 0122 for (unsigned int i = 0; i < N / 2; i++) 0123 QCOMPARE(data[i], result[i]); 0124 } 0125 0126 // ############################################################################## 0127 // ################# two sided tests 0128 // ############################################################################## 0129 0130 void NSLDFTTest::testTwosided_real() { 0131 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0132 const double result[] = {10, 2, -5.85410196624968, 2, 0.854101966249685, 2, 0.854101966249685, 2, -5.85410196624968, 2}; 0133 0134 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_real); 0135 for (unsigned int i = 0; i < N; i++) 0136 QCOMPARE(data[i], result[i]); 0137 } 0138 0139 void NSLDFTTest::testTwosided_imag() { 0140 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0141 const double result[] = {0, -4.97979656976556, 0, 0.449027976579585, 0, 0, 0, -0.449027976579585, 0, 4.97979656976556}; 0142 0143 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_imag); 0144 for (unsigned int i = 0; i < N; i++) { 0145 DEBUG(std::setprecision(15) << data[i]); 0146 if (i == 2 || i == 8) 0147 QCOMPARE(data[i] + 1., 1.); // -1.11022302462516e-16 (Win) 0148 else 0149 QCOMPARE(data[i], result[i]); 0150 } 0151 } 0152 0153 void NSLDFTTest::testTwosided_magnitude() { 0154 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0155 const double result[] = {10, 0156 5.36641163872553, 0157 5.85410196624968, 0158 2.04978684837013, 0159 0.854101966249685, 0160 2, 0161 0.854101966249685, 0162 2.04978684837013, 0163 5.85410196624968, 0164 5.36641163872553}; 0165 0166 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_magnitude); 0167 for (unsigned int i = 0; i < N; i++) 0168 QCOMPARE(data[i], result[i]); 0169 } 0170 0171 void NSLDFTTest::testTwosided_amplitude() { 0172 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0173 const double result[] = {1, 0174 1.07328232774511, 0175 1.17082039324994, 0176 0.409957369674026, 0177 0.170820393249937, 0178 0.4, 0179 0.170820393249937, 0180 0.409957369674026, 0181 1.17082039324994, 0182 1.07328232774511}; 0183 0184 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_amplitude); 0185 for (unsigned int i = 0; i < N; i++) 0186 QCOMPARE(data[i], result[i]); 0187 } 0188 0189 void NSLDFTTest::testTwosided_power() { 0190 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0191 const double result[] = {10, 0192 5.75967477524977, 0193 6.85410196624968, 0194 0.840325224750231, 0195 0.145898033750316, 0196 0.8, 0197 0.145898033750316, 0198 0.840325224750231, 0199 6.85410196624968, 0200 5.75967477524977}; 0201 0202 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_power); 0203 for (unsigned int i = 0; i < N; i++) 0204 QCOMPARE(data[i], result[i]); 0205 } 0206 0207 void NSLDFTTest::testTwosided_phase() { 0208 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0209 const double result[] = {0, 1.18889174012102, -3.14159265358979, -0.220851801285041, 0, 0, 0, 0.220851801285041, 3.14159265358979, -1.18889174012102}; 0210 0211 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_phase); 0212 for (unsigned int i = 0; i < N; i++) { 0213 DEBUG(std::setprecision(15) << data[i]); 0214 if (i == 2 || i == 8) // sign can be + or - 0215 QCOMPARE(fabs(data[i]), fabs(result[i])); 0216 else 0217 QCOMPARE(data[i], result[i]); 0218 } 0219 } 0220 0221 void NSLDFTTest::testTwosided_dB() { 0222 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0223 const double result[] = {0, 0224 0.614279569861449, 0225 1.36980556663896, 0226 -7.7452260401377, 0227 -15.3492056533593, 0228 -7.95880017344075, 0229 -15.3492056533593, 0230 -7.7452260401377, 0231 1.36980556663896, 0232 0.614279569861449}; 0233 0234 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_dB); 0235 for (unsigned int i = 0; i < N; i++) 0236 QCOMPARE(data[i], result[i]); 0237 } 0238 0239 void NSLDFTTest::testTwosided_squaremagnitude() { 0240 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0241 const double result[] = {100, 0242 28.7983738762488, 0243 34.2705098312484, 0244 4.20162612375116, 0245 0.729490168751578, 0246 4, 0247 0.729490168751578, 0248 4.20162612375116, 0249 34.2705098312484, 0250 28.7983738762488}; 0251 0252 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_squaremagnitude); 0253 for (unsigned int i = 0; i < N; i++) 0254 QCOMPARE(data[i], result[i]); 0255 } 0256 0257 void NSLDFTTest::testTwosided_squareamplitude() { 0258 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0259 const double result[] = {1, 0260 1.15193495504995, 0261 1.37082039324994, 0262 0.168065044950046, 0263 0.0291796067500631, 0264 0.16, 0265 0.0291796067500631, 0266 0.168065044950046, 0267 1.37082039324994, 0268 1.15193495504995}; 0269 0270 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_squareamplitude); 0271 for (unsigned int i = 0; i < N; i++) 0272 QCOMPARE(data[i], result[i]); 0273 } 0274 0275 void NSLDFTTest::testTwosided_normdB() { 0276 double data[] = {1, 1, 3, 3, 1, -1, 0, 1, 1, 0}; 0277 const double result[] = {-1.36980556663896, 0278 -0.755525996777514, 0279 0, 0280 -9.11503160677666, 0281 -16.7190112199983, 0282 -9.32860574007971, 0283 -16.7190112199983, 0284 -9.11503160677666, 0285 0, 0286 -0.755525996777514}; 0287 0288 nsl_dft_transform(data, 1, N, TWOSIDED, nsl_dft_result_normdB); 0289 for (unsigned int i = 0; i < N; i++) 0290 QCOMPARE(data[i], result[i]); 0291 } 0292 0293 // ############################################################################## 0294 // ################# performance 0295 // ############################################################################## 0296 0297 #ifdef HAVE_FFTW3 0298 const int NN = 1e6; 0299 #else // GSL is much slower 0300 const int NN = 1e6; 0301 #endif 0302 0303 void NSLDFTTest::testPerformance_onesided() { 0304 double* data = new double[NN]; 0305 0306 for (int i = 0; i < NN; i++) 0307 data[i] = 1.; 0308 0309 QBENCHMARK { nsl_dft_transform(data, 1, NN, ONESIDED, nsl_dft_result_real); } 0310 0311 delete[] data; 0312 } 0313 0314 void NSLDFTTest::testPerformance_twosided() { 0315 double* data = new double[NN]; 0316 0317 for (int i = 0; i < NN; i++) 0318 data[i] = 1.; 0319 0320 QBENCHMARK { nsl_dft_transform(data, 1, NN, TWOSIDED, nsl_dft_result_real); } 0321 0322 delete[] data; 0323 } 0324 0325 QTEST_MAIN(NSLDFTTest)