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

0001 /*
0002     File                 : ConvolutionTest.cpp
0003     Project              : LabPlot
0004     Description          : Tests for data convolution
0005     --------------------------------------------------------------------
0006     SPDX-FileCopyrightText: 2018 Stefan Gerlach <stefan.gerlach@uni.kn>
0007 
0008     SPDX-License-Identifier: GPL-2.0-or-later
0009 */
0010 
0011 #include "ConvolutionTest.h"
0012 #include "backend/core/column/Column.h"
0013 #include "backend/worksheet/plots/cartesian/XYConvolutionCurve.h"
0014 
0015 // ##############################################################################
0016 
0017 void ConvolutionTest::testLinear() {
0018     // data
0019     QVector<int> xData = {1, 2, 3, 4};
0020     QVector<double> yData = {1., 2., 3., 4.};
0021     QVector<double> y2Data = {0, 1., .5};
0022 
0023     // data source columns
0024     Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer);
0025     xDataColumn.replaceInteger(0, xData);
0026 
0027     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0028     yDataColumn.replaceValues(0, yData);
0029 
0030     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0031     y2DataColumn.replaceValues(0, y2Data);
0032 
0033     XYConvolutionCurve curve(QStringLiteral("convolution"));
0034     curve.setXDataColumn(&xDataColumn);
0035     curve.setYDataColumn(&yDataColumn);
0036     curve.setY2DataColumn(&y2DataColumn);
0037 
0038     // prepare the convolution
0039     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0040     curve.setConvolutionData(convolutionData);
0041 
0042     // perform the convolution
0043     curve.recalculate();
0044     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0045 
0046     // check the results
0047     QCOMPARE(result.available, true);
0048     QCOMPARE(result.valid, true);
0049 
0050     const AbstractColumn* resultXDataColumn = curve.xColumn();
0051     const AbstractColumn* resultYDataColumn = curve.yColumn();
0052 
0053     const int np = resultXDataColumn->rowCount();
0054     QCOMPARE(np, 6);
0055 
0056     for (int i = 0; i < np; i++)
0057         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0058 
0059     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0060     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0061     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
0062     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0063     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0064     QCOMPARE(resultYDataColumn->valueAt(4), 5.5);
0065     QCOMPARE(resultYDataColumn->valueAt(5), 2.);
0066 }
0067 
0068 void ConvolutionTest::testLinear2() {
0069     // data
0070     QVector<int> xData = {1, 2, 3};
0071     QVector<double> yData = {1., 2., 3.};
0072     QVector<double> y2Data = {0, 1., .5};
0073 
0074     // data source columns
0075     Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer);
0076     xDataColumn.replaceInteger(0, xData);
0077 
0078     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0079     yDataColumn.replaceValues(0, yData);
0080 
0081     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0082     y2DataColumn.replaceValues(0, y2Data);
0083 
0084     XYConvolutionCurve curve(QStringLiteral("convolution"));
0085     curve.setXDataColumn(&xDataColumn);
0086     curve.setYDataColumn(&yDataColumn);
0087     curve.setY2DataColumn(&y2DataColumn);
0088 
0089     // prepare the convolution
0090     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0091     curve.setConvolutionData(convolutionData);
0092 
0093     // perform the convolution
0094     curve.recalculate();
0095     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0096 
0097     // check the results
0098     QCOMPARE(result.available, true);
0099     QCOMPARE(result.valid, true);
0100 
0101     const AbstractColumn* resultXDataColumn = curve.xColumn();
0102     const AbstractColumn* resultYDataColumn = curve.yColumn();
0103 
0104     const int np = resultXDataColumn->rowCount();
0105     QCOMPARE(np, 5);
0106 
0107     for (int i = 0; i < np; i++)
0108         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0109 
0110     QCOMPARE(resultYDataColumn->valueAt(0), 0.);
0111     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
0112     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0113     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0114     QCOMPARE(resultYDataColumn->valueAt(4), 1.5);
0115 }
0116 
0117 void ConvolutionTest::testLinear_noX() {
0118     // data
0119     QVector<double> yData = {1., 2., 3., 4.};
0120     QVector<double> y2Data = {0, 1., .5};
0121 
0122     // data source columns
0123     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0124     yDataColumn.replaceValues(0, yData);
0125 
0126     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0127     y2DataColumn.replaceValues(0, y2Data);
0128 
0129     XYConvolutionCurve curve(QStringLiteral("convolution"));
0130     curve.setYDataColumn(&yDataColumn);
0131     curve.setY2DataColumn(&y2DataColumn);
0132 
0133     // prepare the convolution
0134     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0135     curve.setConvolutionData(convolutionData);
0136 
0137     // perform the convolution
0138     curve.recalculate();
0139     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0140 
0141     // check the results
0142     QCOMPARE(result.available, true);
0143     QCOMPARE(result.valid, true);
0144 
0145     const AbstractColumn* resultXDataColumn = curve.xColumn();
0146     const AbstractColumn* resultYDataColumn = curve.yColumn();
0147 
0148     const int np = resultXDataColumn->rowCount();
0149     QCOMPARE(np, 6);
0150 
0151     for (int i = 0; i < np; i++)
0152         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0153 
0154     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0155     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0156     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
0157     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0158     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0159     QCOMPARE(resultYDataColumn->valueAt(4), 5.5);
0160     QCOMPARE(resultYDataColumn->valueAt(5), 2.);
0161 }
0162 
0163 void ConvolutionTest::testLinear_swapped() {
0164     // data
0165     QVector<int> xData = {1, 2, 3, 4};
0166     QVector<double> yData = {0, 1., .5};
0167     QVector<double> y2Data = {1., 2., 3., 4.};
0168 
0169     // data source columns
0170     Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer);
0171     xDataColumn.replaceInteger(0, xData);
0172 
0173     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0174     yDataColumn.replaceValues(0, yData);
0175 
0176     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0177     y2DataColumn.replaceValues(0, y2Data);
0178 
0179     XYConvolutionCurve curve(QStringLiteral("convolution"));
0180     curve.setXDataColumn(&xDataColumn);
0181     curve.setYDataColumn(&yDataColumn);
0182     curve.setY2DataColumn(&y2DataColumn);
0183 
0184     // prepare the convolution
0185     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0186     curve.setConvolutionData(convolutionData);
0187 
0188     // perform the convolution
0189     curve.recalculate();
0190     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0191 
0192     // check the results
0193     QCOMPARE(result.available, true);
0194     QCOMPARE(result.valid, true);
0195 
0196     const AbstractColumn* resultXDataColumn = curve.xColumn();
0197     const AbstractColumn* resultYDataColumn = curve.yColumn();
0198 
0199     const int np = resultXDataColumn->rowCount();
0200     QCOMPARE(np, 6);
0201 
0202     for (int i = 0; i < np; i++)
0203         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0204 
0205     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0206     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0207     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
0208     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0209     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0210     QCOMPARE(resultYDataColumn->valueAt(4), 5.5);
0211     QCOMPARE(resultYDataColumn->valueAt(5), 2.);
0212 }
0213 
0214 void ConvolutionTest::testLinear_swapped_noX() {
0215     // data
0216     QVector<double> yData = {0, 1., .5};
0217     QVector<double> y2Data = {1., 2., 3., 4.};
0218 
0219     // data source columns
0220     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0221     yDataColumn.replaceValues(0, yData);
0222 
0223     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0224     y2DataColumn.replaceValues(0, y2Data);
0225 
0226     XYConvolutionCurve curve(QStringLiteral("convolution"));
0227     curve.setYDataColumn(&yDataColumn);
0228     curve.setY2DataColumn(&y2DataColumn);
0229 
0230     // prepare the convolution
0231     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0232     curve.setConvolutionData(convolutionData);
0233 
0234     // perform the convolution
0235     curve.recalculate();
0236     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0237 
0238     // check the results
0239     QCOMPARE(result.available, true);
0240     QCOMPARE(result.valid, true);
0241 
0242     const AbstractColumn* resultXDataColumn = curve.xColumn();
0243     const AbstractColumn* resultYDataColumn = curve.yColumn();
0244 
0245     const int np = resultXDataColumn->rowCount();
0246     QCOMPARE(np, 6);
0247 
0248     for (int i = 0; i < np; i++)
0249         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0250 
0251     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0252     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0253     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
0254     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0255     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0256     QCOMPARE(resultYDataColumn->valueAt(4), 5.5);
0257     QCOMPARE(resultYDataColumn->valueAt(5), 2.);
0258 }
0259 
0260 void ConvolutionTest::testLinear_norm() {
0261     // data
0262     QVector<double> yData = {1., 2., 3., 4.};
0263     QVector<double> y2Data = {0, 1., .5};
0264 
0265     // data source columns
0266     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0267     yDataColumn.replaceValues(0, yData);
0268 
0269     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0270     y2DataColumn.replaceValues(0, y2Data);
0271 
0272     XYConvolutionCurve curve(QStringLiteral("convolution"));
0273     curve.setYDataColumn(&yDataColumn);
0274     curve.setY2DataColumn(&y2DataColumn);
0275 
0276     // prepare the convolution
0277     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0278     convolutionData.normalize = nsl_conv_norm_euclidean;
0279     curve.setConvolutionData(convolutionData);
0280 
0281     // perform the convolution
0282     curve.recalculate();
0283     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0284 
0285     // check the results
0286     QCOMPARE(result.available, true);
0287     QCOMPARE(result.valid, true);
0288 
0289     const AbstractColumn* resultXDataColumn = curve.xColumn();
0290     const AbstractColumn* resultYDataColumn = curve.yColumn();
0291 
0292     const int np = resultXDataColumn->rowCount();
0293     QCOMPARE(np, 6);
0294 
0295     for (int i = 0; i < np; i++)
0296         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0297 
0298     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0299     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0300     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0301     QCOMPARE(resultYDataColumn->valueAt(1), 0.894427190999916);
0302     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0303     QCOMPARE(resultYDataColumn->valueAt(2), 2.23606797749979);
0304     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0305     QCOMPARE(resultYDataColumn->valueAt(3), 3.57770876399966);
0306     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0307     QCOMPARE(resultYDataColumn->valueAt(4), 4.91934955049954);
0308     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0309     QCOMPARE(resultYDataColumn->valueAt(5), 1.78885438199983);
0310 }
0311 
0312 void ConvolutionTest::testLinear_swapped_norm() {
0313     // data
0314     QVector<double> yData = {0, 1., .5};
0315     QVector<double> y2Data = {1., 2., 3., 4.};
0316 
0317     // data source columns
0318     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0319     yDataColumn.replaceValues(0, yData);
0320 
0321     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0322     y2DataColumn.replaceValues(0, y2Data);
0323 
0324     XYConvolutionCurve curve(QStringLiteral("convolution"));
0325     curve.setYDataColumn(&yDataColumn);
0326     curve.setY2DataColumn(&y2DataColumn);
0327 
0328     // prepare the convolution
0329     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0330     convolutionData.normalize = nsl_conv_norm_euclidean;
0331     curve.setConvolutionData(convolutionData);
0332 
0333     // perform the convolution
0334     curve.recalculate();
0335     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0336 
0337     // check the results
0338     QCOMPARE(result.available, true);
0339     QCOMPARE(result.valid, true);
0340 
0341     const AbstractColumn* resultXDataColumn = curve.xColumn();
0342     const AbstractColumn* resultYDataColumn = curve.yColumn();
0343 
0344     const int np = resultXDataColumn->rowCount();
0345     QCOMPARE(np, 6);
0346 
0347     for (int i = 0; i < np; i++)
0348         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0349 
0350     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0351     QCOMPARE(resultYDataColumn->valueAt(0), 0.);
0352     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0353     QCOMPARE(resultYDataColumn->valueAt(1), 0.182574185835055);
0354     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0355     QCOMPARE(resultYDataColumn->valueAt(2), 0.456435464587638);
0356     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0357     QCOMPARE(resultYDataColumn->valueAt(3), 0.730296743340221);
0358     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0359     QCOMPARE(resultYDataColumn->valueAt(4), 1.0041580220928);
0360     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0361     QCOMPARE(resultYDataColumn->valueAt(5), 0.365148371670111);
0362 }
0363 
0364 void ConvolutionTest::testLinear_wrapMax() {
0365     // data
0366     QVector<double> yData = {1., 2., 3., 4.};
0367     QVector<double> y2Data = {0, 1., .5};
0368 
0369     // data source columns
0370     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0371     yDataColumn.replaceValues(0, yData);
0372 
0373     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0374     y2DataColumn.replaceValues(0, y2Data);
0375 
0376     XYConvolutionCurve curve(QStringLiteral("convolution"));
0377     curve.setYDataColumn(&yDataColumn);
0378     curve.setY2DataColumn(&y2DataColumn);
0379 
0380     // prepare the convolution
0381     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0382     convolutionData.wrap = nsl_conv_wrap_max;
0383     curve.setConvolutionData(convolutionData);
0384 
0385     // perform the convolution
0386     curve.recalculate();
0387     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0388 
0389     // check the results
0390     QCOMPARE(result.available, true);
0391     QCOMPARE(result.valid, true);
0392 
0393     const AbstractColumn* resultXDataColumn = curve.xColumn();
0394     const AbstractColumn* resultYDataColumn = curve.yColumn();
0395 
0396     const int np = resultXDataColumn->rowCount();
0397     QCOMPARE(np, 6);
0398 
0399     for (int i = 0; i < np; i++)
0400         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0401 
0402     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0403     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
0404     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0405     QCOMPARE(resultYDataColumn->valueAt(1), 2.5);
0406     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0407     QCOMPARE(resultYDataColumn->valueAt(2), 4.);
0408     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0409     QCOMPARE(resultYDataColumn->valueAt(3), 5.5);
0410     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0411     QCOMPARE(resultYDataColumn->valueAt(4), 2.);
0412     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0413     FuzzyCompare(resultYDataColumn->valueAt(5), 0., 1.e-15);
0414 }
0415 
0416 void ConvolutionTest::testLinear_swapped_wrapMax() {
0417     // data
0418     QVector<double> yData = {0, 1., .5};
0419     QVector<double> y2Data = {1., 2., 3., 4.};
0420 
0421     // data source columns
0422     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0423     yDataColumn.replaceValues(0, yData);
0424 
0425     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0426     y2DataColumn.replaceValues(0, y2Data);
0427 
0428     XYConvolutionCurve curve(QStringLiteral("convolution"));
0429     curve.setYDataColumn(&yDataColumn);
0430     curve.setY2DataColumn(&y2DataColumn);
0431 
0432     // prepare the convolution
0433     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0434     convolutionData.wrap = nsl_conv_wrap_max;
0435     curve.setConvolutionData(convolutionData);
0436 
0437     // perform the convolution
0438     curve.recalculate();
0439     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0440 
0441     // check the results
0442     QCOMPARE(result.available, true);
0443     QCOMPARE(result.valid, true);
0444 
0445     const AbstractColumn* resultXDataColumn = curve.xColumn();
0446     const AbstractColumn* resultYDataColumn = curve.yColumn();
0447 
0448     const int np = resultXDataColumn->rowCount();
0449     QCOMPARE(np, 6);
0450 
0451     for (int i = 0; i < np; i++)
0452         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0453 
0454     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0455     QCOMPARE(resultYDataColumn->valueAt(0), 4.);
0456     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0457     QCOMPARE(resultYDataColumn->valueAt(1), 5.5);
0458     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0459     QCOMPARE(resultYDataColumn->valueAt(2), 2.);
0460     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0461     FuzzyCompare(resultYDataColumn->valueAt(3), 0., 1.e-15);
0462     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0463     QCOMPARE(resultYDataColumn->valueAt(4), 1.);
0464     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0465     QCOMPARE(resultYDataColumn->valueAt(5), 2.5);
0466 }
0467 
0468 void ConvolutionTest::testLinear_wrapCenter() {
0469     // data
0470     QVector<double> yData = {1., 2., 3., 4.};
0471     QVector<double> y2Data = {0, 1., .5};
0472 
0473     // data source columns
0474     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0475     yDataColumn.replaceValues(0, yData);
0476 
0477     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0478     y2DataColumn.replaceValues(0, y2Data);
0479 
0480     XYConvolutionCurve curve(QStringLiteral("convolution"));
0481     curve.setYDataColumn(&yDataColumn);
0482     curve.setY2DataColumn(&y2DataColumn);
0483 
0484     // prepare the convolution
0485     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0486     convolutionData.wrap = nsl_conv_wrap_center;
0487     curve.setConvolutionData(convolutionData);
0488 
0489     // perform the convolution
0490     curve.recalculate();
0491     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0492 
0493     // check the results
0494     QCOMPARE(result.available, true);
0495     QCOMPARE(result.valid, true);
0496 
0497     const AbstractColumn* resultXDataColumn = curve.xColumn();
0498     const AbstractColumn* resultYDataColumn = curve.yColumn();
0499 
0500     const int np = resultXDataColumn->rowCount();
0501     QCOMPARE(np, 6);
0502 
0503     for (int i = 0; i < np; i++)
0504         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0505 
0506     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0507     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
0508     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0509     QCOMPARE(resultYDataColumn->valueAt(1), 2.5);
0510     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0511     QCOMPARE(resultYDataColumn->valueAt(2), 4.);
0512     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0513     QCOMPARE(resultYDataColumn->valueAt(3), 5.5);
0514     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0515     QCOMPARE(resultYDataColumn->valueAt(4), 2.);
0516     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0517     FuzzyCompare(resultYDataColumn->valueAt(5), 0., 1.e-15);
0518 }
0519 
0520 void ConvolutionTest::testLinear_swapped_wrapCenter() {
0521     // data
0522     QVector<double> yData = {0, 1., .5};
0523     QVector<double> y2Data = {1., 2., 3., 4.};
0524 
0525     // data source columns
0526     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0527     yDataColumn.replaceValues(0, yData);
0528 
0529     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0530     y2DataColumn.replaceValues(0, y2Data);
0531 
0532     XYConvolutionCurve curve(QStringLiteral("convolution"));
0533     curve.setYDataColumn(&yDataColumn);
0534     curve.setY2DataColumn(&y2DataColumn);
0535 
0536     // prepare the convolution
0537     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0538     convolutionData.wrap = nsl_conv_wrap_max;
0539     curve.setConvolutionData(convolutionData);
0540 
0541     // perform the convolution
0542     curve.recalculate();
0543     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0544 
0545     // check the results
0546     QCOMPARE(result.available, true);
0547     QCOMPARE(result.valid, true);
0548 
0549     const AbstractColumn* resultXDataColumn = curve.xColumn();
0550     const AbstractColumn* resultYDataColumn = curve.yColumn();
0551 
0552     const int np = resultXDataColumn->rowCount();
0553     QCOMPARE(np, 6);
0554 
0555     for (int i = 0; i < np; i++)
0556         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0557 
0558     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0559     QCOMPARE(resultYDataColumn->valueAt(0), 4.);
0560     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0561     QCOMPARE(resultYDataColumn->valueAt(1), 5.5);
0562     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0563     QCOMPARE(resultYDataColumn->valueAt(2), 2.);
0564     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0565     FuzzyCompare(resultYDataColumn->valueAt(3), 0., 1.e-15);
0566     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0567     QCOMPARE(resultYDataColumn->valueAt(4), 1.);
0568     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0569     QCOMPARE(resultYDataColumn->valueAt(5), 2.5);
0570 }
0571 
0572 ////////////////// circular tests ////////////////////////////////////////////////////////////////
0573 
0574 void ConvolutionTest::testCircular() {
0575     // data
0576     QVector<int> xData = {1, 2, 3, 4};
0577     QVector<double> yData = {1., 2., 3., 4.};
0578     QVector<double> y2Data = {0, 1., .5};
0579 
0580     // data source columns
0581     Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer);
0582     xDataColumn.replaceInteger(0, xData);
0583 
0584     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0585     yDataColumn.replaceValues(0, yData);
0586 
0587     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0588     y2DataColumn.replaceValues(0, y2Data);
0589 
0590     XYConvolutionCurve curve(QStringLiteral("convolution"));
0591     curve.setXDataColumn(&xDataColumn);
0592     curve.setYDataColumn(&yDataColumn);
0593     curve.setY2DataColumn(&y2DataColumn);
0594 
0595     // prepare the convolution
0596     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0597     convolutionData.type = nsl_conv_type_circular;
0598     curve.setConvolutionData(convolutionData);
0599 
0600     // perform the convolution
0601     curve.recalculate();
0602     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0603 
0604     // check the results
0605     QCOMPARE(result.available, true);
0606     QCOMPARE(result.valid, true);
0607 
0608     const AbstractColumn* resultXDataColumn = curve.xColumn();
0609     const AbstractColumn* resultYDataColumn = curve.yColumn();
0610 
0611     const int np = resultXDataColumn->rowCount();
0612     QCOMPARE(np, 4);
0613 
0614     for (int i = 0; i < np; i++)
0615         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0616 
0617     QCOMPARE(resultYDataColumn->valueAt(0), 5.5);
0618     QCOMPARE(resultYDataColumn->valueAt(1), 3.);
0619     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0620     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0621 }
0622 
0623 void ConvolutionTest::testCircular2() {
0624     // data
0625     QVector<int> xData = {1, 2, 3};
0626     QVector<double> yData = {1., 2., 3.};
0627     QVector<double> y2Data = {0, 1., .5};
0628 
0629     // data source columns
0630     Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer);
0631     xDataColumn.replaceInteger(0, xData);
0632 
0633     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0634     yDataColumn.replaceValues(0, yData);
0635 
0636     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0637     y2DataColumn.replaceValues(0, y2Data);
0638 
0639     XYConvolutionCurve curve(QStringLiteral("convolution"));
0640     curve.setXDataColumn(&xDataColumn);
0641     curve.setYDataColumn(&yDataColumn);
0642     curve.setY2DataColumn(&y2DataColumn);
0643 
0644     // prepare the convolution
0645     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0646     convolutionData.type = nsl_conv_type_circular;
0647     curve.setConvolutionData(convolutionData);
0648 
0649     // perform the convolution
0650     curve.recalculate();
0651     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0652 
0653     // check the results
0654     QCOMPARE(result.available, true);
0655     QCOMPARE(result.valid, true);
0656 
0657     const AbstractColumn* resultXDataColumn = curve.xColumn();
0658     const AbstractColumn* resultYDataColumn = curve.yColumn();
0659 
0660     const int np = resultXDataColumn->rowCount();
0661     QCOMPARE(np, 3);
0662 
0663     for (int i = 0; i < np; i++)
0664         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0665 
0666     QCOMPARE(resultYDataColumn->valueAt(0), 4.);
0667     QCOMPARE(resultYDataColumn->valueAt(1), 2.5);
0668     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0669 }
0670 
0671 void ConvolutionTest::testCircular_noX() {
0672     // data
0673     QVector<double> yData = {1., 2., 3., 4.};
0674     QVector<double> y2Data = {0, 1., .5};
0675 
0676     // data source columns
0677     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0678     yDataColumn.replaceValues(0, yData);
0679 
0680     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0681     y2DataColumn.replaceValues(0, y2Data);
0682 
0683     XYConvolutionCurve curve(QStringLiteral("convolution"));
0684     curve.setYDataColumn(&yDataColumn);
0685     curve.setY2DataColumn(&y2DataColumn);
0686 
0687     // prepare the convolution
0688     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0689     convolutionData.type = nsl_conv_type_circular;
0690     curve.setConvolutionData(convolutionData);
0691 
0692     // perform the convolution
0693     curve.recalculate();
0694     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0695 
0696     // check the results
0697     QCOMPARE(result.available, true);
0698     QCOMPARE(result.valid, true);
0699 
0700     const AbstractColumn* resultXDataColumn = curve.xColumn();
0701     const AbstractColumn* resultYDataColumn = curve.yColumn();
0702 
0703     const int np = resultXDataColumn->rowCount();
0704     QCOMPARE(np, 4);
0705 
0706     for (int i = 0; i < np; i++)
0707         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0708 
0709     QCOMPARE(resultYDataColumn->valueAt(0), 5.5);
0710     QCOMPARE(resultYDataColumn->valueAt(1), 3.);
0711     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0712     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0713 }
0714 
0715 void ConvolutionTest::testCircular_swapped() {
0716     // data
0717     QVector<int> xData = {1, 2, 3, 4};
0718     QVector<double> yData = {0, 1., .5};
0719     QVector<double> y2Data = {1., 2., 3., 4.};
0720 
0721     // data source columns
0722     Column xDataColumn(QStringLiteral("x"), AbstractColumn::ColumnMode::Integer);
0723     xDataColumn.replaceInteger(0, xData);
0724 
0725     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0726     yDataColumn.replaceValues(0, yData);
0727 
0728     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0729     y2DataColumn.replaceValues(0, y2Data);
0730 
0731     XYConvolutionCurve curve(QStringLiteral("convolution"));
0732     curve.setXDataColumn(&xDataColumn);
0733     curve.setYDataColumn(&yDataColumn);
0734     curve.setY2DataColumn(&y2DataColumn);
0735 
0736     // prepare the convolution
0737     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0738     convolutionData.type = nsl_conv_type_circular;
0739     curve.setConvolutionData(convolutionData);
0740 
0741     // perform the convolution
0742     curve.recalculate();
0743     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0744 
0745     // check the results
0746     QCOMPARE(result.available, true);
0747     QCOMPARE(result.valid, true);
0748 
0749     const AbstractColumn* resultXDataColumn = curve.xColumn();
0750     const AbstractColumn* resultYDataColumn = curve.yColumn();
0751 
0752     const int np = resultXDataColumn->rowCount();
0753     QCOMPARE(np, 4);
0754 
0755     for (int i = 0; i < np; i++)
0756         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0757 
0758     QCOMPARE(resultYDataColumn->valueAt(0), 5.5);
0759     QCOMPARE(resultYDataColumn->valueAt(1), 3.);
0760     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0761     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0762 }
0763 
0764 void ConvolutionTest::testCircular_swapped_noX() {
0765     // data
0766     QVector<double> yData = {0, 1., .5};
0767     QVector<double> y2Data = {1., 2., 3., 4.};
0768 
0769     // data source columns
0770     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0771     yDataColumn.replaceValues(0, yData);
0772 
0773     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0774     y2DataColumn.replaceValues(0, y2Data);
0775 
0776     XYConvolutionCurve curve(QStringLiteral("convolution"));
0777     curve.setYDataColumn(&yDataColumn);
0778     curve.setY2DataColumn(&y2DataColumn);
0779 
0780     // prepare the convolution
0781     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0782     convolutionData.type = nsl_conv_type_circular;
0783     curve.setConvolutionData(convolutionData);
0784 
0785     // perform the convolution
0786     curve.recalculate();
0787     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0788 
0789     // check the results
0790     QCOMPARE(result.available, true);
0791     QCOMPARE(result.valid, true);
0792 
0793     const AbstractColumn* resultXDataColumn = curve.xColumn();
0794     const AbstractColumn* resultYDataColumn = curve.yColumn();
0795 
0796     const int np = resultXDataColumn->rowCount();
0797     QCOMPARE(np, 4);
0798 
0799     for (int i = 0; i < np; i++)
0800         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0801 
0802     QCOMPARE(resultYDataColumn->valueAt(0), 5.5);
0803     QCOMPARE(resultYDataColumn->valueAt(1), 3.);
0804     QCOMPARE(resultYDataColumn->valueAt(2), 2.5);
0805     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
0806 }
0807 
0808 void ConvolutionTest::testCircular_norm() {
0809     // data
0810     QVector<double> yData = {1., 2., 3., 4.};
0811     QVector<double> y2Data = {0, 1., .5};
0812 
0813     // data source columns
0814     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0815     yDataColumn.replaceValues(0, yData);
0816 
0817     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0818     y2DataColumn.replaceValues(0, y2Data);
0819 
0820     XYConvolutionCurve curve(QStringLiteral("convolution"));
0821     curve.setYDataColumn(&yDataColumn);
0822     curve.setY2DataColumn(&y2DataColumn);
0823 
0824     // prepare the convolution
0825     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0826     convolutionData.type = nsl_conv_type_circular;
0827     convolutionData.normalize = nsl_conv_norm_euclidean;
0828     curve.setConvolutionData(convolutionData);
0829 
0830     // perform the convolution
0831     curve.recalculate();
0832     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0833 
0834     // check the results
0835     QCOMPARE(result.available, true);
0836     QCOMPARE(result.valid, true);
0837 
0838     const AbstractColumn* resultXDataColumn = curve.xColumn();
0839     const AbstractColumn* resultYDataColumn = curve.yColumn();
0840 
0841     const int np = resultXDataColumn->rowCount();
0842     QCOMPARE(np, 4);
0843 
0844     for (int i = 0; i < np; i++)
0845         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0846 
0847     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0848     QCOMPARE(resultYDataColumn->valueAt(0), 4.91934955049954);
0849     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0850     QCOMPARE(resultYDataColumn->valueAt(1), 2.68328157299975);
0851     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0852     QCOMPARE(resultYDataColumn->valueAt(2), 2.23606797749979);
0853     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0854     QCOMPARE(resultYDataColumn->valueAt(3), 3.57770876399966);
0855 }
0856 
0857 void ConvolutionTest::testCircular_swapped_norm() {
0858     // data
0859     QVector<double> yData = {0, 1., .5};
0860     QVector<double> y2Data = {1., 2., 3., 4.};
0861 
0862     // data source columns
0863     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0864     yDataColumn.replaceValues(0, yData);
0865 
0866     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0867     y2DataColumn.replaceValues(0, y2Data);
0868 
0869     XYConvolutionCurve curve(QStringLiteral("convolution"));
0870     curve.setYDataColumn(&yDataColumn);
0871     curve.setY2DataColumn(&y2DataColumn);
0872 
0873     // prepare the convolution
0874     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0875     convolutionData.type = nsl_conv_type_circular;
0876     convolutionData.normalize = nsl_conv_norm_euclidean;
0877     curve.setConvolutionData(convolutionData);
0878 
0879     // perform the convolution
0880     curve.recalculate();
0881     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0882 
0883     // check the results
0884     QCOMPARE(result.available, true);
0885     QCOMPARE(result.valid, true);
0886 
0887     const AbstractColumn* resultXDataColumn = curve.xColumn();
0888     const AbstractColumn* resultYDataColumn = curve.yColumn();
0889 
0890     const int np = resultXDataColumn->rowCount();
0891     QCOMPARE(np, 4);
0892 
0893     for (int i = 0; i < np; i++)
0894         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0895 
0896     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0897     QCOMPARE(resultYDataColumn->valueAt(0), 1.0041580220928);
0898     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0899     QCOMPARE(resultYDataColumn->valueAt(1), 0.547722557505166);
0900     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0901     QCOMPARE(resultYDataColumn->valueAt(2), 0.456435464587638);
0902     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0903     QCOMPARE(resultYDataColumn->valueAt(3), 0.730296743340221);
0904 }
0905 
0906 void ConvolutionTest::testCircular_wrapMax() {
0907     // data
0908     QVector<double> yData = {1., 2., 3., 4.};
0909     QVector<double> y2Data = {0, 1., .5};
0910 
0911     // data source columns
0912     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0913     yDataColumn.replaceValues(0, yData);
0914 
0915     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0916     y2DataColumn.replaceValues(0, y2Data);
0917 
0918     XYConvolutionCurve curve(QStringLiteral("convolution"));
0919     curve.setYDataColumn(&yDataColumn);
0920     curve.setY2DataColumn(&y2DataColumn);
0921 
0922     // prepare the convolution
0923     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0924     convolutionData.type = nsl_conv_type_circular;
0925     convolutionData.wrap = nsl_conv_wrap_max;
0926     curve.setConvolutionData(convolutionData);
0927 
0928     // perform the convolution
0929     curve.recalculate();
0930     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0931 
0932     // check the results
0933     QCOMPARE(result.available, true);
0934     QCOMPARE(result.valid, true);
0935 
0936     const AbstractColumn* resultXDataColumn = curve.xColumn();
0937     const AbstractColumn* resultYDataColumn = curve.yColumn();
0938 
0939     const int np = resultXDataColumn->rowCount();
0940     QCOMPARE(np, 4);
0941 
0942     for (int i = 0; i < np; i++)
0943         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0944 
0945     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0946     QCOMPARE(resultYDataColumn->valueAt(0), 3.);
0947     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0948     QCOMPARE(resultYDataColumn->valueAt(1), 2.5);
0949     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0950     QCOMPARE(resultYDataColumn->valueAt(2), 4.);
0951     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0952     QCOMPARE(resultYDataColumn->valueAt(3), 5.5);
0953 }
0954 
0955 void ConvolutionTest::testCircular_swapped_wrapMax() {
0956     // data
0957     QVector<double> yData = {0, 1., .5};
0958     QVector<double> y2Data = {1., 2., 3., 4.};
0959 
0960     // data source columns
0961     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
0962     yDataColumn.replaceValues(0, yData);
0963 
0964     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
0965     y2DataColumn.replaceValues(0, y2Data);
0966 
0967     XYConvolutionCurve curve(QStringLiteral("convolution"));
0968     curve.setYDataColumn(&yDataColumn);
0969     curve.setY2DataColumn(&y2DataColumn);
0970 
0971     // prepare the convolution
0972     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
0973     convolutionData.type = nsl_conv_type_circular;
0974     convolutionData.wrap = nsl_conv_wrap_max;
0975     curve.setConvolutionData(convolutionData);
0976 
0977     // perform the convolution
0978     curve.recalculate();
0979     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
0980 
0981     // check the results
0982     QCOMPARE(result.available, true);
0983     QCOMPARE(result.valid, true);
0984 
0985     const AbstractColumn* resultXDataColumn = curve.xColumn();
0986     const AbstractColumn* resultYDataColumn = curve.yColumn();
0987 
0988     const int np = resultXDataColumn->rowCount();
0989     QCOMPARE(np, 4);
0990 
0991     for (int i = 0; i < np; i++)
0992         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0993 
0994     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0995     QCOMPARE(resultYDataColumn->valueAt(0), 4.);
0996     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0997     QCOMPARE(resultYDataColumn->valueAt(1), 5.5);
0998     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0999     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1000     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1001     QCOMPARE(resultYDataColumn->valueAt(3), 2.5);
1002 }
1003 
1004 void ConvolutionTest::testCircular_wrapCenter() {
1005     // data
1006     QVector<double> yData = {1., 2., 3., 4.};
1007     QVector<double> y2Data = {0, 1., .5};
1008 
1009     // data source columns
1010     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1011     yDataColumn.replaceValues(0, yData);
1012 
1013     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1014     y2DataColumn.replaceValues(0, y2Data);
1015 
1016     XYConvolutionCurve curve(QStringLiteral("convolution"));
1017     curve.setYDataColumn(&yDataColumn);
1018     curve.setY2DataColumn(&y2DataColumn);
1019 
1020     // prepare the convolution
1021     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1022     convolutionData.type = nsl_conv_type_circular;
1023     convolutionData.wrap = nsl_conv_wrap_center;
1024     curve.setConvolutionData(convolutionData);
1025 
1026     // perform the convolution
1027     curve.recalculate();
1028     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1029 
1030     // check the results
1031     QCOMPARE(result.available, true);
1032     QCOMPARE(result.valid, true);
1033 
1034     const AbstractColumn* resultXDataColumn = curve.xColumn();
1035     const AbstractColumn* resultYDataColumn = curve.yColumn();
1036 
1037     const int np = resultXDataColumn->rowCount();
1038     QCOMPARE(np, 4);
1039 
1040     for (int i = 0; i < np; i++)
1041         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1042 
1043     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1044     QCOMPARE(resultYDataColumn->valueAt(0), 3.);
1045     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1046     QCOMPARE(resultYDataColumn->valueAt(1), 2.5);
1047     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1048     QCOMPARE(resultYDataColumn->valueAt(2), 4.);
1049     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1050     QCOMPARE(resultYDataColumn->valueAt(3), 5.5);
1051 }
1052 
1053 void ConvolutionTest::testCircular_swapped_wrapCenter() {
1054     // data
1055     QVector<double> yData = {0, 1., .5};
1056     QVector<double> y2Data = {1., 2., 3., 4.};
1057 
1058     // data source columns
1059     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1060     yDataColumn.replaceValues(0, yData);
1061 
1062     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1063     y2DataColumn.replaceValues(0, y2Data);
1064 
1065     XYConvolutionCurve curve(QStringLiteral("convolution"));
1066     curve.setYDataColumn(&yDataColumn);
1067     curve.setY2DataColumn(&y2DataColumn);
1068 
1069     // prepare the convolution
1070     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1071     convolutionData.type = nsl_conv_type_circular;
1072     convolutionData.wrap = nsl_conv_wrap_center;
1073     curve.setConvolutionData(convolutionData);
1074 
1075     // perform the convolution
1076     curve.recalculate();
1077     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1078 
1079     // check the results
1080     QCOMPARE(result.available, true);
1081     QCOMPARE(result.valid, true);
1082 
1083     const AbstractColumn* resultXDataColumn = curve.xColumn();
1084     const AbstractColumn* resultYDataColumn = curve.yColumn();
1085 
1086     const int np = resultXDataColumn->rowCount();
1087     QCOMPARE(np, 4);
1088 
1089     for (int i = 0; i < np; i++)
1090         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1091 
1092     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1093     QCOMPARE(resultYDataColumn->valueAt(0), 2.5);
1094     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1095     QCOMPARE(resultYDataColumn->valueAt(1), 4.);
1096     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1097     QCOMPARE(resultYDataColumn->valueAt(2), 5.5);
1098     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1099     QCOMPARE(resultYDataColumn->valueAt(3), 3.);
1100 }
1101 
1102 //////////////// Deconvolution tests /////////////////////
1103 
1104 void ConvolutionTest::testLinearDeconv() {
1105     // data
1106     QVector<double> yData = {0., 1., 2.5, 4., 5.5, 2.};
1107     QVector<double> y2Data = {0, 1., .5};
1108 
1109     // data source columns
1110     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1111     yDataColumn.replaceValues(0, yData);
1112 
1113     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1114     y2DataColumn.replaceValues(0, y2Data);
1115 
1116     XYConvolutionCurve curve(QStringLiteral("convolution"));
1117     curve.setYDataColumn(&yDataColumn);
1118     curve.setY2DataColumn(&y2DataColumn);
1119 
1120     // prepare the convolution
1121     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1122     convolutionData.direction = nsl_conv_direction_backward;
1123     curve.setConvolutionData(convolutionData);
1124 
1125     // perform the convolution
1126     curve.recalculate();
1127     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1128 
1129     // check the results
1130     QCOMPARE(result.available, true);
1131     QCOMPARE(result.valid, true);
1132 
1133     const AbstractColumn* resultXDataColumn = curve.xColumn();
1134     const AbstractColumn* resultYDataColumn = curve.yColumn();
1135 
1136     const int np = resultXDataColumn->rowCount();
1137     QCOMPARE(np, 4);
1138 
1139     for (int i = 0; i < np; i++)
1140         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1141 
1142     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1143     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
1144     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1145     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
1146     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1147     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1148     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1149     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
1150 }
1151 
1152 void ConvolutionTest::testLinearDeconv2() {
1153     // data
1154     QVector<double> yData = {0., 1., 2.5, 4., 1.5};
1155     QVector<double> y2Data = {0, 1., .5};
1156 
1157     // data source columns
1158     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1159     yDataColumn.replaceValues(0, yData);
1160 
1161     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1162     y2DataColumn.replaceValues(0, y2Data);
1163 
1164     XYConvolutionCurve curve(QStringLiteral("convolution"));
1165     curve.setYDataColumn(&yDataColumn);
1166     curve.setY2DataColumn(&y2DataColumn);
1167 
1168     // prepare the convolution
1169     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1170     convolutionData.direction = nsl_conv_direction_backward;
1171     curve.setConvolutionData(convolutionData);
1172 
1173     // perform the convolution
1174     curve.recalculate();
1175     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1176 
1177     // check the results
1178     QCOMPARE(result.available, true);
1179     QCOMPARE(result.valid, true);
1180 
1181     const AbstractColumn* resultXDataColumn = curve.xColumn();
1182     const AbstractColumn* resultYDataColumn = curve.yColumn();
1183 
1184     const int np = resultXDataColumn->rowCount();
1185     QCOMPARE(np, 3);
1186 
1187     for (int i = 0; i < np; i++)
1188         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1189 
1190     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1191     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
1192     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1193     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
1194     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1195     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1196 }
1197 
1198 void ConvolutionTest::testLinearDeconv_swapped() {
1199     // data
1200     QVector<double> yData = {0., 1., 2.5, 4., 5.5, 2.};
1201     QVector<double> y2Data = {1, 2, 3, 4};
1202 
1203     // data source columns
1204     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1205     yDataColumn.replaceValues(0, yData);
1206 
1207     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1208     y2DataColumn.replaceValues(0, y2Data);
1209 
1210     XYConvolutionCurve curve(QStringLiteral("convolution"));
1211     curve.setYDataColumn(&yDataColumn);
1212     curve.setY2DataColumn(&y2DataColumn);
1213 
1214     // prepare the convolution
1215     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1216     convolutionData.direction = nsl_conv_direction_backward;
1217     curve.setConvolutionData(convolutionData);
1218 
1219     // perform the convolution
1220     curve.recalculate();
1221     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1222 
1223     // check the results
1224     QCOMPARE(result.available, true);
1225     QCOMPARE(result.valid, true);
1226 
1227     const AbstractColumn* resultXDataColumn = curve.xColumn();
1228     const AbstractColumn* resultYDataColumn = curve.yColumn();
1229 
1230     const int np = resultXDataColumn->rowCount();
1231     QCOMPARE(np, 3);
1232 
1233     for (int i = 0; i < np; i++)
1234         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1235 
1236     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1237     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
1238     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1239     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
1240     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1241     QCOMPARE(resultYDataColumn->valueAt(2), 0.5);
1242 }
1243 
1244 void ConvolutionTest::testLinearDeconv2_swapped() {
1245     // data
1246     QVector<double> yData = {0., 1., 2.5, 4., 1.5};
1247     QVector<double> y2Data = {1, 2, 3};
1248 
1249     // data source columns
1250     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1251     yDataColumn.replaceValues(0, yData);
1252 
1253     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1254     y2DataColumn.replaceValues(0, y2Data);
1255 
1256     XYConvolutionCurve curve(QStringLiteral("convolution"));
1257     curve.setYDataColumn(&yDataColumn);
1258     curve.setY2DataColumn(&y2DataColumn);
1259 
1260     // prepare the convolution
1261     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1262     convolutionData.direction = nsl_conv_direction_backward;
1263     curve.setConvolutionData(convolutionData);
1264 
1265     // perform the convolution
1266     curve.recalculate();
1267     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1268 
1269     // check the results
1270     QCOMPARE(result.available, true);
1271     QCOMPARE(result.valid, true);
1272 
1273     const AbstractColumn* resultXDataColumn = curve.xColumn();
1274     const AbstractColumn* resultYDataColumn = curve.yColumn();
1275 
1276     const int np = resultXDataColumn->rowCount();
1277     QCOMPARE(np, 3);
1278 
1279     for (int i = 0; i < np; i++)
1280         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1281 
1282     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1283     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
1284     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1285     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
1286     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1287     QCOMPARE(resultYDataColumn->valueAt(2), 0.5);
1288 }
1289 
1290 void ConvolutionTest::testLinearDeconv_norm() {
1291     // data
1292     QVector<double> yData = {0, 0.894427190999916, 2.23606797749979, 3.57770876399966, 4.91934955049954, 1.78885438199983};
1293     QVector<double> y2Data = {0, 1., .5};
1294 
1295     // data source columns
1296     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1297     yDataColumn.replaceValues(0, yData);
1298 
1299     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1300     y2DataColumn.replaceValues(0, y2Data);
1301 
1302     XYConvolutionCurve curve(QStringLiteral("convolution"));
1303     curve.setYDataColumn(&yDataColumn);
1304     curve.setY2DataColumn(&y2DataColumn);
1305 
1306     // prepare the convolution
1307     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1308     convolutionData.direction = nsl_conv_direction_backward;
1309     convolutionData.normalize = nsl_conv_norm_euclidean;
1310     curve.setConvolutionData(convolutionData);
1311 
1312     // perform the convolution
1313     curve.recalculate();
1314     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1315 
1316     // check the results
1317     QCOMPARE(result.available, true);
1318     QCOMPARE(result.valid, true);
1319 
1320     const AbstractColumn* resultXDataColumn = curve.xColumn();
1321     const AbstractColumn* resultYDataColumn = curve.yColumn();
1322 
1323     const int np = resultXDataColumn->rowCount();
1324     QCOMPARE(np, 4);
1325 
1326     for (int i = 0; i < np; i++)
1327         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1328 
1329     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1330     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
1331     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1332     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
1333     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1334     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1335     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1336     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
1337 }
1338 
1339 void ConvolutionTest::testCircularDeconv() {
1340     // data
1341     QVector<double> yData = {5.5, 3., 2.5, 4.};
1342     QVector<double> y2Data = {0, 1., .5};
1343 
1344     // data source columns
1345     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1346     yDataColumn.replaceValues(0, yData);
1347 
1348     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1349     y2DataColumn.replaceValues(0, y2Data);
1350 
1351     XYConvolutionCurve curve(QStringLiteral("convolution"));
1352     curve.setYDataColumn(&yDataColumn);
1353     curve.setY2DataColumn(&y2DataColumn);
1354 
1355     // prepare the convolution
1356     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1357     convolutionData.direction = nsl_conv_direction_backward;
1358     convolutionData.type = nsl_conv_type_circular;
1359     curve.setConvolutionData(convolutionData);
1360 
1361     // perform the convolution
1362     curve.recalculate();
1363     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1364 
1365     // check the results
1366     QCOMPARE(result.available, true);
1367     QCOMPARE(result.valid, true);
1368 
1369     const AbstractColumn* resultXDataColumn = curve.xColumn();
1370     const AbstractColumn* resultYDataColumn = curve.yColumn();
1371 
1372     const int np = resultXDataColumn->rowCount();
1373     QCOMPARE(np, 4);
1374 
1375     for (int i = 0; i < np; i++)
1376         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1377 
1378     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1379     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
1380     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1381     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
1382     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1383     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1384     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1385     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
1386 }
1387 
1388 void ConvolutionTest::testCircularDeconv2() {
1389     // data
1390     QVector<double> yData = {4., 2.5, 2.5};
1391     QVector<double> y2Data = {0, 1., .5};
1392 
1393     // data source columns
1394     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1395     yDataColumn.replaceValues(0, yData);
1396 
1397     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1398     y2DataColumn.replaceValues(0, y2Data);
1399 
1400     XYConvolutionCurve curve(QStringLiteral("convolution"));
1401     curve.setYDataColumn(&yDataColumn);
1402     curve.setY2DataColumn(&y2DataColumn);
1403 
1404     // prepare the convolution
1405     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1406     convolutionData.direction = nsl_conv_direction_backward;
1407     convolutionData.type = nsl_conv_type_circular;
1408     curve.setConvolutionData(convolutionData);
1409 
1410     // perform the convolution
1411     curve.recalculate();
1412     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1413 
1414     // check the results
1415     QCOMPARE(result.available, true);
1416     QCOMPARE(result.valid, true);
1417 
1418     const AbstractColumn* resultXDataColumn = curve.xColumn();
1419     const AbstractColumn* resultYDataColumn = curve.yColumn();
1420 
1421     const int np = resultXDataColumn->rowCount();
1422     QCOMPARE(np, 3);
1423 
1424     for (int i = 0; i < np; i++)
1425         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1426 
1427     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1428     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
1429     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1430     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
1431     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1432     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1433 }
1434 
1435 void ConvolutionTest::testCircularDeconv_norm() {
1436     // data
1437     QVector<double> yData = {4.91934955049954, 2.68328157299975, 2.23606797749979, 3.57770876399966};
1438     QVector<double> y2Data = {0, 1., .5};
1439 
1440     // data source columns
1441     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1442     yDataColumn.replaceValues(0, yData);
1443 
1444     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1445     y2DataColumn.replaceValues(0, y2Data);
1446 
1447     XYConvolutionCurve curve(QStringLiteral("convolution"));
1448     curve.setYDataColumn(&yDataColumn);
1449     curve.setY2DataColumn(&y2DataColumn);
1450 
1451     // prepare the convolution
1452     XYConvolutionCurve::ConvolutionData convolutionData = curve.convolutionData();
1453     convolutionData.direction = nsl_conv_direction_backward;
1454     convolutionData.type = nsl_conv_type_circular;
1455     convolutionData.normalize = nsl_conv_norm_euclidean;
1456     curve.setConvolutionData(convolutionData);
1457 
1458     // perform the convolution
1459     curve.recalculate();
1460     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1461 
1462     // check the results
1463     QCOMPARE(result.available, true);
1464     QCOMPARE(result.valid, true);
1465 
1466     const AbstractColumn* resultXDataColumn = curve.xColumn();
1467     const AbstractColumn* resultYDataColumn = curve.yColumn();
1468 
1469     const int np = resultXDataColumn->rowCount();
1470     QCOMPARE(np, 4);
1471 
1472     for (int i = 0; i < np; i++)
1473         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
1474 
1475     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
1476     QCOMPARE(resultYDataColumn->valueAt(0), 1.);
1477     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
1478     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
1479     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
1480     QCOMPARE(resultYDataColumn->valueAt(2), 3.);
1481     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
1482     QCOMPARE(resultYDataColumn->valueAt(3), 4.);
1483 }
1484 
1485 void ConvolutionTest::testPerformance() {
1486     // data
1487     QVector<double> yData;
1488 #ifdef HAVE_FFTW3
1489     const int N = 3e6;
1490 #else // GSL is much slower
1491     const int N = 5e4;
1492 #endif
1493     for (int i = 0; i < N; i++)
1494         yData.append(i % 100);
1495     QVector<double> y2Data = {0, 1., .5};
1496 
1497     // data source columns
1498     Column yDataColumn(QStringLiteral("y"), AbstractColumn::ColumnMode::Double);
1499     yDataColumn.replaceValues(0, yData);
1500 
1501     Column y2DataColumn(QStringLiteral("y2"), AbstractColumn::ColumnMode::Double);
1502     y2DataColumn.replaceValues(0, y2Data);
1503 
1504     XYConvolutionCurve curve(QStringLiteral("convolution"));
1505     curve.setYDataColumn(&yDataColumn);
1506     curve.setY2DataColumn(&y2DataColumn);
1507 
1508     // prepare and perform the convolution
1509     XYConvolutionCurve::ConvolutionData data = curve.convolutionData();
1510     QBENCHMARK {
1511         // triggers recalculate()
1512         curve.setConvolutionData(data);
1513     }
1514 
1515     // check the results
1516     const XYConvolutionCurve::ConvolutionResult& result = curve.convolutionResult();
1517 
1518     QCOMPARE(result.available, true);
1519     QCOMPARE(result.valid, true);
1520 
1521     const AbstractColumn* resultXDataColumn = curve.xColumn();
1522 
1523     const int np = resultXDataColumn->rowCount();
1524     QCOMPARE(np, N + 2);
1525 }
1526 
1527 QTEST_MAIN(ConvolutionTest)