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