File indexing completed on 2024-05-05 03:48:26
0001 /* 0002 File : HilbertTransformTest.cpp 0003 Project : LabPlot 0004 Description : Tests for Hilbert transform 0005 -------------------------------------------------------------------- 0006 SPDX-FileCopyrightText: 2021 Stefan Gerlach <stefan.gerlach@uni.kn> 0007 0008 SPDX-License-Identifier: GPL-2.0-or-later 0009 */ 0010 0011 #include "HilbertTransformTest.h" 0012 #include "backend/core/column/Column.h" 0013 #include "backend/worksheet/plots/cartesian/XYHilbertTransformCurve.h" 0014 0015 // ############################################################################## 0016 0017 void HilbertTransformTest::test1() { 0018 // data 0019 QVector<int> xData = {1, 2, 3, 4}; 0020 QVector<double> yData = {1., 2., 3., 4.}; 0021 0022 // data source columns 0023 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0024 xDataColumn.replaceInteger(0, xData); 0025 0026 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0027 yDataColumn.replaceValues(0, yData); 0028 0029 XYHilbertTransformCurve curve(QStringLiteral("Hilbert Trafo")); 0030 curve.setXDataColumn(&xDataColumn); 0031 curve.setYDataColumn(&yDataColumn); 0032 0033 // prepare the transform 0034 XYHilbertTransformCurve::TransformData data = curve.transformData(); 0035 curve.setTransformData(data); 0036 0037 // perform the transform 0038 const auto& result = curve.result(); 0039 0040 // check the results 0041 QCOMPARE(result.available, true); 0042 QCOMPARE(result.valid, true); 0043 0044 const AbstractColumn* resultXDataColumn = curve.xColumn(); 0045 const AbstractColumn* resultYDataColumn = curve.yColumn(); 0046 0047 const int np = resultXDataColumn->rowCount(); 0048 QCOMPARE(np, 4); 0049 0050 for (int i = 0; i < np; i++) 0051 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0052 for (int i = 0; i < np; i++) 0053 DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(i)); 0054 0055 QCOMPARE(resultYDataColumn->valueAt(0), 1.); 0056 QCOMPARE(resultYDataColumn->valueAt(1), -1.); 0057 QCOMPARE(resultYDataColumn->valueAt(2), -1.); 0058 QCOMPARE(resultYDataColumn->valueAt(3), 1.); 0059 } 0060 0061 void HilbertTransformTest::test2() { 0062 // data 0063 QVector<int> xData = {1, 2, 3, 4, 5, 6, 7}; 0064 QVector<double> yData = {1., 2., 3., 4., 3., 2., 1.}; 0065 0066 // data source columns 0067 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0068 xDataColumn.replaceInteger(0, xData); 0069 0070 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0071 yDataColumn.replaceValues(0, yData); 0072 0073 XYHilbertTransformCurve curve(QStringLiteral("Hilbert Trafo")); 0074 curve.setXDataColumn(&xDataColumn); 0075 curve.setYDataColumn(&yDataColumn); 0076 0077 // prepare the transform 0078 XYHilbertTransformCurve::TransformData data = curve.transformData(); 0079 curve.setTransformData(data); 0080 0081 // perform the transform 0082 const auto& result = curve.result(); 0083 0084 // check the results 0085 QCOMPARE(result.available, true); 0086 QCOMPARE(result.valid, true); 0087 0088 const AbstractColumn* resultXDataColumn = curve.xColumn(); 0089 const AbstractColumn* resultYDataColumn = curve.yColumn(); 0090 0091 const int np = resultXDataColumn->rowCount(); 0092 QCOMPARE(np, 7); 0093 0094 for (int i = 0; i < np; i++) 0095 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0096 for (int i = 0; i < np; i++) 0097 DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(i)); 0098 0099 QCOMPARE(resultYDataColumn->valueAt(0), -0.736238855198572); 0100 QCOMPARE(resultYDataColumn->valueAt(1), -1.22454414518711); 0101 QCOMPARE(resultYDataColumn->valueAt(2), -1.29334051930247); 0102 FuzzyCompare(resultYDataColumn->valueAt(3), 0., 1.e-15); 0103 QCOMPARE(resultYDataColumn->valueAt(4), -resultYDataColumn->valueAt(2)); 0104 QCOMPARE(resultYDataColumn->valueAt(5), -resultYDataColumn->valueAt(1)); 0105 QCOMPARE(resultYDataColumn->valueAt(6), -resultYDataColumn->valueAt(0)); 0106 } 0107 0108 void HilbertTransformTest::test3() { 0109 // data 0110 QVector<int> xData = {1, 2, 3, 4, 5, 6, 7, 8}; 0111 QVector<double> yData = {1, 2, 3, 4, 5, 6, 7, 8}; 0112 0113 // data source columns 0114 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0115 xDataColumn.replaceInteger(0, xData); 0116 0117 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0118 yDataColumn.replaceValues(0, yData); 0119 0120 XYHilbertTransformCurve curve(QStringLiteral("Hilbert trafo")); 0121 curve.setXDataColumn(&xDataColumn); 0122 curve.setYDataColumn(&yDataColumn); 0123 0124 // prepare the transform 0125 XYHilbertTransformCurve::TransformData data = curve.transformData(); 0126 0127 // perform the transform 0128 curve.setTransformData(data); 0129 0130 const auto& result = curve.result(); 0131 0132 // check the results 0133 QCOMPARE(result.available, true); 0134 QCOMPARE(result.valid, true); 0135 0136 const AbstractColumn* resultXDataColumn = curve.xColumn(); 0137 const AbstractColumn* resultYDataColumn = curve.yColumn(); 0138 0139 const int np = resultXDataColumn->rowCount(); 0140 QCOMPARE(np, 8); 0141 0142 for (int i = 0; i < np; i++) 0143 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0144 for (int i = 0; i < np; i++) 0145 DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(i)); 0146 0147 QCOMPARE(resultYDataColumn->valueAt(0), 3.82842712474619); 0148 QCOMPARE(resultYDataColumn->valueAt(1), -1.); 0149 QCOMPARE(resultYDataColumn->valueAt(2), -1.); 0150 QCOMPARE(resultYDataColumn->valueAt(3), -1.82842712474619); 0151 QCOMPARE(resultYDataColumn->valueAt(4), -1.82842712474619); 0152 QCOMPARE(resultYDataColumn->valueAt(5), -1.); 0153 QCOMPARE(resultYDataColumn->valueAt(6), -1.); 0154 QCOMPARE(resultYDataColumn->valueAt(7), 3.82842712474619); 0155 } 0156 0157 void HilbertTransformTest::test4() { 0158 // data 0159 QVector<int> xData = {1, 2, 3, 4, 5, 6, 7, 8, 9}; 0160 QVector<double> yData = {1., -1., 2., -2., 3., -3., 4., -4., 5.}; 0161 0162 // data source columns 0163 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0164 xDataColumn.replaceInteger(0, xData); 0165 0166 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0167 yDataColumn.replaceValues(0, yData); 0168 0169 XYHilbertTransformCurve curve(QStringLiteral("Hilbert trafo")); 0170 curve.setXDataColumn(&xDataColumn); 0171 curve.setYDataColumn(&yDataColumn); 0172 0173 // prepare the transform 0174 XYHilbertTransformCurve::TransformData data = curve.transformData(); 0175 0176 // perform the transform 0177 curve.setTransformData(data); 0178 0179 const auto& result = curve.result(); 0180 0181 // check the results 0182 QCOMPARE(result.available, true); 0183 QCOMPARE(result.valid, true); 0184 0185 const AbstractColumn* resultXDataColumn = curve.xColumn(); 0186 const AbstractColumn* resultYDataColumn = curve.yColumn(); 0187 0188 const int np = resultXDataColumn->rowCount(); 0189 QCOMPARE(np, 9); 0190 0191 for (int i = 0; i < np; i++) 0192 QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1); 0193 for (int i = 0; i < np; i++) 0194 DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(i)); 0195 0196 QCOMPARE(resultYDataColumn->valueAt(0), 5.73760166175338); 0197 QCOMPARE(resultYDataColumn->valueAt(1), -2.91301405896714); 0198 QCOMPARE(resultYDataColumn->valueAt(2), 2.9964917553466); 0199 QCOMPARE(resultYDataColumn->valueAt(3), -2.12747459905025); 0200 QCOMPARE(resultYDataColumn->valueAt(4), 1.6613081372851); 0201 QCOMPARE(resultYDataColumn->valueAt(5), -1.10190838316691); 0202 QCOMPARE(resultYDataColumn->valueAt(6), -0.146025447565372); 0203 QCOMPARE(resultYDataColumn->valueAt(7), 0.674355652492414); 0204 QCOMPARE(resultYDataColumn->valueAt(8), -4.78133471812782); 0205 } 0206 0207 void HilbertTransformTest::testPerformance() { 0208 // data 0209 QVector<int> xData; 0210 QVector<double> yData; 0211 #ifdef HAVE_FFTW3 0212 const int N = 1e6; 0213 #else // GSL is much slower 0214 const int N = 2e5; 0215 #endif 0216 for (int i = 0; i < N; i++) { 0217 xData.append(i); 0218 yData.append(i % 100); 0219 } 0220 0221 // data source columns 0222 Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer); 0223 xDataColumn.replaceInteger(0, xData); 0224 0225 Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double); 0226 yDataColumn.replaceValues(0, yData); 0227 0228 XYHilbertTransformCurve curve(QStringLiteral("Hilbert trafo")); 0229 curve.setXDataColumn(&xDataColumn); 0230 curve.setYDataColumn(&yDataColumn); 0231 0232 // prepare and perform the convolution 0233 XYHilbertTransformCurve::TransformData data = curve.transformData(); 0234 QBENCHMARK { 0235 // triggers recalculate() 0236 curve.setTransformData(data); 0237 } 0238 0239 // check the results 0240 const auto& result = curve.result(); 0241 0242 QCOMPARE(result.available, true); 0243 QCOMPARE(result.valid, true); 0244 0245 const AbstractColumn* resultXDataColumn = curve.xColumn(); 0246 0247 const int np = resultXDataColumn->rowCount(); 0248 QCOMPARE(np, N); 0249 } 0250 0251 QTEST_MAIN(HilbertTransformTest)