Warning, file /education/labplot/tests/analysis/correlation/CorrelationTest.cpp was not indexed or was modified since last indexation (in which case cross-reference links may be missing, inaccurate or erroneous).

0001 /***************************************************************************
0002     File                 : CorrelationTest.cpp
0003     Project              : LabPlot
0004     Description          : Tests for data correlation
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 "CorrelationTest.h"
0029 #include "backend/core/column/Column.h"
0030 #include "backend/worksheet/plots/cartesian/XYCorrelationCurve.h"
0031 
0032 //##############################################################################
0033 
0034 void CorrelationTest::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     XYCorrelationCurve correlationCurve("correlation");
0051     correlationCurve.setXDataColumn(&xDataColumn);
0052     correlationCurve.setYDataColumn(&yDataColumn);
0053     correlationCurve.setY2DataColumn(&y2DataColumn);
0054 
0055     //prepare the correlation
0056     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0057     correlationCurve.setCorrelationData(correlationData);
0058 
0059     //perform the correlation
0060     correlationCurve.recalculate();
0061     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0062 
0063     //check the results
0064     QCOMPARE(correlationResult.available, true);
0065     QCOMPARE(correlationResult.valid, true);
0066 
0067     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0068     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0069 
0070     const int np = resultXDataColumn->rowCount();
0071     QCOMPARE(np, 7);
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), 0.5);
0079     QCOMPARE(resultYDataColumn->valueAt(2), 2.);
0080     QCOMPARE(resultYDataColumn->valueAt(3), 3.5);
0081     QCOMPARE(resultYDataColumn->valueAt(4), 5.);
0082     QCOMPARE(resultYDataColumn->valueAt(5), 4.);
0083     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0084     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 2.e-15);
0085 }
0086 
0087 void CorrelationTest::testLinear2() {
0088     // data
0089     QVector<int> xData = {1, 2, 3};
0090     QVector<double> yData = {1.,2.,3.};
0091     QVector<double> y2Data = {0,1.,.5};
0092 
0093     //data source columns
0094     Column xDataColumn("x", AbstractColumn::ColumnMode::Integer);
0095     xDataColumn.replaceInteger(0, xData);
0096 
0097     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0098     yDataColumn.replaceValues(0, yData);
0099 
0100     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0101     y2DataColumn.replaceValues(0, y2Data);
0102 
0103     XYCorrelationCurve correlationCurve("correlation");
0104     correlationCurve.setXDataColumn(&xDataColumn);
0105     correlationCurve.setYDataColumn(&yDataColumn);
0106     correlationCurve.setY2DataColumn(&y2DataColumn);
0107 
0108     //prepare the correlation
0109     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0110     correlationCurve.setCorrelationData(correlationData);
0111 
0112     //perform the correlation
0113     correlationCurve.recalculate();
0114     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0115 
0116     //check the results
0117     QCOMPARE(correlationResult.available, true);
0118     QCOMPARE(correlationResult.valid, true);
0119 
0120     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0121     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0122 
0123     const int np = resultXDataColumn->rowCount();
0124     QCOMPARE(np, 5);
0125 
0126     for (int i = 0; i < np; i++)
0127         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0128 
0129     QCOMPARE(resultYDataColumn->valueAt(0), 0.5);
0130     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
0131     QCOMPARE(resultYDataColumn->valueAt(2), 3.5);
0132     QCOMPARE(resultYDataColumn->valueAt(3), 3.);
0133     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0134     FuzzyCompare(resultYDataColumn->valueAt(4), 0., 1.e-15);
0135 }
0136 
0137 void CorrelationTest::testLinear_noX() {
0138     // data
0139     QVector<double> yData = {1.,2.,3.,4.};
0140     QVector<double> y2Data = {0,1.,.5};
0141 
0142     //data source columns
0143     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0144     yDataColumn.replaceValues(0, yData);
0145 
0146     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0147     y2DataColumn.replaceValues(0, y2Data);
0148 
0149     XYCorrelationCurve correlationCurve("correlation");
0150     correlationCurve.setYDataColumn(&yDataColumn);
0151     correlationCurve.setY2DataColumn(&y2DataColumn);
0152 
0153     //prepare the correlation
0154     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0155     correlationCurve.setCorrelationData(correlationData);
0156 
0157     //perform the correlation
0158     correlationCurve.recalculate();
0159     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0160 
0161     //check the results
0162     QCOMPARE(correlationResult.available, true);
0163     QCOMPARE(correlationResult.valid, true);
0164 
0165     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0166     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0167 
0168     const int np = resultXDataColumn->rowCount();
0169     QCOMPARE(np, 7);
0170 
0171     for (int i = 0; i < np; i++)
0172         QCOMPARE(resultXDataColumn->valueAt(i), (double)(i-np/2));
0173 
0174     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0175     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0176     QCOMPARE(resultYDataColumn->valueAt(1), 0.5);
0177     QCOMPARE(resultYDataColumn->valueAt(2), 2.);
0178     QCOMPARE(resultYDataColumn->valueAt(3), 3.5);
0179     QCOMPARE(resultYDataColumn->valueAt(4), 5.);
0180     QCOMPARE(resultYDataColumn->valueAt(5), 4.);
0181     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0182     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 2.e-15);
0183 }
0184 
0185 void CorrelationTest::testLinear_swapped() {
0186     // data
0187     QVector<int> xData = {1,2,3,4};
0188     QVector<double> yData = {0,1.,.5};
0189     QVector<double> y2Data = {1.,2.,3.,4.};
0190 
0191     //data source columns
0192     Column xDataColumn("x", AbstractColumn::ColumnMode::Integer);
0193     xDataColumn.replaceInteger(0, xData);
0194 
0195     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0196     yDataColumn.replaceValues(0, yData);
0197 
0198     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0199     y2DataColumn.replaceValues(0, y2Data);
0200 
0201     XYCorrelationCurve correlationCurve("correlation");
0202     correlationCurve.setXDataColumn(&xDataColumn);
0203     correlationCurve.setYDataColumn(&yDataColumn);
0204     correlationCurve.setY2DataColumn(&y2DataColumn);
0205 
0206     //prepare the correlation
0207     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0208     correlationCurve.setCorrelationData(correlationData);
0209 
0210     //perform the correlation
0211     correlationCurve.recalculate();
0212     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0213 
0214     //check the results
0215     QCOMPARE(correlationResult.available, true);
0216     QCOMPARE(correlationResult.valid, true);
0217 
0218     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0219     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0220 
0221     const int np = resultXDataColumn->rowCount();
0222     QCOMPARE(np, 7);
0223 
0224     for (int i = 0; i < np; i++)
0225         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0226 
0227     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0228     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 2.e-15);
0229     QCOMPARE(resultYDataColumn->valueAt(1), 4.);
0230     QCOMPARE(resultYDataColumn->valueAt(2), 5.);
0231     QCOMPARE(resultYDataColumn->valueAt(3), 3.5);
0232     QCOMPARE(resultYDataColumn->valueAt(4), 2.);
0233     QCOMPARE(resultYDataColumn->valueAt(5), 0.5);
0234     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0235     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 1.e-15);
0236 }
0237 
0238 /* circular */
0239 
0240 void CorrelationTest::testCircular() {
0241     // data
0242     QVector<int> xData = {1,2,3,4};
0243     QVector<double> yData = {1.,2.,3.,4.};
0244     QVector<double> y2Data = {0,1.,.5};
0245 
0246     //data source columns
0247     Column xDataColumn("x", AbstractColumn::ColumnMode::Integer);
0248     xDataColumn.replaceInteger(0, xData);
0249 
0250     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0251     yDataColumn.replaceValues(0, yData);
0252 
0253     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0254     y2DataColumn.replaceValues(0, y2Data);
0255 
0256     XYCorrelationCurve correlationCurve("correlation");
0257     correlationCurve.setXDataColumn(&xDataColumn);
0258     correlationCurve.setYDataColumn(&yDataColumn);
0259     correlationCurve.setY2DataColumn(&y2DataColumn);
0260 
0261     //prepare the correlation
0262     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0263     correlationData.type = nsl_corr_type_circular;
0264     correlationCurve.setCorrelationData(correlationData);
0265 
0266     //perform the correlation
0267     correlationCurve.recalculate();
0268     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0269 
0270     //check the results
0271     QCOMPARE(correlationResult.available, true);
0272     QCOMPARE(correlationResult.valid, true);
0273 
0274     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0275     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0276 
0277     const int np = resultXDataColumn->rowCount();
0278     QCOMPARE(np, 4);
0279 
0280     for (int i = 0; i < np; i++)
0281         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0282 
0283     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0284     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0285     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0286     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0287     QCOMPARE(resultYDataColumn->valueAt(0), 2.);
0288     QCOMPARE(resultYDataColumn->valueAt(1), 4.5);
0289     QCOMPARE(resultYDataColumn->valueAt(2), 5.);
0290     QCOMPARE(resultYDataColumn->valueAt(3), 3.5);
0291 }
0292 
0293 void CorrelationTest::testCircular2() {
0294     // data
0295     QVector<int> xData = {1,2,3};
0296     QVector<double> yData = {1.,2.,3.};
0297     QVector<double> y2Data = {0,1.,.5};
0298 
0299     //data source columns
0300     Column xDataColumn("x", AbstractColumn::ColumnMode::Integer);
0301     xDataColumn.replaceInteger(0, xData);
0302 
0303     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0304     yDataColumn.replaceValues(0, yData);
0305 
0306     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0307     y2DataColumn.replaceValues(0, y2Data);
0308 
0309     XYCorrelationCurve correlationCurve("correlation");
0310     correlationCurve.setXDataColumn(&xDataColumn);
0311     correlationCurve.setYDataColumn(&yDataColumn);
0312     correlationCurve.setY2DataColumn(&y2DataColumn);
0313 
0314     //prepare the correlation
0315     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0316     correlationData.type = nsl_corr_type_circular;
0317     correlationCurve.setCorrelationData(correlationData);
0318 
0319     //perform the correlation
0320     correlationCurve.recalculate();
0321     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0322 
0323     //check the results
0324     QCOMPARE(correlationResult.available, true);
0325     QCOMPARE(correlationResult.valid, true);
0326 
0327     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0328     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0329 
0330     const int np = resultXDataColumn->rowCount();
0331     QCOMPARE(np, 3);
0332 
0333     for (int i = 0; i < np; i++)
0334         QCOMPARE(resultXDataColumn->valueAt(i), (double)i + 1);
0335 
0336     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0337     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0338     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0339     QCOMPARE(resultYDataColumn->valueAt(0), 2.);
0340     QCOMPARE(resultYDataColumn->valueAt(1), 3.5);
0341     QCOMPARE(resultYDataColumn->valueAt(2), 3.5);
0342 }
0343 
0344 /* norm tests */
0345 
0346 void CorrelationTest::testLinear_biased() {
0347     // data
0348     QVector<double> yData = {1.,2.,3.,4.};
0349     QVector<double> y2Data = {0,1.,.5};
0350 
0351     //data source columns
0352     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0353     yDataColumn.replaceValues(0, yData);
0354 
0355     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0356     y2DataColumn.replaceValues(0, y2Data);
0357 
0358     XYCorrelationCurve correlationCurve("correlation");
0359     correlationCurve.setYDataColumn(&yDataColumn);
0360     correlationCurve.setY2DataColumn(&y2DataColumn);
0361 
0362     //prepare the correlation
0363     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0364     correlationData.normalize = nsl_corr_norm_biased;
0365     correlationCurve.setCorrelationData(correlationData);
0366 
0367     //perform the correlation
0368     correlationCurve.recalculate();
0369     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0370 
0371     //check the results
0372     QCOMPARE(correlationResult.available, true);
0373     QCOMPARE(correlationResult.valid, true);
0374 
0375     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0376     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0377 
0378     const int np = resultXDataColumn->rowCount();
0379     QCOMPARE(np, 7);
0380 
0381     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0382     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0383     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0384     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0385     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0386     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0387     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0388     QCOMPARE(resultYDataColumn->valueAt(1), 0.125);
0389     QCOMPARE(resultYDataColumn->valueAt(2), .5);
0390     QCOMPARE(resultYDataColumn->valueAt(3), 3.5/4.);
0391     QCOMPARE(resultYDataColumn->valueAt(4), 1.25);
0392     QCOMPARE(resultYDataColumn->valueAt(5), 1.);
0393     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0394     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 2.e-15);
0395 }
0396 
0397 void CorrelationTest::testLinear2_biased() {
0398     // data
0399     QVector<double> yData = {1.,2.,3.};
0400     QVector<double> y2Data = {0,1.,.5};
0401 
0402     //data source columns
0403     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0404     yDataColumn.replaceValues(0, yData);
0405 
0406     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0407     y2DataColumn.replaceValues(0, y2Data);
0408 
0409     XYCorrelationCurve correlationCurve("correlation");
0410     correlationCurve.setYDataColumn(&yDataColumn);
0411     correlationCurve.setY2DataColumn(&y2DataColumn);
0412 
0413     //prepare the correlation
0414     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0415     correlationData.normalize = nsl_corr_norm_biased;
0416     correlationCurve.setCorrelationData(correlationData);
0417 
0418     //perform the correlation
0419     correlationCurve.recalculate();
0420     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0421 
0422     //check the results
0423     QCOMPARE(correlationResult.available, true);
0424     QCOMPARE(correlationResult.valid, true);
0425 
0426     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0427     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0428 
0429     const int np = resultXDataColumn->rowCount();
0430     QCOMPARE(np, 5);
0431 
0432     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0433     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0434     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0435     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0436     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0437     QCOMPARE(resultYDataColumn->valueAt(0), 1./6.);
0438     QCOMPARE(resultYDataColumn->valueAt(1), 2./3.);
0439     QCOMPARE(resultYDataColumn->valueAt(2), 7./6.);
0440     QCOMPARE(resultYDataColumn->valueAt(3), 1.);
0441     FuzzyCompare(resultYDataColumn->valueAt(4), 0., 1.e-15);
0442 }
0443 
0444 void CorrelationTest::testLinear_unbiased() {
0445     // data
0446     QVector<double> yData = {1.,2.,3.,4.};
0447     QVector<double> y2Data = {0,1.,.5};
0448 
0449     //data source columns
0450     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0451     yDataColumn.replaceValues(0, yData);
0452 
0453     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0454     y2DataColumn.replaceValues(0, y2Data);
0455 
0456     XYCorrelationCurve correlationCurve("correlation");
0457     correlationCurve.setYDataColumn(&yDataColumn);
0458     correlationCurve.setY2DataColumn(&y2DataColumn);
0459 
0460     //prepare the correlation
0461     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0462     correlationData.normalize = nsl_corr_norm_unbiased;
0463     correlationCurve.setCorrelationData(correlationData);
0464 
0465     //perform the correlation
0466     correlationCurve.recalculate();
0467     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0468 
0469     //check the results
0470     QCOMPARE(correlationResult.available, true);
0471     QCOMPARE(correlationResult.valid, true);
0472 
0473     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0474     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0475 
0476     const int np = resultXDataColumn->rowCount();
0477     QCOMPARE(np, 7);
0478 
0479     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0480     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0481     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0482     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0483     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0484     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0485     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0486     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0487     QCOMPARE(resultYDataColumn->valueAt(1), 0.25);
0488     QCOMPARE(resultYDataColumn->valueAt(2), 2./3.);
0489     QCOMPARE(resultYDataColumn->valueAt(3), 3.5/4.);
0490     QCOMPARE(resultYDataColumn->valueAt(4), 5./3.);
0491     QCOMPARE(resultYDataColumn->valueAt(5), 2.);
0492     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 2.e-15);
0493 }
0494 
0495 void CorrelationTest::testLinear2_unbiased() {
0496     // data
0497     QVector<double> yData = {1.,2.,3.};
0498     QVector<double> y2Data = {0,1.,.5};
0499 
0500     //data source columns
0501     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0502     yDataColumn.replaceValues(0, yData);
0503 
0504     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0505     y2DataColumn.replaceValues(0, y2Data);
0506 
0507     XYCorrelationCurve correlationCurve("correlation");
0508     correlationCurve.setYDataColumn(&yDataColumn);
0509     correlationCurve.setY2DataColumn(&y2DataColumn);
0510 
0511     //prepare the correlation
0512     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0513     correlationData.normalize = nsl_corr_norm_unbiased;
0514     correlationCurve.setCorrelationData(correlationData);
0515 
0516     //perform the correlation
0517     correlationCurve.recalculate();
0518     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0519 
0520     //check the results
0521     QCOMPARE(correlationResult.available, true);
0522     QCOMPARE(correlationResult.valid, true);
0523 
0524     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0525     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0526 
0527     const int np = resultXDataColumn->rowCount();
0528     QCOMPARE(np, 5);
0529 
0530     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0531     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0532     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0533     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0534     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0535     QCOMPARE(resultYDataColumn->valueAt(0), 0.5);
0536     QCOMPARE(resultYDataColumn->valueAt(1), 1.);
0537     QCOMPARE(resultYDataColumn->valueAt(2), 7./6.);
0538     QCOMPARE(resultYDataColumn->valueAt(3), 1.5);
0539     FuzzyCompare(resultYDataColumn->valueAt(4), 0., 1.e-15);
0540 }
0541 
0542 void CorrelationTest::testLinear_coeff() {
0543     // data
0544     QVector<double> yData = {1.,2.,3.,4.};
0545     QVector<double> y2Data = {0,1.,.5};
0546 
0547     //data source columns
0548     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0549     yDataColumn.replaceValues(0, yData);
0550 
0551     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0552     y2DataColumn.replaceValues(0, y2Data);
0553 
0554     XYCorrelationCurve correlationCurve("correlation");
0555     correlationCurve.setYDataColumn(&yDataColumn);
0556     correlationCurve.setY2DataColumn(&y2DataColumn);
0557 
0558     //prepare the correlation
0559     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0560     correlationData.normalize = nsl_corr_norm_coeff;
0561     correlationCurve.setCorrelationData(correlationData);
0562 
0563     //perform the correlation
0564     correlationCurve.recalculate();
0565     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0566 
0567     //check the results
0568     QCOMPARE(correlationResult.available, true);
0569     QCOMPARE(correlationResult.valid, true);
0570 
0571     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0572     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0573 
0574     const int np = resultXDataColumn->rowCount();
0575     QCOMPARE(np, 7);
0576 
0577     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0578     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0579     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0580     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0581     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0582     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(5));
0583     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0584     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0585     double norm = sqrt(30) * sqrt(1.25);
0586     QCOMPARE(resultYDataColumn->valueAt(1), 0.5/norm);
0587     QCOMPARE(resultYDataColumn->valueAt(2), 2./norm);
0588     QCOMPARE(resultYDataColumn->valueAt(3), 3.5/norm);
0589     QCOMPARE(resultYDataColumn->valueAt(4), 5./norm);
0590     QCOMPARE(resultYDataColumn->valueAt(5), 4./norm);
0591     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 2.e-15);
0592 }
0593 
0594 void CorrelationTest::testLinear2_coeff() {
0595     // data
0596     QVector<double> yData = {1.,2.,3.};
0597     QVector<double> y2Data = {0,1.,.5};
0598 
0599     //data source columns
0600     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0601     yDataColumn.replaceValues(0, yData);
0602 
0603     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0604     y2DataColumn.replaceValues(0, y2Data);
0605 
0606     XYCorrelationCurve correlationCurve("correlation");
0607     correlationCurve.setYDataColumn(&yDataColumn);
0608     correlationCurve.setY2DataColumn(&y2DataColumn);
0609 
0610     //prepare the correlation
0611     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0612     correlationData.normalize = nsl_corr_norm_coeff;
0613     correlationCurve.setCorrelationData(correlationData);
0614 
0615     //perform the correlation
0616     correlationCurve.recalculate();
0617     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0618 
0619     //check the results
0620     QCOMPARE(correlationResult.available, true);
0621     QCOMPARE(correlationResult.valid, true);
0622 
0623     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0624     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0625 
0626     const int np = resultXDataColumn->rowCount();
0627     QCOMPARE(np, 5);
0628 
0629     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0630     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0631     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0632     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0633     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0634     double norm = sqrt(14.)*sqrt(1.25);
0635     QCOMPARE(resultYDataColumn->valueAt(0), .5/norm);
0636     QCOMPARE(resultYDataColumn->valueAt(1), 2./norm);
0637     QCOMPARE(resultYDataColumn->valueAt(2), 3.5/norm);
0638     QCOMPARE(resultYDataColumn->valueAt(3), 3./norm);
0639     FuzzyCompare(resultYDataColumn->valueAt(4), 0., 1.e-15);
0640 }
0641 
0642 void CorrelationTest::testCircular_coeff() {
0643     // data
0644     QVector<double> yData = {1.,2.,3.,4.};
0645     QVector<double> y2Data = {0,1.,.5};
0646 
0647     //data source columns
0648     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0649     yDataColumn.replaceValues(0, yData);
0650 
0651     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0652     y2DataColumn.replaceValues(0, y2Data);
0653 
0654     XYCorrelationCurve correlationCurve("correlation");
0655     correlationCurve.setYDataColumn(&yDataColumn);
0656     correlationCurve.setY2DataColumn(&y2DataColumn);
0657 
0658     //prepare the correlation
0659     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0660     correlationData.type = nsl_corr_type_circular;
0661     correlationData.normalize = nsl_corr_norm_coeff;
0662     correlationCurve.setCorrelationData(correlationData);
0663 
0664     //perform the correlation
0665     correlationCurve.recalculate();
0666     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0667 
0668     //check the results
0669     QCOMPARE(correlationResult.available, true);
0670     QCOMPARE(correlationResult.valid, true);
0671 
0672     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0673     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0674 
0675     const int np = resultXDataColumn->rowCount();
0676     QCOMPARE(np, 4);
0677 
0678     for (int i = 0; i < np; i++)
0679         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0680 
0681     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0682     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0683     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0684     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(3));
0685     QCOMPARE(resultYDataColumn->valueAt(0), 0.32659863237109);
0686     QCOMPARE(resultYDataColumn->valueAt(1), 0.734846922834953);
0687     QCOMPARE(resultYDataColumn->valueAt(2), 0.816496580927726);
0688     QCOMPARE(resultYDataColumn->valueAt(3), 0.571547606649408);
0689 }
0690 
0691 void CorrelationTest::testCircular2_coeff() {
0692     // data
0693     QVector<double> yData = {1.,2.,3.};
0694     QVector<double> y2Data = {0,1.,.5};
0695 
0696     //data source columns
0697     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0698     yDataColumn.replaceValues(0, yData);
0699 
0700     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0701     y2DataColumn.replaceValues(0, y2Data);
0702 
0703     XYCorrelationCurve correlationCurve("correlation");
0704     correlationCurve.setYDataColumn(&yDataColumn);
0705     correlationCurve.setY2DataColumn(&y2DataColumn);
0706 
0707     //prepare the correlation
0708     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0709     correlationData.type = nsl_corr_type_circular;
0710     correlationData.normalize = nsl_corr_norm_coeff;
0711     correlationCurve.setCorrelationData(correlationData);
0712 
0713     //perform the correlation
0714     correlationCurve.recalculate();
0715     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0716 
0717     //check the results
0718     QCOMPARE(correlationResult.available, true);
0719     QCOMPARE(correlationResult.valid, true);
0720 
0721     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0722     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0723 
0724     const int np = resultXDataColumn->rowCount();
0725     QCOMPARE(np, 3);
0726 
0727     for (int i = 0; i < np; i++)
0728         QCOMPARE(resultXDataColumn->valueAt(i), (double)i);
0729 
0730     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0731     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(1));
0732     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(2));
0733     QCOMPARE(resultYDataColumn->valueAt(0), 0.478091443733757);
0734     QCOMPARE(resultYDataColumn->valueAt(1), 0.836660026534076);
0735     QCOMPARE(resultYDataColumn->valueAt(2), 0.836660026534076);
0736 }
0737 
0738 /* samplingInterval */
0739 
0740 void CorrelationTest::testLinear_samplingInterval() {
0741     // data
0742     QVector<double> yData = {1.,2.,3.,4.};
0743     QVector<double> y2Data = {0,1.,.5};
0744 
0745     //data source columns
0746     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0747     yDataColumn.replaceValues(0, yData);
0748 
0749     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0750     y2DataColumn.replaceValues(0, y2Data);
0751 
0752     XYCorrelationCurve correlationCurve("correlation");
0753     correlationCurve.setYDataColumn(&yDataColumn);
0754     correlationCurve.setY2DataColumn(&y2DataColumn);
0755 
0756     //prepare the correlation
0757     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0758     correlationData.samplingInterval = 0.1;
0759     correlationCurve.setCorrelationData(correlationData);
0760 
0761     //perform the correlation
0762     correlationCurve.recalculate();
0763     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0764 
0765     //check the results
0766     QCOMPARE(correlationResult.available, true);
0767     QCOMPARE(correlationResult.valid, true);
0768 
0769     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0770     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0771 
0772     const int np = resultXDataColumn->rowCount();
0773     QCOMPARE(np, 7);
0774 
0775     for (int i = 0; i < np; i++) {
0776         DEBUG(std::setprecision(15) << resultXDataColumn->valueAt(i));
0777         QCOMPARE(resultXDataColumn->valueAt(i), (double) (i-np/2) * correlationData.samplingInterval);
0778     }
0779 
0780     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(0));
0781     FuzzyCompare(resultYDataColumn->valueAt(0), 0., 1.e-15);
0782     QCOMPARE(resultYDataColumn->valueAt(1), 0.5);
0783     QCOMPARE(resultYDataColumn->valueAt(2), 2.);
0784     QCOMPARE(resultYDataColumn->valueAt(3), 3.5);
0785     QCOMPARE(resultYDataColumn->valueAt(4), 5.);
0786     QCOMPARE(resultYDataColumn->valueAt(5), 4.);
0787     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(6));
0788     FuzzyCompare(resultYDataColumn->valueAt(6), 0., 2.e-15);
0789 }
0790 
0791 void CorrelationTest::testLinear2_samplingInterval() {
0792     // data
0793     QVector<double> yData = {1.,2.,3.};
0794     QVector<double> y2Data = {0,1.,.5};
0795 
0796     //data source columns
0797     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0798     yDataColumn.replaceValues(0, yData);
0799 
0800     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0801     y2DataColumn.replaceValues(0, y2Data);
0802 
0803     XYCorrelationCurve correlationCurve("correlation");
0804     correlationCurve.setYDataColumn(&yDataColumn);
0805     correlationCurve.setY2DataColumn(&y2DataColumn);
0806 
0807     //prepare the correlation
0808     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0809     correlationData.samplingInterval = 0.1;
0810     correlationCurve.setCorrelationData(correlationData);
0811 
0812     //perform the correlation
0813     correlationCurve.recalculate();
0814     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0815 
0816     //check the results
0817     QCOMPARE(correlationResult.available, true);
0818     QCOMPARE(correlationResult.valid, true);
0819 
0820     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0821     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0822 
0823     const int np = resultXDataColumn->rowCount();
0824     QCOMPARE(np, 5);
0825 
0826     for (int i = 0; i < np; i++) {
0827         DEBUG(std::setprecision(15) << resultXDataColumn->valueAt(i));
0828         QCOMPARE(resultXDataColumn->valueAt(i), (double) (i-np/2) * correlationData.samplingInterval);
0829     }
0830 
0831     QCOMPARE(resultYDataColumn->valueAt(0), 0.5);
0832     QCOMPARE(resultYDataColumn->valueAt(1), 2.);
0833     QCOMPARE(resultYDataColumn->valueAt(2), 3.5);
0834     QCOMPARE(resultYDataColumn->valueAt(3), 3.);
0835     DEBUG(std::setprecision(15) << resultYDataColumn->valueAt(4));
0836     FuzzyCompare(resultYDataColumn->valueAt(4), 0., 1.e-15);
0837 }
0838 
0839 void CorrelationTest::testCircular_samplingInterval() {
0840     // data
0841     QVector<double> yData = {1.,2.,3.,4.};
0842     QVector<double> y2Data = {0,1.,.5};
0843 
0844     //data source columns
0845     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0846     yDataColumn.replaceValues(0, yData);
0847 
0848     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0849     y2DataColumn.replaceValues(0, y2Data);
0850 
0851     XYCorrelationCurve correlationCurve("correlation");
0852     correlationCurve.setYDataColumn(&yDataColumn);
0853     correlationCurve.setY2DataColumn(&y2DataColumn);
0854 
0855     //prepare the correlation
0856     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0857     correlationData.type = nsl_corr_type_circular;
0858     correlationData.samplingInterval = 0.1;
0859     correlationCurve.setCorrelationData(correlationData);
0860 
0861     //perform the correlation
0862     correlationCurve.recalculate();
0863     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0864 
0865     //check the results
0866     QCOMPARE(correlationResult.available, true);
0867     QCOMPARE(correlationResult.valid, true);
0868 
0869     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0870     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0871 
0872     const int np = resultXDataColumn->rowCount();
0873     QCOMPARE(np, 4);
0874 
0875     for (int i = 0; i < np; i++) {
0876         DEBUG(std::setprecision(15) << resultXDataColumn->valueAt(i));
0877         QCOMPARE(resultXDataColumn->valueAt(i), (double) i * correlationData.samplingInterval);
0878     }
0879 
0880     QCOMPARE(resultYDataColumn->valueAt(0), 2.);
0881     QCOMPARE(resultYDataColumn->valueAt(1), 4.5);
0882     QCOMPARE(resultYDataColumn->valueAt(2), 5.);
0883     QCOMPARE(resultYDataColumn->valueAt(3), 3.5);
0884 }
0885 
0886 void CorrelationTest::testCircular2_samplingInterval() {
0887     // data
0888     QVector<double> yData = {1.,2.,3.};
0889     QVector<double> y2Data = {0,1.,.5};
0890 
0891     //data source columns
0892     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0893     yDataColumn.replaceValues(0, yData);
0894 
0895     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0896     y2DataColumn.replaceValues(0, y2Data);
0897 
0898     XYCorrelationCurve correlationCurve("correlation");
0899     correlationCurve.setYDataColumn(&yDataColumn);
0900     correlationCurve.setY2DataColumn(&y2DataColumn);
0901 
0902     //prepare the correlation
0903     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0904     correlationData.type = nsl_corr_type_circular;
0905     correlationData.samplingInterval = 0.1;
0906     correlationCurve.setCorrelationData(correlationData);
0907 
0908     //perform the correlation
0909     correlationCurve.recalculate();
0910     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0911 
0912     //check the results
0913     QCOMPARE(correlationResult.available, true);
0914     QCOMPARE(correlationResult.valid, true);
0915 
0916     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0917     const AbstractColumn* resultYDataColumn = correlationCurve.yColumn();
0918 
0919     const int np = resultXDataColumn->rowCount();
0920     QCOMPARE(np, 3);
0921 
0922     for (int i = 0; i < np; i++) {
0923         DEBUG(std::setprecision(15) << resultXDataColumn->valueAt(i));
0924         QCOMPARE(resultXDataColumn->valueAt(i), (double) i * correlationData.samplingInterval);
0925     }
0926 
0927     QCOMPARE(resultYDataColumn->valueAt(0), 2.);
0928     QCOMPARE(resultYDataColumn->valueAt(1), 3.5);
0929     QCOMPARE(resultYDataColumn->valueAt(2), 3.5);
0930 }
0931 
0932 void CorrelationTest::testPerformance() {
0933     // data
0934     QVector<double> yData, y2Data;
0935 #ifdef HAVE_FFTW3
0936     const int N = 1e6;
0937 #else   // GSL is much slower
0938     const int N = 5e4;
0939 #endif
0940     for (int i = 0;  i < N; i++) {
0941         yData.append(i % 100);
0942         y2Data.append(i % 10);
0943     }
0944 
0945     //data source columns
0946     Column yDataColumn("y", AbstractColumn::ColumnMode::Numeric);
0947     yDataColumn.replaceValues(0, yData);
0948 
0949     Column y2DataColumn("y2", AbstractColumn::ColumnMode::Numeric);
0950     y2DataColumn.replaceValues(0, y2Data);
0951 
0952     XYCorrelationCurve correlationCurve("correlation");
0953     correlationCurve.setYDataColumn(&yDataColumn);
0954     correlationCurve.setY2DataColumn(&y2DataColumn);
0955 
0956     //prepare and perform the correlation
0957     XYCorrelationCurve::CorrelationData correlationData = correlationCurve.correlationData();
0958     QBENCHMARK {
0959         // triggers recalculate()
0960         correlationCurve.setCorrelationData(correlationData);
0961     }
0962 
0963     //check the results
0964     const XYCorrelationCurve::CorrelationResult& correlationResult = correlationCurve.correlationResult();
0965 
0966     QCOMPARE(correlationResult.available, true);
0967     QCOMPARE(correlationResult.valid, true);
0968 
0969     const AbstractColumn* resultXDataColumn = correlationCurve.xColumn();
0970 
0971     const int np = resultXDataColumn->rowCount();
0972     QCOMPARE(np, 2*N - 1);
0973 }
0974 
0975 QTEST_MAIN(CorrelationTest)