File indexing completed on 2024-10-13 12:06:04

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