diff --git a/src/backend/generalTest/CorrelationCoefficient.cpp b/src/backend/generalTest/CorrelationCoefficient.cpp index fef51153e..08482fc59 100644 --- a/src/backend/generalTest/CorrelationCoefficient.cpp +++ b/src/backend/generalTest/CorrelationCoefficient.cpp @@ -1,411 +1,409 @@ /*************************************************************************** - File : CorrelationCoefficient.cpp - Project : LabPlot - Description : Finding Correlation Coefficient on data provided - -------------------------------------------------------------------- - Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) + File : CorrelationCoefficient.cpp + Project : LabPlot + Description : Finding Correlation Coefficient on data provided + -------------------------------------------------------------------- + Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "CorrelationCoefficient.h" #include "GeneralTest.h" #include "kdefrontend/generalTest/CorrelationCoefficientView.h" #include "backend/spreadsheet/Spreadsheet.h" #include "backend/core/column/Column.h" #include "backend/lib/macros.h" #include #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "backend/nsl/nsl_stats.h" } CorrelationCoefficient::CorrelationCoefficient(const QString& name) : GeneralTest(name, AspectType::CorrelationCoefficient) { } CorrelationCoefficient::~CorrelationCoefficient() { } void CorrelationCoefficient::performTest(Test test, bool categoricalVariable) { - m_statsTable = ""; - m_tooltips.clear(); - m_correlationValue = 0; - m_statisticValue.clear(); - m_pValue.clear(); - for (int i = 0; i < RESULTLINESCOUNT; i++) - m_resultLine[i]->clear(); - - switch (test) { - case CorrelationCoefficient::Test::Pearson: { - m_currTestName = "

" + i18n("Pearson's r Correlation Test") + "

"; - performPearson(categoricalVariable); - break; - } - case CorrelationCoefficient::Test::Kendall: - m_currTestName = "

" + i18n("Kendall's Rank Correlation Test") + "

"; - performKendall(); - break; - case CorrelationCoefficient::Test::Spearman: { - m_currTestName = "

" + i18n("Spearman Correlation Coefficient Test") + "

"; - performSpearman(); - break; - } - } - - emit changed(); + m_statsTable = ""; + m_tooltips.clear(); + m_correlationValue = 0; + m_statisticValue.clear(); + m_pValue.clear(); + for (int i = 0; i < RESULTLINESCOUNT; i++) + m_resultLine[i]->clear(); + + switch (test) { + case CorrelationCoefficient::Test::Pearson: { + m_currTestName = "

" + i18n("Pearson's r Correlation Test") + "

"; + performPearson(categoricalVariable); + break; + } + case CorrelationCoefficient::Test::Kendall: + m_currTestName = "

" + i18n("Kendall's Rank Correlation Test") + "

"; + performKendall(); + break; + case CorrelationCoefficient::Test::Spearman: { + m_currTestName = "

" + i18n("Spearman Correlation Coefficient Test") + "

"; + performSpearman(); + break; + } + } + + emit changed(); } -double CorrelationCoefficient::correlationValue() const{ - return m_correlationValue; +double CorrelationCoefficient::correlationValue() const { + return m_correlationValue; } -QList CorrelationCoefficient::statisticValue() const{ - return m_statisticValue; +QList CorrelationCoefficient::statisticValue() const { + return m_statisticValue; } -QList CorrelationCoefficient::pValue() const{ - return m_pValue; +QList CorrelationCoefficient::pValue() const { + return m_pValue; } /*************************************************************************************************************************** * Private Implementations * ************************************************************************************************************************/ /*********************************************Pearson r ******************************************************************/ //Formulaes are taken from https://www.statisticssolutions.com/correlation-pearson-kendall-spearman/ // variables: // N = total number of observations // sumColx = sum of values in colx // sumSqColx = sum of square of values in colx // sumColxColy = sum of product of values in colx and coly //TODO: support for col1 is categorical. //TODO: add tooltip for correlation value result //TODO: find p value void CorrelationCoefficient::performPearson(bool categoricalVariable) { - if (m_columns.count() != 2) { - printError("Select only 2 columns "); - return; - } + if (m_columns.count() != 2) { + printError("Select only 2 columns "); + return; + } - if (categoricalVariable) { - printLine(1, "currently categorical variable not supported", "blue"); - return; - } + if (categoricalVariable) { + printLine(1, "currently categorical variable not supported", "blue"); + return; + } - QString col1Name = m_columns[0]->name(); - QString col2Name = m_columns[1]->name(); + QString col1Name = m_columns[0]->name(); + QString col2Name = m_columns[1]->name(); - if (!m_columns[1]->isNumeric()) { - printError("Column " + col2Name + " should contain only numeric or interger values"); - } + if (!m_columns[1]->isNumeric()) + printError("Column " + col2Name + " should contain only numeric or interger values"); - int N = findCount(m_columns[0]); - if (N != findCount(m_columns[1])) { - printError("Number of data values in Column: " + col1Name + "and Column: " + col2Name + "are not equal"); - return; - } + int N = findCount(m_columns[0]); + if (N != findCount(m_columns[1])) { + printError("Number of data values in Column: " + col1Name + "and Column: " + col2Name + "are not equal"); + return; + } - double sumCol1 = findSum(m_columns[0], N); - double sumCol2 = findSum(m_columns[1], N); - double sumSqCol1 = findSumSq(m_columns[0], N); - double sumSqCol2 = findSumSq(m_columns[1], N); + double sumCol1 = findSum(m_columns[0], N); + double sumCol2 = findSum(m_columns[1], N); + double sumSqCol1 = findSumSq(m_columns[0], N); + double sumSqCol2 = findSumSq(m_columns[1], N); - double sumCol12 = 0; + double sumCol12 = 0; - for (int i = 0; i < N; i++) - sumCol12 += m_columns[0]->valueAt(i) * - m_columns[1]->valueAt(i); + for (int i = 0; i < N; i++) + sumCol12 += m_columns[0]->valueAt(i) * + m_columns[1]->valueAt(i); - // printing table; - // cell constructor structure; data, level, rowSpanCount, m_columnspanCount, isHeader; - QList rowMajor; - int level = 0; + // printing table; + // cell constructor structure; data, level, rowSpanCount, m_columnspanCount, isHeader; + QList rowMajor; + int level = 0; - // horizontal header - QString sigma = UTF8_QSTRING("Σ"); - rowMajor.append(new Cell("", level, true)); + // horizontal header + QString sigma = UTF8_QSTRING("Σ"); + rowMajor.append(new Cell("", level, true)); - rowMajor.append(new Cell("N", level, true, "Total Number of Observations")); - rowMajor.append(new Cell(QString(sigma + "Scores"), level, true, "Sum of Scores in each column")); - rowMajor.append(new Cell(QString(sigma + "Scores2"), level, true, "Sum of Squares of scores in each column")); - rowMajor.append(new Cell(QString(sigma + "(" + UTF8_QSTRING("∏") + "Scores)"), level, true, "Sum of product of scores of both columns")); + rowMajor.append(new Cell("N", level, true, "Total Number of Observations")); + rowMajor.append(new Cell(QString(sigma + "Scores"), level, true, "Sum of Scores in each column")); + rowMajor.append(new Cell(QString(sigma + "Scores2"), level, true, "Sum of Squares of scores in each column")); + rowMajor.append(new Cell(QString(sigma + "(" + UTF8_QSTRING("∏") + "Scores)"), level, true, "Sum of product of scores of both columns")); - //data with vertical header. - level++; - rowMajor.append(new Cell(col1Name, level, true)); - rowMajor.append(new Cell(N, level)); - rowMajor.append(new Cell(sumCol1, level)); - rowMajor.append(new Cell(sumSqCol1, level)); + //data with vertical header. + level++; + rowMajor.append(new Cell(col1Name, level, true)); + rowMajor.append(new Cell(N, level)); + rowMajor.append(new Cell(sumCol1, level)); + rowMajor.append(new Cell(sumSqCol1, level)); - rowMajor.append(new Cell(sumCol12, level, false, "", 2, 1)); + rowMajor.append(new Cell(sumCol12, level, false, "", 2, 1)); - level++; - rowMajor.append(new Cell(col2Name, level, true)); - rowMajor.append(new Cell(N, level)); - rowMajor.append(new Cell(sumCol2, level)); - rowMajor.append(new Cell(sumSqCol2, level)); + level++; + rowMajor.append(new Cell(col2Name, level, true)); + rowMajor.append(new Cell(N, level)); + rowMajor.append(new Cell(sumCol2, level)); + rowMajor.append(new Cell(sumSqCol2, level)); - m_statsTable += getHtmlTable3(rowMajor); + m_statsTable += getHtmlTable3(rowMajor); - m_correlationValue = (N * sumCol12 - sumCol1*sumCol2) / - sqrt((N * sumSqCol1 - gsl_pow_2(sumCol1)) * - (N * sumSqCol2 - gsl_pow_2(sumCol2))); + m_correlationValue = (N * sumCol12 - sumCol1*sumCol2) / + sqrt((N * sumSqCol1 - gsl_pow_2(sumCol1)) * + (N * sumSqCol2 - gsl_pow_2(sumCol2))); - printLine(0, QString("Correlation Value is %1").arg(round(m_correlationValue)), "green"); + printLine(0, QString("Correlation Value is %1").arg(round(m_correlationValue)), "green"); } /***********************************************Kendall ******************************************************************/ // used knight algorithm for fast performance O(nlogn) rather than O(n^2) // http://adereth.github.io/blog/2013/10/30/efficiently-computing-kendalls-tau/ // TODO: Change date format type to original for numeric type; // TODO: add tooltips. // TODO: Compute tauB for ties. // TODO: find P Value from Z Value void CorrelationCoefficient::performKendall() { - if (m_columns.count() != 2) { - printError("Select only 2 columns "); - return; - } - - QString col1Name = m_columns[0]->name(); - QString col2Name = m_columns[1]->name(); - - int N = findCount(m_columns[0]); - if (N != findCount(m_columns[1])) { - printError("Number of data values in Column: " + col1Name + "and Column: " + col2Name + "are not equal"); - return; - } - - QVector col2Ranks(N); - if (m_columns[0]->isNumeric()) { - if (m_columns[0]->isNumeric() && m_columns[1]->isNumeric()) { - for (int i = 0; i < N; i++) - col2Ranks[int(m_columns[0]->valueAt(i)) - 1] = int(m_columns[1]->valueAt(i)); - } else { - printError(QString("Ranking System should be same for both Column: %1 and Column: %2
" - "Hint: Check for data types of columns").arg(col1Name).arg(col2Name)); - return; - } - } else { - AbstractColumn::ColumnMode origCol1Mode = m_columns[0]->columnMode(); - AbstractColumn::ColumnMode origCol2Mode = m_columns[1]->columnMode(); - - m_columns[0]->setColumnMode(AbstractColumn::Text); - m_columns[1]->setColumnMode(AbstractColumn::Text); - - QMap ValueToRank; - - for (int i = 0; i < N; i++) { - if (ValueToRank[m_columns[0]->textAt(i)] != 0) { - printError("Currently ties are not supported"); - m_columns[0]->setColumnMode(origCol1Mode); - m_columns[1]->setColumnMode(origCol2Mode); - return; - } - ValueToRank[m_columns[0]->textAt(i)] = i + 1; - } - - for (int i = 0; i < N; i++) - col2Ranks[i] = ValueToRank[m_columns[1]->textAt(i)]; - - m_columns[0]->setColumnMode(origCol1Mode); - m_columns[1]->setColumnMode(origCol2Mode); - } - - int nPossiblePairs = (N * (N - 1)) / 2; - - int nDiscordant = findDiscordants(col2Ranks.data(), 0, N - 1); - int nCorcordant = nPossiblePairs - nDiscordant; - - m_correlationValue = double(nCorcordant - nDiscordant) / nPossiblePairs; - - m_statisticValue.append((3 * (nCorcordant - nDiscordant)) / - sqrt(N * (N- 1) * (2 * N + 5) / 2)); - - printLine(0 , QString("Number of Discordants are %1").arg(nDiscordant), "green"); - printLine(1 , QString("Number of Concordant are %1").arg(nCorcordant), "green"); - - printLine(2 , QString("Tau a is %1").arg(round(m_correlationValue)), "green"); - printLine(3 , QString("Z Value is %1").arg(round(m_statisticValue[0])), "green"); - - return; + if (m_columns.count() != 2) { + printError("Select only 2 columns "); + return; + } + + QString col1Name = m_columns[0]->name(); + QString col2Name = m_columns[1]->name(); + + int N = findCount(m_columns[0]); + if (N != findCount(m_columns[1])) { + printError("Number of data values in Column: " + col1Name + "and Column: " + col2Name + "are not equal"); + return; + } + + QVector col2Ranks(N); + if (m_columns[0]->isNumeric()) { + if (m_columns[0]->isNumeric() && m_columns[1]->isNumeric()) { + for (int i = 0; i < N; i++) + col2Ranks[int(m_columns[0]->valueAt(i)) - 1] = int(m_columns[1]->valueAt(i)); + } else { + printError(QString("Ranking System should be same for both Column: %1 and Column: %2
" + "Hint: Check for data types of columns").arg(col1Name).arg(col2Name)); + return; + } + } else { + AbstractColumn::ColumnMode origCol1Mode = m_columns[0]->columnMode(); + AbstractColumn::ColumnMode origCol2Mode = m_columns[1]->columnMode(); + + m_columns[0]->setColumnMode(AbstractColumn::Text); + m_columns[1]->setColumnMode(AbstractColumn::Text); + + QMap ValueToRank; + + for (int i = 0; i < N; i++) { + if (ValueToRank[m_columns[0]->textAt(i)] != 0) { + printError("Currently ties are not supported"); + m_columns[0]->setColumnMode(origCol1Mode); + m_columns[1]->setColumnMode(origCol2Mode); + return; + } + ValueToRank[m_columns[0]->textAt(i)] = i + 1; + } + + for (int i = 0; i < N; i++) + col2Ranks[i] = ValueToRank[m_columns[1]->textAt(i)]; + + m_columns[0]->setColumnMode(origCol1Mode); + m_columns[1]->setColumnMode(origCol2Mode); + } + + int nPossiblePairs = (N * (N - 1)) / 2; + + int nDiscordant = findDiscordants(col2Ranks.data(), 0, N - 1); + int nCorcordant = nPossiblePairs - nDiscordant; + + m_correlationValue = double(nCorcordant - nDiscordant) / nPossiblePairs; + + m_statisticValue.append((3 * (nCorcordant - nDiscordant)) / + sqrt(N * (N- 1) * (2 * N + 5) / 2)); + + printLine(0, QString("Number of Discordants are %1").arg(nDiscordant), "green"); + printLine(1, QString("Number of Concordant are %1").arg(nCorcordant), "green"); + + printLine(2, QString("Tau a is %1").arg(round(m_correlationValue)), "green"); + printLine(3, QString("Z Value is %1").arg(round(m_statisticValue[0])), "green"); + + return; } /***********************************************Spearman ******************************************************************/ // All formulaes and symbols are taken from : https://www.statisticshowto.datasciencecentral.com/spearman-rank-correlation-definition-calculate/ void CorrelationCoefficient::performSpearman() { - if (m_columns.count() != 2) { - printError("Select only 2 columns "); - return; - } + if (m_columns.count() != 2) { + printError("Select only 2 columns "); + return; + } - QString col1Name = m_columns[0]->name(); - QString col2Name = m_columns[1]->name(); + QString col1Name = m_columns[0]->name(); + QString col2Name = m_columns[1]->name(); - int N = findCount(m_columns[0]); - if (N != findCount(m_columns[1])) { - printError("Number of data values in Column: " + col1Name + "and Column: " + col2Name + "are not equal"); - return; - } + int N = findCount(m_columns[0]); + if (N != findCount(m_columns[1])) { + printError("Number of data values in Column: " + col1Name + "and Column: " + col2Name + "are not equal"); + return; + } - QMap col1Ranks; - convertToRanks(m_columns[0], N, col1Ranks); + QMap col1Ranks; + convertToRanks(m_columns[0], N, col1Ranks); - QMap col2Ranks; - convertToRanks(m_columns[1], N, col2Ranks); + QMap col2Ranks; + convertToRanks(m_columns[1], N, col2Ranks); - double ranksCol1Mean = 0; - double ranksCol2Mean = 0; + double ranksCol1Mean = 0; + double ranksCol2Mean = 0; - for (int i = 0; i < N; i++) { - ranksCol1Mean += col1Ranks[int(m_columns[0]->valueAt(i))]; - ranksCol2Mean += col2Ranks[int(m_columns[1]->valueAt(i))]; - } + for (int i = 0; i < N; i++) { + ranksCol1Mean += col1Ranks[int(m_columns[0]->valueAt(i))]; + ranksCol2Mean += col2Ranks[int(m_columns[1]->valueAt(i))]; + } - ranksCol1Mean = ranksCol1Mean / N; - ranksCol2Mean = ranksCol2Mean / N; + ranksCol1Mean = ranksCol1Mean / N; + ranksCol2Mean = ranksCol2Mean / N; - double s12 = 0; - double s1 = 0; - double s2 = 0; + double s12 = 0; + double s1 = 0; + double s2 = 0; - for (int i = 0; i < N; i++) { - double centeredRank_1 = col1Ranks[int(m_columns[0]->valueAt(i))] - ranksCol1Mean; - double centeredRank_2 = col2Ranks[int(m_columns[1]->valueAt(i))] - ranksCol2Mean; + for (int i = 0; i < N; i++) { + double centeredRank_1 = col1Ranks[int(m_columns[0]->valueAt(i))] - ranksCol1Mean; + double centeredRank_2 = col2Ranks[int(m_columns[1]->valueAt(i))] - ranksCol2Mean; - s12 += centeredRank_1 * centeredRank_2; + s12 += centeredRank_1 * centeredRank_2; - s1 += gsl_pow_2(centeredRank_1); - s2 += gsl_pow_2(centeredRank_2); - } + s1 += gsl_pow_2(centeredRank_1); + s2 += gsl_pow_2(centeredRank_2); + } - s12 = s12 / N; - s1 = s1 / N; - s2 = s2 / N; + s12 = s12 / N; + s1 = s1 / N; + s2 = s2 / N; - m_correlationValue = s12 / std::sqrt(s1 * s2); + m_correlationValue = s12 / std::sqrt(s1 * s2); - printLine(0, QString("Spearman Rank Correlation value is %1").arg(m_correlationValue), "green"); + printLine(0, QString("Spearman Rank Correlation value is %1").arg(m_correlationValue), "green"); } /***********************************************Helper Functions******************************************************************/ int CorrelationCoefficient::findDiscordants(int *ranks, int start, int end) { - if (start >= end) - return 0; - - int mid = (start + end) / 2; - - int leftDiscordants = findDiscordants(ranks, start, mid); - int rightDiscordants = findDiscordants(ranks, mid + 1, end); - - int len = end - start + 1; - int leftLen = mid - start + 1; - int rightLen = end - mid; - int leftLenRemain = leftLen; - - QVector leftRanks(leftLen); - QVector rightRanks(rightLen); - - for (int i = 0; i < leftLen; i++) - leftRanks[i] = ranks[start + i]; - - for (int i = leftLen; i < leftLen + rightLen; i++) - rightRanks[i - leftLen] = ranks[start + i]; - - int mergeDiscordants = 0; - int i = 0, j = 0, k =0; - while (i < len) { - if (j >= leftLen) { - ranks[start + i] = rightRanks[k]; - k++; - } else if (k >= rightLen) { - ranks[start + i] = leftRanks[j]; - j++; - } else if (leftRanks[j] < rightRanks[k]) { - ranks[start + i] = leftRanks[j]; - j++; - leftLenRemain--; - } else if (leftRanks[j] > rightRanks[k]) { - ranks[start + i] = rightRanks[k]; - mergeDiscordants += leftLenRemain; - k++; - } - i++; - } - return leftDiscordants + rightDiscordants + mergeDiscordants; + if (start >= end) + return 0; + + int mid = (start + end) / 2; + + int leftDiscordants = findDiscordants(ranks, start, mid); + int rightDiscordants = findDiscordants(ranks, mid + 1, end); + + int len = end - start + 1; + int leftLen = mid - start + 1; + int rightLen = end - mid; + int leftLenRemain = leftLen; + + QVector leftRanks(leftLen); + QVector rightRanks(rightLen); + + for (int i = 0; i < leftLen; i++) + leftRanks[i] = ranks[start + i]; + + for (int i = leftLen; i < leftLen + rightLen; i++) + rightRanks[i - leftLen] = ranks[start + i]; + + int mergeDiscordants = 0; + int i = 0, j = 0, k =0; + while (i < len) { + if (j >= leftLen) { + ranks[start + i] = rightRanks[k]; + k++; + } else if (k >= rightLen) { + ranks[start + i] = leftRanks[j]; + j++; + } else if (leftRanks[j] < rightRanks[k]) { + ranks[start + i] = leftRanks[j]; + j++; + leftLenRemain--; + } else if (leftRanks[j] > rightRanks[k]) { + ranks[start + i] = rightRanks[k]; + mergeDiscordants += leftLenRemain; + k++; + } + i++; + } + return leftDiscordants + rightDiscordants + mergeDiscordants; } void CorrelationCoefficient::convertToRanks(const Column* col, int N, QMap &ranks) { - if (col->isNumeric()) - return; + if (col->isNumeric()) + return; - double* sortedList = new double[N]; - for (int i = 0; i < N; i++) - sortedList[i] = col->valueAt(i); + double* sortedList = new double[N]; + for (int i = 0; i < N; i++) + sortedList[i] = col->valueAt(i); - std::sort(sortedList, sortedList + N, std::greater()); + std::sort(sortedList, sortedList + N, std::greater()); - ranks.clear(); - for (int i = 0; i < N; i++) { - ranks[sortedList[i]] = i + 1; - } + ranks.clear(); + for (int i = 0; i < N; i++) + ranks[sortedList[i]] = i + 1; - delete[] sortedList; + delete[] sortedList; } void CorrelationCoefficient::convertToRanks(const Column* col, QMap &ranks) { - convertToRanks(col, findCount(col), ranks); + convertToRanks(col, findCount(col), ranks); } /***********************************************Virtual Functions******************************************************************/ QWidget* CorrelationCoefficient::view() const { - if (!m_partView) { - m_view = new CorrelationCoefficientView(const_cast(this)); - m_partView = m_view; - } - return m_partView; + if (!m_partView) { + m_view = new CorrelationCoefficientView(const_cast(this)); + m_partView = m_view; + } + return m_partView; } diff --git a/src/backend/generalTest/CorrelationCoefficient.h b/src/backend/generalTest/CorrelationCoefficient.h index 98adcde02..57981caf5 100644 --- a/src/backend/generalTest/CorrelationCoefficient.h +++ b/src/backend/generalTest/CorrelationCoefficient.h @@ -1,71 +1,71 @@ /*************************************************************************** File : CorrelationCoefficient.h Project : LabPlot Description : Finding Correlation Coefficient on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef CORRELATIONCOEFFICIENT_H #define CORRELATIONCOEFFICIENT_H #include "GeneralTest.h" class CorrelationCoefficientView; class CorrelationCoefficient : public GeneralTest { - Q_OBJECT + Q_OBJECT public: - explicit CorrelationCoefficient(const QString& name); - ~CorrelationCoefficient() override; + explicit CorrelationCoefficient(const QString& name); + ~CorrelationCoefficient() override; - enum Test{ - Pearson, - Kendall, - Spearman - }; + enum Test { + Pearson, + Kendall, + Spearman + }; - double correlationValue() const; - QList statisticValue() const; - QList pValue() const; + double correlationValue() const; + QList statisticValue() const; + QList pValue() const; - QWidget* view() const override; + QWidget* view() const override; - void performTest(Test m_test, bool categoricalVariable = false); + void performTest(Test m_test, bool categoricalVariable = false); private: - void performPearson(bool categoricalVariable); - void performKendall(); - void performSpearman(); + void performPearson(bool categoricalVariable); + void performKendall(); + void performSpearman(); - int findDiscordants(int* ranks, int start, int end); + int findDiscordants(int* ranks, int start, int end); - void convertToRanks(const Column* col, int N, QMap &ranks); - void convertToRanks(const Column* col, QMap &ranks); + void convertToRanks(const Column* col, int N, QMap &ranks); + void convertToRanks(const Column* col, QMap &ranks); - double m_correlationValue; - QList m_statisticValue; - QList m_pValue; + double m_correlationValue; + QList m_statisticValue; + QList m_pValue; }; #endif // CORRELATIONCOEFFICIENT_H diff --git a/src/backend/generalTest/GeneralTest.cpp b/src/backend/generalTest/GeneralTest.cpp index 278799cde..a33284f5b 100644 --- a/src/backend/generalTest/GeneralTest.cpp +++ b/src/backend/generalTest/GeneralTest.cpp @@ -1,554 +1,554 @@ /*************************************************************************** File : GeneralTest.cpp Project : LabPlot Description : Doing Hypothesis-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "GeneralTest.h" #include "kdefrontend/generalTest/HypothesisTestView.h" #include "backend/spreadsheet/Spreadsheet.h" #include "backend/core/column/Column.h" #include "backend/lib/macros.h" //#include //#include //#include #include #include //#include //#include //#include #include #include #include extern "C" { #include "backend/nsl/nsl_stats.h" } GeneralTest::GeneralTest(const QString& name, const AspectType& type) : AbstractPart(name, type), - m_summaryLayout(new QVBoxLayout()) { + m_summaryLayout(new QVBoxLayout()) { - m_currTestName = i18n("Result Table"); - for (int i = 0; i < RESULTLINESCOUNT; i++) { - m_resultLine[i] = new QLabel(); - m_summaryLayout->addWidget(m_resultLine[i]); - } + m_currTestName = i18n("Result Table"); + for (int i = 0; i < RESULTLINESCOUNT; i++) { + m_resultLine[i] = new QLabel(); + m_summaryLayout->addWidget(m_resultLine[i]); + } } GeneralTest::~GeneralTest() { } void GeneralTest::setDataSourceType(DataSourceType type) { - if (type != m_dataSourceType) - m_dataSourceType = type; + if (type != m_dataSourceType) + m_dataSourceType = type; } GeneralTest::DataSourceType GeneralTest::dataSourceType() const { - return m_dataSourceType; + return m_dataSourceType; } void GeneralTest::setDataSourceSpreadsheet(Spreadsheet* spreadsheet) { - m_dataSourceSpreadsheet = spreadsheet; - for (auto* col : m_dataSourceSpreadsheet->children()) - m_allColumns << col->name(); + m_dataSourceSpreadsheet = spreadsheet; + for (auto* col : m_dataSourceSpreadsheet->children()) + m_allColumns << col->name(); } QString GeneralTest::testName() { - return m_currTestName; + return m_currTestName; } QString GeneralTest::statsTable() { - return m_statsTable; + return m_statsTable; } QMap GeneralTest::tooltips() { - return m_tooltips; + return m_tooltips; } QVBoxLayout* GeneralTest::summaryLayout() { - return m_summaryLayout; + return m_summaryLayout; } void GeneralTest::setColumns(QStringList cols) { - m_columns.clear(); - Column* column = new Column("column"); - for (QString col : cols) { - if (!cols.isEmpty()) { - column = m_dataSourceSpreadsheet->column(col); - m_columns.append(column); - } - } - delete column; + m_columns.clear(); + Column* column = new Column("column"); + for (QString col : cols) { + if (!cols.isEmpty()) { + column = m_dataSourceSpreadsheet->column(col); + m_columns.append(column); + } + } + delete column; } void GeneralTest::setColumns(const QVector &cols) { - m_columns = cols; + m_columns = cols; } /******************************************************************************************************************** * Protected functions implementations [Helper Functions] ********************************************************************************************************************/ QString GeneralTest::round(QVariant number, int precision) { - if (number.userType() == QMetaType::Double || number.userType() == QMetaType::Float) { - double multiplierPrecision = gsl_pow_int(10, precision); - int tempNum = int(number.toDouble()*multiplierPrecision*10); + if (number.userType() == QMetaType::Double || number.userType() == QMetaType::Float) { + double multiplierPrecision = gsl_pow_int(10, precision); + int tempNum = int(number.toDouble()*multiplierPrecision*10); - if (tempNum % 10 < 5) - return QString::number((tempNum/10) / multiplierPrecision); - else - return QString::number((tempNum/10 + 1) / multiplierPrecision); - } - return i18n("%1", number.toString()); + if (tempNum % 10 < 5) + return QString::number((tempNum/10) / multiplierPrecision); + else + return QString::number((tempNum/10 + 1) / multiplierPrecision); + } + return i18n("%1", number.toString()); } int GeneralTest::findCount(const Column *column) { - int N = column->rowCount(); - switch (column->columnMode()) { - case (AbstractColumn::Numeric): - case (AbstractColumn::Integer): { - for (int i = 0; i < N; i++) - if (std::isnan(column->valueAt(i))) { - N = i; - break; - } - break; - } - case (AbstractColumn::Month): - case (AbstractColumn::Day): - case (AbstractColumn::Text): { - for (int i = 0; i < N; i++) - if (column->textAt(i).isEmpty()) { - N = i; - break; - } - break; - } - case (AbstractColumn::DateTime): - break; - } - return N; + int N = column->rowCount(); + switch (column->columnMode()) { + case (AbstractColumn::Numeric): + case (AbstractColumn::Integer): { + for (int i = 0; i < N; i++) + if (std::isnan(column->valueAt(i))) { + N = i; + break; + } + break; + } + case (AbstractColumn::Month): + case (AbstractColumn::Day): + case (AbstractColumn::Text): { + for (int i = 0; i < N; i++) + if (column->textAt(i).isEmpty()) { + N = i; + break; + } + break; + } + case (AbstractColumn::DateTime): + break; + } + return N; } double GeneralTest::findSum(const Column *column, int N) { - if (!column->isNumeric()) - return 0; + if (!column->isNumeric()) + return 0; - if (N < 0) - N = findCount(column); + if (N < 0) + N = findCount(column); - double sum = 0; - for (int i = 0; i < N; i++) - sum += column->valueAt(i); - return sum; + double sum = 0; + for (int i = 0; i < N; i++) + sum += column->valueAt(i); + return sum; } double GeneralTest::findSumSq(const Column *column, int N) { - if (!column->isNumeric()) - return 0; + if (!column->isNumeric()) + return 0; - if (N < 0) - N = findCount(column); + if (N < 0) + N = findCount(column); - double sumSq = 0; - for (int i = 0; i < N; i++) - sumSq += gsl_pow_2(column->valueAt(i)); - return sumSq; + double sumSq = 0; + for (int i = 0; i < N; i++) + sumSq += gsl_pow_2(column->valueAt(i)); + return sumSq; } double GeneralTest::findMean(const Column *column, int N) { - if (!column->isNumeric()) - return 0; + if (!column->isNumeric()) + return 0; - if (N < 0) - N = findCount(column); + if (N < 0) + N = findCount(column); - double sum = findSum(column, N); - return sum / N; + double sum = findSum(column, N); + return sum / N; } double GeneralTest::findStd(const Column *column, int N, double mean) { - if (!column->isNumeric()) - return 0; + if (!column->isNumeric()) + return 0; - double std = 0; - for (int i = 0; i < N; i++) { - double row = column->valueAt(i); - std += gsl_pow_2( (row - mean)); - } + double std = 0; + for (int i = 0; i < N; i++) { + double row = column->valueAt(i); + std += gsl_pow_2( (row - mean)); + } - if (N > 1) - std = std / (N-1); - std = sqrt(std); - return std; + if (N > 1) + std = std / (N-1); + std = sqrt(std); + return std; } double GeneralTest::findStd(const Column *column, int N) { - if (!column->isNumeric()) - return 0; + if (!column->isNumeric()) + return 0; - if (N < 0) - N = findCount(column); + if (N < 0) + N = findCount(column); - double mean = findMean(column, N); - return findStd(column, N, mean); + double mean = findMean(column, N); + return findStd(column, N, mean); } GeneralTest::ErrorType GeneralTest::findStats(const Column* column, int& count, double& sum, double& mean, double& std) { - count = findCount(column); - sum = findSum(column, count); - mean = findMean(column, count); - std = findStd(column, count, mean); + count = findCount(column); + sum = findSum(column, count); + mean = findMean(column, count); + std = findStd(column, count, mean); - if (count < 1) - return GeneralTest::ErrorEmptyColumn; + if (count < 1) + return GeneralTest::ErrorEmptyColumn; - return GeneralTest::NoError; + return GeneralTest::NoError; } GeneralTest::ErrorType GeneralTest::findStatsPaired(const Column* column1, const Column* column2, int& count, double& sum, double& mean, double& std) { - sum = 0; - mean = 0; - std = 0; + sum = 0; + mean = 0; + std = 0; - int count1 = column1->rowCount(); - int count2 = column2->rowCount(); + int count1 = column1->rowCount(); + int count2 = column2->rowCount(); - count = qMin(count1, count2); - double cell1, cell2; - for (int i = 0; i < count; i++) { - cell1 = column1->valueAt(i); - cell2 = column2->valueAt(i); + count = qMin(count1, count2); + double cell1, cell2; + for (int i = 0; i < count; i++) { + cell1 = column1->valueAt(i); + cell2 = column2->valueAt(i); - if (std::isnan(cell1) || std::isnan(cell2)) { - if (std::isnan(cell1) && std::isnan(cell2)) - count = i; - else - return GeneralTest::ErrorUnqualSize; - break; - } + if (std::isnan(cell1) || std::isnan(cell2)) { + if (std::isnan(cell1) && std::isnan(cell2)) + count = i; + else + return GeneralTest::ErrorUnqualSize; + break; + } - sum += cell1 - cell2; - } + sum += cell1 - cell2; + } - if (count < 1) - return GeneralTest::ErrorEmptyColumn; + if (count < 1) + return GeneralTest::ErrorEmptyColumn; - mean = sum / count; + mean = sum / count; - double row; - for (int i = 0; i < count; i++) { - cell1 = column1->valueAt(i); - cell2 = column2->valueAt(i); - row = cell1 - cell2; - std += gsl_pow_2( (row - mean)); - } + double row; + for (int i = 0; i < count; i++) { + cell1 = column1->valueAt(i); + cell2 = column2->valueAt(i); + row = cell1 - cell2; + std += gsl_pow_2( (row - mean)); + } - if (count > 1) - std = std / (count-1); + if (count > 1) + std = std / (count-1); - std = sqrt(std); - return GeneralTest::NoError; + std = sqrt(std); + return GeneralTest::NoError; } void GeneralTest::countPartitions(Column* column, int& np, int& totalRows) { - totalRows = column->rowCount(); - np = 0; - QString cellValue; - QMap discoveredCategoricalVar; + totalRows = column->rowCount(); + np = 0; + QString cellValue; + QMap discoveredCategoricalVar; - AbstractColumn::ColumnMode originalColMode = column->columnMode(); - column->setColumnMode(AbstractColumn::Text); + AbstractColumn::ColumnMode originalColMode = column->columnMode(); + column->setColumnMode(AbstractColumn::Text); - for (int i = 0; i < totalRows; i++) { - cellValue = column->textAt(i); + for (int i = 0; i < totalRows; i++) { + cellValue = column->textAt(i); - if (cellValue.isEmpty()) { - totalRows = i; - break; - } + if (cellValue.isEmpty()) { + totalRows = i; + break; + } - if (discoveredCategoricalVar[cellValue]) - continue; + if (discoveredCategoricalVar[cellValue]) + continue; - discoveredCategoricalVar[cellValue] = true; - np++; - } - column->setColumnMode(originalColMode); + discoveredCategoricalVar[cellValue] = true; + np++; + } + column->setColumnMode(originalColMode); } GeneralTest::ErrorType GeneralTest::findStatsCategorical(Column* column1, Column* column2, int n[], double sum[], double mean[], double std[], QMap& colName, const int& np, const int& totalRows) { - Column* columns[] = {column1, column2}; + Column* columns[] = {column1, column2}; - for (int i = 0; i < np; i++) { - n[i] = 0; - sum[i] = 0; - mean[i] = 0; - std[i] = 0; - } + for (int i = 0; i < np; i++) { + n[i] = 0; + sum[i] = 0; + mean[i] = 0; + std[i] = 0; + } - AbstractColumn::ColumnMode originalColMode = columns[0]->columnMode(); - columns[0]->setColumnMode(AbstractColumn::Text); + AbstractColumn::ColumnMode originalColMode = columns[0]->columnMode(); + columns[0]->setColumnMode(AbstractColumn::Text); - int partitionNumber = 1; - for (int i = 0; i < totalRows; i++) { - QString name = columns[0]->textAt(i); - double value = columns[1]->valueAt(i); + int partitionNumber = 1; + for (int i = 0; i < totalRows; i++) { + QString name = columns[0]->textAt(i); + double value = columns[1]->valueAt(i); - if (std::isnan(value)) { - columns[0]->setColumnMode(originalColMode); - return GeneralTest::ErrorUnqualSize; - } + if (std::isnan(value)) { + columns[0]->setColumnMode(originalColMode); + return GeneralTest::ErrorUnqualSize; + } - if (colName[name] == 0) { - colName[name] = partitionNumber; - partitionNumber++; - } + if (colName[name] == 0) { + colName[name] = partitionNumber; + partitionNumber++; + } - n[colName[name]-1]++; - sum[colName[name]-1] += value; - } + n[colName[name]-1]++; + sum[colName[name]-1] += value; + } - for (int i = 0; i < np; i++) - mean[i] = sum[i] / n[i]; + for (int i = 0; i < np; i++) + mean[i] = sum[i] / n[i]; - for (int i = 0; i < totalRows; i++) { - QString name = columns[0]->textAt(i); - double value = columns[1]->valueAt(i); + for (int i = 0; i < totalRows; i++) { + QString name = columns[0]->textAt(i); + double value = columns[1]->valueAt(i); - std[colName[name]-1] += gsl_pow_2( (value - mean[colName[name]-1])); - } + std[colName[name]-1] += gsl_pow_2( (value - mean[colName[name]-1])); + } - for (int i = 0; i < np; i++) { - if (n[i] > 1) - std[i] = std[i] / (n[i] - 1); - std[i] = sqrt(std[i]); - } + for (int i = 0; i < np; i++) { + if (n[i] > 1) + std[i] = std[i] / (n[i] - 1); + std[i] = sqrt(std[i]); + } - columns[0]->setColumnMode(originalColMode); - if (columns[0]->isNumeric()) { + columns[0]->setColumnMode(originalColMode); + if (columns[0]->isNumeric()) { - } + } - return GeneralTest::NoError; + return GeneralTest::NoError; } QString GeneralTest::getHtmlTable(int row, int column, QVariant* rowMajor) { - if (row < 1 || column < 1) - return QString(); - - QString table; - table = "" - "" - " "; - - QString bg = "tg-0pky"; - bool pky = true; - - QString element; - table += " "; - for (int j = 0; j < column; j++) { - element = rowMajor[j].toString(); - table += " "; - } - table += " "; - - if (pky) - bg = "tg-0pky"; - else - bg = "tg-btxf"; - pky = !pky; - - for (int i = 1; i < row; i++) { - table += " "; - - QString element = round(rowMajor[i*column]); - table += " "; - for (int j = 1; j < column; j++) { - element = round(rowMajor[i*column+j]); - table += " "; - } - - table += " "; - if (pky) - bg = "tg-0pky"; - else - bg = "tg-btxf"; - pky = !pky; - } - table += "
" + i18n("%1", element) + "
" + i18n("%1", element) + "" + i18n("%1", element) + "
"; - - return table; + if (row < 1 || column < 1) + return QString(); + + QString table; + table = "" + "" + " "; + + QString bg = "tg-0pky"; + bool pky = true; + + QString element; + table += " "; + for (int j = 0; j < column; j++) { + element = rowMajor[j].toString(); + table += " "; + } + table += " "; + + if (pky) + bg = "tg-0pky"; + else + bg = "tg-btxf"; + pky = !pky; + + for (int i = 1; i < row; i++) { + table += " "; + + QString element = round(rowMajor[i*column]); + table += " "; + for (int j = 1; j < column; j++) { + element = round(rowMajor[i*column+j]); + table += " "; + } + + table += " "; + if (pky) + bg = "tg-0pky"; + else + bg = "tg-btxf"; + pky = !pky; + } + table += "
" + i18n("%1", element) + "
" + i18n("%1", element) + "" + i18n("%1", element) + "
"; + + return table; } QString GeneralTest::getHtmlTable3(const QList& rowMajor) { - m_tooltips.clear(); - int rowMajorSize = rowMajor.size(); - - if (rowMajorSize == 0) - return QString(); - - QString table; - table = ""; - - table += ""; - - table += " "; - int prevLevel = 0; - for (int i = 0; i < rowMajorSize; i++) { - Cell* currCell = rowMajor[i]; - if (currCell->level != prevLevel) { - table += " "; - table += " "; - prevLevel = currCell->level; - } - QString cellStartTag = ""; - table += "
isHeader) { - cellStartTag = "" + - i18n("%1", currCell->data) + - cellEndTag; - - if (!currCell->tooltip.isEmpty()) - m_tooltips.insert(currCell->data, currCell->tooltip); - } - table += "
"; - return table; + m_tooltips.clear(); + int rowMajorSize = rowMajor.size(); + + if (rowMajorSize == 0) + return QString(); + + QString table; + table = ""; + + table += ""; + + table += " "; + int prevLevel = 0; + for (int i = 0; i < rowMajorSize; i++) { + Cell* currCell = rowMajor[i]; + if (currCell->level != prevLevel) { + table += " "; + table += " "; + prevLevel = currCell->level; + } + QString cellStartTag = ""; + table += "
isHeader) { + cellStartTag = "" + + i18n("%1", currCell->data) + + cellEndTag; + + if (!currCell->tooltip.isEmpty()) + m_tooltips.insert(currCell->data, currCell->tooltip); + } + table += "
"; + return table; } QString GeneralTest::getLine(const QString& msg, const QString& color) { - return "

" + i18n("%1", msg) + "

"; + return "

" + i18n("%1", msg) + "

"; } void GeneralTest::printLine(const int& index, const QString& msg, const QString& color) { - if (index < 0 || index >= 10) - return; + if (index < 0 || index >= 10) + return; - m_resultLine[index]->setText(getLine(msg, color)); - return; + m_resultLine[index]->setText(getLine(msg, color)); + return; } void GeneralTest::printTooltip(const int &index, const QString &msg) { - if (index < 0 || index >= 10) - return; + if (index < 0 || index >= 10) + return; - m_resultLine[index]->setToolTip(i18n("%1", msg)); + m_resultLine[index]->setToolTip(i18n("%1", msg)); } void GeneralTest::printError(const QString& errorMsg) { - printLine(0, errorMsg, "red"); + printLine(0, errorMsg, "red"); } /******************************************************************************************************************** * virtual functions implementations ********************************************************************************************************************/ /*! Saves as XML. */ void GeneralTest::save(QXmlStreamWriter* writer) const { - writer->writeStartElement("GeneralTest"); - writeBasicAttributes(writer); - writeCommentElement(writer); + writer->writeStartElement("GeneralTest"); + writeBasicAttributes(writer); + writeCommentElement(writer); - writer->writeEndElement(); + writer->writeEndElement(); } /*! Loads from XML. */ bool GeneralTest::load(XmlStreamReader* reader, bool preview) { - Q_UNUSED(preview); - if (!readBasicAttributes(reader)) - return false; + Q_UNUSED(preview); + if (!readBasicAttributes(reader)) + return false; - return !reader->hasError(); + return !reader->hasError(); } Spreadsheet *GeneralTest::dataSourceSpreadsheet() const { - return m_dataSourceSpreadsheet; + return m_dataSourceSpreadsheet; } bool GeneralTest::exportView() const { - return true; + return true; } bool GeneralTest::printView() { - return true; + return true; } bool GeneralTest::printPreview() const { - return true; + return true; } /*! Constructs a primary view on me. This method may be called multiple times during the life time of an Aspect, or it might not get called at all. Aspects must not depend on the existence of a view for their operation. */ //QWidget* GeneralTest::view() const { // if (!m_partView) { // m_view = new HypothesisTestView(const_cast(this)); // m_partView = m_view; // } // return m_partView; //} /*! Returns a new context menu. The caller takes ownership of the menu. */ QMenu* GeneralTest::createContextMenu() { - QMenu* menu = AbstractPart::createContextMenu(); - // Q_ASSERT(menu); - // emit requestProjectContextMenu(menu); - return menu; + QMenu* menu = AbstractPart::createContextMenu(); + // Q_ASSERT(menu); + // emit requestProjectContextMenu(menu); + return menu; } diff --git a/src/backend/generalTest/GeneralTest.h b/src/backend/generalTest/GeneralTest.h index 55c9f00ca..961960a8e 100644 --- a/src/backend/generalTest/GeneralTest.h +++ b/src/backend/generalTest/GeneralTest.h @@ -1,145 +1,145 @@ /*************************************************************************** File : GeneralTest.h Project : LabPlot Description : Doing Hypothesis-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef GENERALTEST_H #define GENERALTEST_H #include "backend/core/AbstractPart.h" #include "backend/lib/macros.h" #include "kdefrontend/generalTest/GeneralTestView.h" class Spreadsheet; class QString; class Column; class QVBoxLayout; class QLabel; class GeneralTest : public AbstractPart { - Q_OBJECT + Q_OBJECT public: - explicit GeneralTest(const QString& name, const AspectType& type); - ~GeneralTest() override; - - enum DataSourceType {DataSourceSpreadsheet, DataSourceDatabase}; - - struct Cell { - QString data; - int level; - bool isHeader; - QString tooltip; - int rowSpanCount; - int columnSpanCount; - Cell(QVariant data = "", int level = 0, bool isHeader = false, QString tooltip = "", int rowSpanCount = 1, int columnSpanCount = 1) { - this->data = data.toString(); - this->level = level; - this->isHeader = isHeader; - this->tooltip = tooltip; - this->rowSpanCount = rowSpanCount; - this->columnSpanCount = columnSpanCount; - } - }; - - enum ErrorType {ErrorUnqualSize, ErrorEmptyColumn, NoError}; - - void setDataSourceType(DataSourceType type); - DataSourceType dataSourceType() const; - void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); - Spreadsheet* dataSourceSpreadsheet() const; - - void setColumns(const QVector& cols); - void setColumns(QStringList cols); - QStringList allColumns(); - QString testName(); - QString statsTable(); - QMap tooltips(); - - QVBoxLayout* summaryLayout(); - - //virtual methods - // QIcon icon() const override; - QMenu* createContextMenu() override; + explicit GeneralTest(const QString& name, const AspectType& type); + ~GeneralTest() override; + + enum DataSourceType {DataSourceSpreadsheet, DataSourceDatabase}; + + struct Cell { + QString data; + int level; + bool isHeader; + QString tooltip; + int rowSpanCount; + int columnSpanCount; + Cell(QVariant data = "", int level = 0, bool isHeader = false, QString tooltip = "", int rowSpanCount = 1, int columnSpanCount = 1) { + this->data = data.toString(); + this->level = level; + this->isHeader = isHeader; + this->tooltip = tooltip; + this->rowSpanCount = rowSpanCount; + this->columnSpanCount = columnSpanCount; + } + }; + + enum ErrorType {ErrorUnqualSize, ErrorEmptyColumn, NoError}; + + void setDataSourceType(DataSourceType type); + DataSourceType dataSourceType() const; + void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); + Spreadsheet* dataSourceSpreadsheet() const; + + void setColumns(const QVector& cols); + void setColumns(QStringList cols); + QStringList allColumns(); + QString testName(); + QString statsTable(); + QMap tooltips(); + + QVBoxLayout* summaryLayout(); + + //virtual methods + // QIcon icon() const override; + QMenu* createContextMenu() override; // QWidget* view() const override; - bool exportView() const override; - bool printView() override; - bool printPreview() const override; + bool exportView() const override; + bool printView() override; + bool printPreview() const override; - void save(QXmlStreamWriter*) const override; - bool load(XmlStreamReader*, bool preview) override; + void save(QXmlStreamWriter*) const override; + bool load(XmlStreamReader*, bool preview) override; signals: - void changed(); - void requestProjectContextMenu(QMenu*); - void dataSourceTypeChanged(GeneralTest::DataSourceType); - void dataSourceSpreadsheetChanged(Spreadsheet*); + void changed(); + void requestProjectContextMenu(QMenu*); + void dataSourceTypeChanged(GeneralTest::DataSourceType); + void dataSourceSpreadsheetChanged(Spreadsheet*); protected: - DataSourceType m_dataSourceType{GeneralTest::DataSourceSpreadsheet}; - Spreadsheet* m_dataSourceSpreadsheet{nullptr}; - QVector m_columns; - QStringList m_allColumns; + DataSourceType m_dataSourceType{GeneralTest::DataSourceSpreadsheet}; + Spreadsheet* m_dataSourceSpreadsheet{nullptr}; + QVector m_columns; + QStringList m_allColumns; - QString m_currTestName; - QString m_statsTable; + QString m_currTestName; + QString m_statsTable; - QVBoxLayout* m_summaryLayout{nullptr}; - QLabel* m_resultLine[RESULTLINESCOUNT]; - QMap m_tooltips; + QVBoxLayout* m_summaryLayout{nullptr}; + QLabel* m_resultLine[RESULTLINESCOUNT]; + QMap m_tooltips; - QString round(QVariant number, int precision = 3); + QString round(QVariant number, int precision = 3); - int findCount(const Column* column); - double findSum(const Column* column, int N = -1); - double findSumSq(const Column* column, int N = -1); - double findMean(const Column* column, int N = -1); - double findStd(const Column* column, int N, double mean); - double findStd(const Column* column, int N = -1); + int findCount(const Column* column); + double findSum(const Column* column, int N = -1); + double findSumSq(const Column* column, int N = -1); + double findMean(const Column* column, int N = -1); + double findStd(const Column* column, int N, double mean); + double findStd(const Column* column, int N = -1); - void countPartitions(Column* column, int& np, int& totalRows); + void countPartitions(Column* column, int& np, int& totalRows); // double findSumProducts(const Column* columns[], int N = -1); - ErrorType findStats(const Column* column,int& count, double& sum, double& mean, double& std); - ErrorType findStatsPaired(const Column* column1, const Column* column2, int& count, double& sum, double& mean, double& std); - ErrorType findStatsCategorical(Column* column1, Column* column2, int n[], double sum[], double mean[], double std[], QMap& colName, const int& np, const int& totalRows); + ErrorType findStats(const Column* column,int& count, double& sum, double& mean, double& std); + ErrorType findStatsPaired(const Column* column1, const Column* column2, int& count, double& sum, double& mean, double& std); + ErrorType findStatsCategorical(Column* column1, Column* column2, int n[], double sum[], double mean[], double std[], QMap& colName, const int& np, const int& totalRows); - QString getHtmlTable(int row, int column, QVariant* rowMajor); - QString getHtmlTable3(const QList& rowMajor); + QString getHtmlTable(int row, int column, QVariant* rowMajor); + QString getHtmlTable3(const QList& rowMajor); - QString getLine(const QString& msg, const QString& color = "black"); - void printLine(const int& index, const QString& msg, const QString& color = "black"); - void printTooltip(const int& index, const QString& msg); - void printError(const QString& errorMsg); + QString getLine(const QString& msg, const QString& color = "black"); + void printLine(const int& index, const QString& msg, const QString& color = "black"); + void printTooltip(const int& index, const QString& msg); + void printError(const QString& errorMsg); - bool m_dbCreated{false}; - mutable GeneralTestView* m_view{nullptr}; + bool m_dbCreated{false}; + mutable GeneralTestView* m_view{nullptr}; }; #endif // GeneralTest_H diff --git a/src/backend/generalTest/HypothesisTest.cpp b/src/backend/generalTest/HypothesisTest.cpp index d9dc7e7ad..1033587d6 100644 --- a/src/backend/generalTest/HypothesisTest.cpp +++ b/src/backend/generalTest/HypothesisTest.cpp @@ -1,1148 +1,1147 @@ /*************************************************************************** - File : HypothesisTest.cpp - Project : LabPlot - Description : Doing Hypothesis-Test on data provided - -------------------------------------------------------------------- - Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) + File : HypothesisTest.cpp + Project : LabPlot + Description : Doing Hypothesis-Test on data provided + -------------------------------------------------------------------- + Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "HypothesisTest.h" #include "kdefrontend/generalTest/HypothesisTestView.h" #include "backend/spreadsheet/Spreadsheet.h" #include "backend/core/column/Column.h" #include "backend/lib/macros.h" #include #include #include #include #include #include #include #include #include #include #include extern "C" { #include "backend/nsl/nsl_stats.h" } HypothesisTest::HypothesisTest(const QString &name) : GeneralTest(name, AspectType::HypothesisTest) { } HypothesisTest::~HypothesisTest() { } void HypothesisTest::setPopulationMean(QVariant populationMean) { - m_populationMean = populationMean.toDouble(); + m_populationMean = populationMean.toDouble(); } void HypothesisTest::setSignificanceLevel(QVariant alpha) { - m_significanceLevel = alpha.toDouble(); + m_significanceLevel = alpha.toDouble(); } void HypothesisTest::performTest(Test test, bool categoricalVariable, bool equalVariance) { - m_tailType = test.tail; - m_pValue.clear(); - m_statisticValue.clear(); - m_statsTable = ""; - m_tooltips.clear(); - for (int i = 0; i < RESULTLINESCOUNT; i++) - m_resultLine[i]->clear(); - - switch (test.subtype) { - case HypothesisTest::Test::SubType::TwoSampleIndependent: { - m_currTestName = "

" + i18n("Two Sample Independent Test") + "

"; - performTwoSampleIndependentTest(test.type, categoricalVariable, equalVariance); - break; - } - case HypothesisTest::Test::SubType::TwoSamplePaired: - m_currTestName = "

" + i18n("Two Sample Paired Test") + "

"; - performTwoSamplePairedTest(test.type); - break; - case HypothesisTest::Test::SubType::OneSample: { - m_currTestName = "

" + i18n("One Sample Test") + "

"; - performOneSampleTest(test.type); - break; - } - case HypothesisTest::Test::SubType::OneWay: { - m_currTestName = "

" + i18n("One Way Anova") + "

"; - performOneWayAnova(); - break; - } - case HypothesisTest::Test::SubType::TwoWay: { - m_currTestName = "

" + i18n("Two Way Anova") + "

"; - performTwoWayAnova(); - break; - } - case HypothesisTest::Test::SubType::NoneSubType: - break; - } - - emit changed(); + m_tailType = test.tail; + m_pValue.clear(); + m_statisticValue.clear(); + m_statsTable = ""; + m_tooltips.clear(); + for (int i = 0; i < RESULTLINESCOUNT; i++) + m_resultLine[i]->clear(); + + switch (test.subtype) { + case HypothesisTest::Test::SubType::TwoSampleIndependent: { + m_currTestName = "

" + i18n("Two Sample Independent Test") + "

"; + performTwoSampleIndependentTest(test.type, categoricalVariable, equalVariance); + break; + } + case HypothesisTest::Test::SubType::TwoSamplePaired: + m_currTestName = "

" + i18n("Two Sample Paired Test") + "

"; + performTwoSamplePairedTest(test.type); + break; + case HypothesisTest::Test::SubType::OneSample: { + m_currTestName = "

" + i18n("One Sample Test") + "

"; + performOneSampleTest(test.type); + break; + } + case HypothesisTest::Test::SubType::OneWay: { + m_currTestName = "

" + i18n("One Way Anova") + "

"; + performOneWayAnova(); + break; + } + case HypothesisTest::Test::SubType::TwoWay: { + m_currTestName = "

" + i18n("Two Way Anova") + "

"; + performTwoWayAnova(); + break; + } + case HypothesisTest::Test::SubType::NoneSubType: + break; + } + + emit changed(); } void HypothesisTest::performLeveneTest(bool categoricalVariable) { - m_pValue.clear(); - m_statisticValue.clear(); - m_statsTable = ""; - m_tooltips.clear(); - for (int i = 0; i < RESULTLINESCOUNT; i++) - m_resultLine[i]->clear(); - - m_currTestName = "

" + i18n("Levene Test for Equality of Variance") + "

"; - m_performLeveneTest(categoricalVariable); - emit changed(); + m_pValue.clear(); + m_statisticValue.clear(); + m_statsTable = ""; + m_tooltips.clear(); + for (int i = 0; i < RESULTLINESCOUNT; i++) + m_resultLine[i]->clear(); + + m_currTestName = "

" + i18n("Levene Test for Equality of Variance") + "

"; + m_performLeveneTest(categoricalVariable); + emit changed(); } -QList& HypothesisTest::statisticValue(){ - return m_statisticValue; +QList& HypothesisTest::statisticValue() { + return m_statisticValue; } -QList& HypothesisTest::pValue(){ - return m_pValue; +QList& HypothesisTest::pValue() { + return m_pValue; } /****************************************************************************** * Private Implementations * ****************************************************************************/ //TODO: backend of z test; //TODO: add tooltip to tables. (currently it is not possible to use with QTextDocument); //TODO: use https://www.gnu.org/software/gsl/doc/html/statistics.html for basic statistic calculations /**************************Two Sample Independent *************************************/ void HypothesisTest::performTwoSampleIndependentTest(HypothesisTest::Test::Type test, bool categoricalVariable, bool equalVariance) { - if (m_columns.size() != 2) { - printError("Inappropriate number of m_columns selected"); - return; - } - - int n[2]; - double sum[2], mean[2], std[2]; - - QString col1Name = m_columns[0]->name(); - QString col2Name = m_columns[1]->name(); - - if (!categoricalVariable && m_columns[0]->isNumeric()) { - for (int i = 0; i < 2; i++) { - findStats(m_columns[i], n[i], sum[i], mean[i], std[i]); - if (n[i] == 0) { - printError("At least two values should be there in every column"); - return; - } - if (std[i] == 0.0) { - printError(i18n("Standard Deviation of at least one column is equal to 0: last column is: %1", m_columns[i]->name())); - return; - } - } - } else { - QMap colName; - QString baseColName; - int np; - int totalRows; - - countPartitions(m_columns[0], np, totalRows); - if (np != 2) { - printError( i18n("Number of Categorical Variable in Column %1 is not equal to 2", m_columns[0]->name())); - return; - } - - if (m_columns[0]->isNumeric()) - baseColName = m_columns[0]->name(); - - ErrorType errorCode = findStatsCategorical(m_columns[0], m_columns[1], n, sum, mean, std, colName, np, totalRows); - - switch (errorCode) { - case ErrorUnqualSize: { - printError( i18n("Unequal size between Column %1 and Column %2", m_columns[0]->name(), m_columns[1]->name())); - return; - } - case ErrorEmptyColumn: { - printError("At least one of selected column is empty"); - - return; - } - case NoError: - break; - } - - QMapIterator i(colName); - while (i.hasNext()) { - i.next(); - if (i.value() == 1) - col1Name = baseColName + " " + i.key(); - else - col2Name = baseColName + " " + i.key(); - } - } - - QVariant rowMajor[] = {"", "N", "Sum", "Mean", "Std", - col1Name, n[0], sum[0], mean[0], std[0], - col2Name, n[1], sum[1], mean[1], std[1] - }; - - m_statsTable = getHtmlTable(3, 5, rowMajor); - - for (int i = 0; i < 2; i++) { - if (n[i] == 0) { - printError("At least two values should be there in every column"); - return; - } - if (std[i] == 0.0) { - printError( i18n("Standard Deviation of at least one column is equal to 0: last column is: %1", m_columns[i]->name())); - return; - } - } - - double stdSq[2]; - stdSq[0] = gsl_pow_2(std[0]); - stdSq[1] = gsl_pow_2(std[1]); - - QString testName; - int df = 0; - double spSq = 0; - - switch (test) { - case HypothesisTest::Test::Type::TTest: { - testName = "T"; - - if (equalVariance) { - df = n[0] + n[1] - 2; - - spSq = ((n[0]-1) * stdSq[0] + - (n[1]-1) * stdSq[1] ) / df; - QDEBUG("equal variance : spSq is " << spSq); - m_statisticValue.append((mean[0] - mean[1]) / sqrt(spSq / n[0] + spSq / n[1])); - printLine(9, "Assumption: Equal Variance b/w both population means"); - } else { - double temp_val; - temp_val = gsl_pow_2( gsl_pow_2(std[0]) / n[0] + gsl_pow_2(std[1]) / n[1]); - temp_val = temp_val / ( (gsl_pow_2( (gsl_pow_2(std[0]) / n[0]) ) / (n[0]-1)) + - (gsl_pow_2( (gsl_pow_2(std[1]) / n[1]) ) / (n[1]-1))); - df = qRound(temp_val); - - m_statisticValue.append((mean[0] - mean[1]) / (sqrt( (gsl_pow_2(std[0])/n[0]) + - (gsl_pow_2(std[1])/n[1])))); - printLine(9, "Assumption: UnEqual Variance b/w both population means"); - } - - printLine(8, "Assumption: Both Populations approximately follow normal distribution"); - break; - } - case HypothesisTest::Test::Type::ZTest: { - testName = "Z"; - spSq = ((n[0]-1) * gsl_pow_2(std[0]) + (n[1]-1) * gsl_pow_2(std[1])) / df; - m_statisticValue.append((mean[0] - mean[1]) / sqrt(spSq / n[0] + spSq / n[1])); - // m_pValue.append(gsl_cdf_gaussian_P(m_statisticValue, sp)); - break; - } - case HypothesisTest::Test::Type::Anova: - case HypothesisTest::Test::Type::NoneType: - break; - } - - m_currTestName = "

" + i18n("Two Sample Independent %1 Test for %2 vs %3", testName, col1Name, col2Name) + "

"; - m_pValue.append(getPValue(test, m_statisticValue[0], col1Name, col2Name, (mean[0] - mean[1]), sqrt(spSq), df)); - - printLine(2, i18n("Significance level is %1", round(m_significanceLevel)), "blue"); - - printLine(4, i18n("%1 Value is %2 ", testName, round(m_statisticValue[0])), "green"); - printTooltip(4, i18n("More is the |%1-value|, more safely we can reject the null hypothesis", testName)); - - printLine(5, i18n("P Value is %1 ", m_pValue[0]), "green"); - - printLine(6, i18n("Degree of Freedom is %1", df), "green"); - printTooltip(6, i18n("Number of independent Pieces of information that went into calculating the estimate")); - - if (m_pValue[0] <= m_significanceLevel) - printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", round(m_significanceLevel))); - else - printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); - return; + if (m_columns.size() != 2) { + printError("Inappropriate number of m_columns selected"); + return; + } + + int n[2]; + double sum[2], mean[2], std[2]; + + QString col1Name = m_columns[0]->name(); + QString col2Name = m_columns[1]->name(); + + if (!categoricalVariable && m_columns[0]->isNumeric()) { + for (int i = 0; i < 2; i++) { + findStats(m_columns[i], n[i], sum[i], mean[i], std[i]); + if (n[i] == 0) { + printError("At least two values should be there in every column"); + return; + } + if (std[i] == 0.0) { + printError(i18n("Standard Deviation of at least one column is equal to 0: last column is: %1", m_columns[i]->name())); + return; + } + } + } else { + QMap colName; + QString baseColName; + int np; + int totalRows; + + countPartitions(m_columns[0], np, totalRows); + if (np != 2) { + printError( i18n("Number of Categorical Variable in Column %1 is not equal to 2", m_columns[0]->name())); + return; + } + + if (m_columns[0]->isNumeric()) + baseColName = m_columns[0]->name(); + + ErrorType errorCode = findStatsCategorical(m_columns[0], m_columns[1], n, sum, mean, std, colName, np, totalRows); + + switch (errorCode) { + case ErrorUnqualSize: { + printError( i18n("Unequal size between Column %1 and Column %2", m_columns[0]->name(), m_columns[1]->name())); + return; + } + case ErrorEmptyColumn: { + printError("At least one of selected column is empty"); + + return; + } + case NoError: + break; + } + + QMapIterator i(colName); + while (i.hasNext()) { + i.next(); + if (i.value() == 1) + col1Name = baseColName + " " + i.key(); + else + col2Name = baseColName + " " + i.key(); + } + } + + QVariant rowMajor[] = {"", "N", "Sum", "Mean", "Std", + col1Name, n[0], sum[0], mean[0], std[0], + col2Name, n[1], sum[1], mean[1], std[1] + }; + + m_statsTable = getHtmlTable(3, 5, rowMajor); + + for (int i = 0; i < 2; i++) { + if (n[i] == 0) { + printError("At least two values should be there in every column"); + return; + } + if (std[i] == 0.0) { + printError( i18n("Standard Deviation of at least one column is equal to 0: last column is: %1", m_columns[i]->name())); + return; + } + } + + double stdSq[2]; + stdSq[0] = gsl_pow_2(std[0]); + stdSq[1] = gsl_pow_2(std[1]); + + QString testName; + int df = 0; + double spSq = 0; + + switch (test) { + case HypothesisTest::Test::Type::TTest: { + testName = "T"; + + if (equalVariance) { + df = n[0] + n[1] - 2; + + spSq = ((n[0]-1) * stdSq[0] + + (n[1]-1) * stdSq[1] ) / df; + QDEBUG("equal variance : spSq is " << spSq); + m_statisticValue.append((mean[0] - mean[1]) / sqrt(spSq / n[0] + spSq / n[1])); + printLine(9, "Assumption: Equal Variance b/w both population means"); + } else { + double temp_val; + temp_val = gsl_pow_2( gsl_pow_2(std[0]) / n[0] + gsl_pow_2(std[1]) / n[1]); + temp_val = temp_val / ( (gsl_pow_2( (gsl_pow_2(std[0]) / n[0]) ) / (n[0]-1)) + + (gsl_pow_2( (gsl_pow_2(std[1]) / n[1]) ) / (n[1]-1))); + df = qRound(temp_val); + + m_statisticValue.append((mean[0] - mean[1]) / (sqrt( (gsl_pow_2(std[0])/n[0]) + + (gsl_pow_2(std[1])/n[1])))); + printLine(9, "Assumption: UnEqual Variance b/w both population means"); + } + + printLine(8, "Assumption: Both Populations approximately follow normal distribution"); + break; + } + case HypothesisTest::Test::Type::ZTest: { + testName = "Z"; + spSq = ((n[0]-1) * gsl_pow_2(std[0]) + (n[1]-1) * gsl_pow_2(std[1])) / df; + m_statisticValue.append((mean[0] - mean[1]) / sqrt(spSq / n[0] + spSq / n[1])); + // m_pValue.append(gsl_cdf_gaussian_P(m_statisticValue, sp)); + break; + } + case HypothesisTest::Test::Type::Anova: + case HypothesisTest::Test::Type::NoneType: + break; + } + + m_currTestName = "

" + i18n("Two Sample Independent %1 Test for %2 vs %3", testName, col1Name, col2Name) + "

"; + m_pValue.append(getPValue(test, m_statisticValue[0], col1Name, col2Name, (mean[0] - mean[1]), sqrt(spSq), df)); + + printLine(2, i18n("Significance level is %1", round(m_significanceLevel)), "blue"); + + printLine(4, i18n("%1 Value is %2 ", testName, round(m_statisticValue[0])), "green"); + printTooltip(4, i18n("More is the |%1-value|, more safely we can reject the null hypothesis", testName)); + + printLine(5, i18n("P Value is %1 ", m_pValue[0]), "green"); + + printLine(6, i18n("Degree of Freedom is %1", df), "green"); + printTooltip(6, i18n("Number of independent Pieces of information that went into calculating the estimate")); + + if (m_pValue[0] <= m_significanceLevel) + printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", round(m_significanceLevel))); + else + printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); + return; } /********************************Two Sample Paired ***************************************/ void HypothesisTest::performTwoSamplePairedTest(HypothesisTest::Test::Type test) { - if (m_columns.size() != 2) { - printError("Inappropriate number of m_columns selected"); - - return; - } - - for (int i = 0; i < 2; i++) { - if ( !m_columns[0]->isNumeric()) { - printError("select only m_columns with numbers"); - return; - } - } - - int n; - double sum, mean, std; - ErrorType errorCode = findStatsPaired(m_columns[0], m_columns[1], n, sum, mean, std); - - switch (errorCode) { - case ErrorUnqualSize: { - printError("both m_columns are having different sizes"); - - return; - } - case ErrorEmptyColumn: { - printError("m_columns are empty"); - return; - } - case NoError: - break; - } - - - QVariant rowMajor[] = {"", "N", "Sum", "Mean", "Std", - "difference", n, sum, mean, std - }; - - m_statsTable = getHtmlTable(2, 5, rowMajor); - - if (std == 0.0) { - printError("Standard deviation of the difference is 0"); - return; - } - - - QString testName; - int df = 0; - - switch (test) { - case HypothesisTest::Test::Type::TTest: { - m_statisticValue[0] = mean / (std / sqrt(n)); - df = n - 1; - testName = "T"; - printLine(6, i18n("Degree of Freedom is %1name(), i18n("%1", m_populationMean), mean, std, df)); - m_currTestName = "

" + i18n("One Sample %1 Test for %2 vs %3", testName, m_columns[0]->name(), m_columns[1]->name()) + "

"; - - printLine(2, i18n("Significance level is %1 ", round(m_significanceLevel)), "blue"); - printLine(4, i18n("%1 Value is %2 ", testName, round(m_statisticValue[0])), "green"); - printLine(5, i18n("P Value is %1 ", m_pValue[0]), "green"); - - if (m_pValue[0] <= m_significanceLevel) - printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); - else - printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); - - return; + if (m_columns.size() != 2) { + printError("Inappropriate number of m_columns selected"); + + return; + } + + for (int i = 0; i < 2; i++) { + if ( !m_columns[0]->isNumeric()) { + printError("select only m_columns with numbers"); + return; + } + } + + int n; + double sum, mean, std; + ErrorType errorCode = findStatsPaired(m_columns[0], m_columns[1], n, sum, mean, std); + + switch (errorCode) { + case ErrorUnqualSize: { + printError("both m_columns are having different sizes"); + + return; + } + case ErrorEmptyColumn: { + printError("m_columns are empty"); + return; + } + case NoError: + break; + } + + QVariant rowMajor[] = {"", "N", "Sum", "Mean", "Std", + "difference", n, sum, mean, std + }; + + m_statsTable = getHtmlTable(2, 5, rowMajor); + + if (std == 0.0) { + printError("Standard deviation of the difference is 0"); + return; + } + + + QString testName; + int df = 0; + + switch (test) { + case HypothesisTest::Test::Type::TTest: { + m_statisticValue[0] = mean / (std / sqrt(n)); + df = n - 1; + testName = "T"; + printLine(6, i18n("Degree of Freedom is %1name(), i18n("%1", m_populationMean), mean, std, df)); + m_currTestName = "

" + i18n("One Sample %1 Test for %2 vs %3", testName, m_columns[0]->name(), m_columns[1]->name()) + "

"; + + printLine(2, i18n("Significance level is %1 ", round(m_significanceLevel)), "blue"); + printLine(4, i18n("%1 Value is %2 ", testName, round(m_statisticValue[0])), "green"); + printLine(5, i18n("P Value is %1 ", m_pValue[0]), "green"); + + if (m_pValue[0] <= m_significanceLevel) + printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); + else + printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); + + return; } /******************************** One Sample ***************************************/ void HypothesisTest::performOneSampleTest(HypothesisTest::Test::Type test) { - if (m_columns.size() != 1) { - printError("Inappropriate number of m_columns selected"); - - return; - } - - if ( !m_columns[0]->isNumeric()) { - printError("select only m_columns with numbers"); - - return; - } - - int n; - double sum, mean, std; - ErrorType errorCode = findStats(m_columns[0], n, sum, mean, std); - - switch (errorCode) { - case ErrorEmptyColumn: { - printError("column is empty"); - return; - } - case NoError: - break; - case ErrorUnqualSize: { - return; - } - } - - QVariant rowMajor[] = {"", "N", "Sum", "Mean", "Std", - m_columns[0]->name(), n, sum, mean, std - }; - - m_statsTable = getHtmlTable(2, 5, rowMajor); - - if (std == 0.0) { - printError("Standard deviation is 0"); - return; - } - - - QString testName; - int df = 0; - - switch (test) { - case HypothesisTest::Test::Type::TTest: { - testName = "T"; - m_statisticValue.append((mean - m_populationMean) / (std / sqrt(n))); - df = n - 1; - printLine(6, i18n("Degree of Freedom is %1", df), "blue"); - break; - } - case HypothesisTest::Test::Type::ZTest: { - testName = "Z"; - df = 0; - m_statisticValue.append((mean - m_populationMean) / (std / sqrt(n))); - break; - } - case HypothesisTest::Test::Type::Anova: - case HypothesisTest::Test::Type::NoneType: - break; - } - - m_pValue.append(getPValue(test, m_statisticValue[0], m_columns[0]->name(), i18n("%1",m_populationMean), mean - m_populationMean, std, df)); - m_currTestName = "

" + i18n("One Sample %1 Test for %2", testName, m_columns[0]->name()) + "

"; - - printLine(2, i18n("Significance level is %1", round(m_significanceLevel)), "blue"); - printLine(4, i18n("%1 Value is %2", testName, round(m_statisticValue[0])), "green"); - printLine(5, i18n("P Value is %1", m_pValue[0]), "green"); - - if (m_pValue[0] <= m_significanceLevel) - printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); - else - printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); - - return; + if (m_columns.size() != 1) { + printError("Inappropriate number of m_columns selected"); + + return; + } + + if ( !m_columns[0]->isNumeric()) { + printError("select only m_columns with numbers"); + + return; + } + + int n; + double sum, mean, std; + ErrorType errorCode = findStats(m_columns[0], n, sum, mean, std); + + switch (errorCode) { + case ErrorEmptyColumn: { + printError("column is empty"); + return; + } + case NoError: + break; + case ErrorUnqualSize: { + return; + } + } + + QVariant rowMajor[] = {"", "N", "Sum", "Mean", "Std", + m_columns[0]->name(), n, sum, mean, std + }; + + m_statsTable = getHtmlTable(2, 5, rowMajor); + + if (std == 0.0) { + printError("Standard deviation is 0"); + return; + } + + + QString testName; + int df = 0; + + switch (test) { + case HypothesisTest::Test::Type::TTest: { + testName = "T"; + m_statisticValue.append((mean - m_populationMean) / (std / sqrt(n))); + df = n - 1; + printLine(6, i18n("Degree of Freedom is %1", df), "blue"); + break; + } + case HypothesisTest::Test::Type::ZTest: { + testName = "Z"; + df = 0; + m_statisticValue.append((mean - m_populationMean) / (std / sqrt(n))); + break; + } + case HypothesisTest::Test::Type::Anova: + case HypothesisTest::Test::Type::NoneType: + break; + } + + m_pValue.append(getPValue(test, m_statisticValue[0], m_columns[0]->name(), i18n("%1",m_populationMean), mean - m_populationMean, std, df)); + m_currTestName = "

" + i18n("One Sample %1 Test for %2", testName, m_columns[0]->name()) + "

"; + + printLine(2, i18n("Significance level is %1", round(m_significanceLevel)), "blue"); + printLine(4, i18n("%1 Value is %2", testName, round(m_statisticValue[0])), "green"); + printLine(5, i18n("P Value is %1", m_pValue[0]), "green"); + + if (m_pValue[0] <= m_significanceLevel) + printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); + else + printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); + + return; } /*************************************One Way Anova***************************************/ // all standard variables and formulas are taken from this wikipedia page: // https://en.wikipedia.org/wiki/One-way_analysis_of_variance // b stands for b/w groups // w stands for within groups // np is number of partition i.e., number of classes void HypothesisTest::performOneWayAnova() { - int np, totalRows; - countPartitions(m_columns[0], np, totalRows); - - int* ni = new int[np]; - double* sum = new double[np]; - double* mean = new double[np]; - double* std = new double[np]; - QString* colNames = new QString[np]; - - QMap classnameToIndex; - QString baseColName; - - if (m_columns[0]->isNumeric()) - baseColName = m_columns[0]->name(); - - findStatsCategorical(m_columns[0], m_columns[1], ni, sum, mean, std, classnameToIndex, np, totalRows); - - double yBar = 0; // overall mean - double sB = 0; // sum of squares of (mean - overall_mean) between the groups - int fB = 0; // degree of freedom between the groups - double msB = 0; // mean sum of squares between the groups - double sW = 0; // sum of squares of (value - mean of group) within the groups - int fW = 0; // degree of freedom within the group - double msW = 0; // mean sum of squares within the groups - - // now finding mean of each group; - - for (int i = 0; i < np; i++) - yBar += mean[i]; - yBar = yBar / np; - - for (int i = 0; i < np; i++) { - sB += ni[i] * gsl_pow_2( ( mean[i] - yBar)); - if (ni[i] > 1) - sW += gsl_pow_2( std[i])*(ni[i] - 1); - else - sW += gsl_pow_2( std[i]); - fW += ni[i] - 1; - } - - fB = np - 1; - msB = sB / fB; - - msW = sW / fW; - m_statisticValue.append(msB / msW); - - - m_pValue.append(nsl_stats_fdist_p(m_statisticValue[0], static_cast(np-1), fW)); - - QMapIterator i(classnameToIndex); - while (i.hasNext()) { - i.next(); - colNames[i.value()-1] = baseColName + " " + i.key(); - } - - // now printing the statistics and result; - int rowCount = np + 1, columnCount = 5; - QVariant* rowMajor = new QVariant[rowCount*columnCount]; - // header data; - rowMajor[0] = ""; - rowMajor[1] = "Ni"; - rowMajor[2] = "Sum"; - rowMajor[3] = "Mean"; - rowMajor[4] = "Std"; - - // table data - for (int row_i = 1; row_i < rowCount ; row_i++) { - rowMajor[row_i*columnCount] = colNames[row_i - 1]; - rowMajor[row_i*columnCount + 1] = ni[row_i - 1]; - rowMajor[row_i*columnCount + 2] = sum[row_i - 1]; - rowMajor[row_i*columnCount + 3] = mean[row_i - 1]; - rowMajor[row_i*columnCount + 4] = std[row_i - 1]; - } - - m_statsTable = "

" + i18n("Group Summary Statistics") + "

"; - - m_statsTable += getHtmlTable(rowCount, columnCount, rowMajor); - - m_statsTable += getLine(""); - m_statsTable += getLine(""); - m_statsTable += "

" + i18n("Grand Summary Statistics") + "

"; - m_statsTable += getLine(""); - m_statsTable += getLine(i18n("Overall Mean is %1", round(yBar))); - - rowCount = 4; - columnCount = 3; - rowMajor->clear(); - - rowMajor[0] = ""; - rowMajor[1] = "Between Groups"; - rowMajor[2] = "Within Groups"; - - int baseIndex = 0; - baseIndex = 1 * columnCount; - rowMajor[baseIndex + 0] = "Sum of Squares"; - rowMajor[baseIndex + 1] = sB; - rowMajor[baseIndex + 2] = sW; - baseIndex = 2 * columnCount; - rowMajor[baseIndex + 0] = "Degree of Freedom"; - rowMajor[baseIndex + 1] = fB; - rowMajor[baseIndex + 2] = fW; - baseIndex = 3 * columnCount; - rowMajor[baseIndex + 0] = "Mean Square Value"; - rowMajor[baseIndex + 1] = msB; - rowMajor[baseIndex + 2] = msW; - - m_statsTable += getHtmlTable(rowCount, columnCount, rowMajor); - - delete[] ni; - delete[] sum; - delete[] mean; - delete[] std; - delete[] colNames; - - printLine(1, i18n("F Value is %1", round(m_statisticValue[0])), "green"); - printLine(2, i18n("P Value is %1 ", m_pValue[0]), "green"); - - if (m_pValue[0] <= m_significanceLevel) - printTooltip(2, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); - else - printTooltip(2, i18n("There is a plausibility for Null Hypothesis to be true")); - - return; + int np, totalRows; + countPartitions(m_columns[0], np, totalRows); + + int* ni = new int[np]; + double* sum = new double[np]; + double* mean = new double[np]; + double* std = new double[np]; + QString* colNames = new QString[np]; + + QMap classnameToIndex; + QString baseColName; + + if (m_columns[0]->isNumeric()) + baseColName = m_columns[0]->name(); + + findStatsCategorical(m_columns[0], m_columns[1], ni, sum, mean, std, classnameToIndex, np, totalRows); + + double yBar = 0; // overall mean + double sB = 0; // sum of squares of (mean - overall_mean) between the groups + int fB = 0; // degree of freedom between the groups + double msB = 0; // mean sum of squares between the groups + double sW = 0; // sum of squares of (value - mean of group) within the groups + int fW = 0; // degree of freedom within the group + double msW = 0; // mean sum of squares within the groups + + // now finding mean of each group; + + for (int i = 0; i < np; i++) + yBar += mean[i]; + yBar = yBar / np; + + for (int i = 0; i < np; i++) { + sB += ni[i] * gsl_pow_2( ( mean[i] - yBar)); + if (ni[i] > 1) + sW += gsl_pow_2( std[i])*(ni[i] - 1); + else + sW += gsl_pow_2( std[i]); + fW += ni[i] - 1; + } + + fB = np - 1; + msB = sB / fB; + + msW = sW / fW; + m_statisticValue.append(msB / msW); + + + m_pValue.append(nsl_stats_fdist_p(m_statisticValue[0], static_cast(np-1), fW)); + + QMapIterator i(classnameToIndex); + while (i.hasNext()) { + i.next(); + colNames[i.value()-1] = baseColName + " " + i.key(); + } + + // now printing the statistics and result; + int rowCount = np + 1, columnCount = 5; + QVariant* rowMajor = new QVariant[rowCount*columnCount]; + // header data; + rowMajor[0] = ""; + rowMajor[1] = "Ni"; + rowMajor[2] = "Sum"; + rowMajor[3] = "Mean"; + rowMajor[4] = "Std"; + + // table data + for (int row_i = 1; row_i < rowCount ; row_i++) { + rowMajor[row_i*columnCount] = colNames[row_i - 1]; + rowMajor[row_i*columnCount + 1] = ni[row_i - 1]; + rowMajor[row_i*columnCount + 2] = sum[row_i - 1]; + rowMajor[row_i*columnCount + 3] = mean[row_i - 1]; + rowMajor[row_i*columnCount + 4] = std[row_i - 1]; + } + + m_statsTable = "

" + i18n("Group Summary Statistics") + "

"; + + m_statsTable += getHtmlTable(rowCount, columnCount, rowMajor); + + m_statsTable += getLine(""); + m_statsTable += getLine(""); + m_statsTable += "

" + i18n("Grand Summary Statistics") + "

"; + m_statsTable += getLine(""); + m_statsTable += getLine(i18n("Overall Mean is %1", round(yBar))); + + rowCount = 4; + columnCount = 3; + rowMajor->clear(); + + rowMajor[0] = ""; + rowMajor[1] = "Between Groups"; + rowMajor[2] = "Within Groups"; + + int baseIndex = 0; + baseIndex = 1 * columnCount; + rowMajor[baseIndex + 0] = "Sum of Squares"; + rowMajor[baseIndex + 1] = sB; + rowMajor[baseIndex + 2] = sW; + baseIndex = 2 * columnCount; + rowMajor[baseIndex + 0] = "Degree of Freedom"; + rowMajor[baseIndex + 1] = fB; + rowMajor[baseIndex + 2] = fW; + baseIndex = 3 * columnCount; + rowMajor[baseIndex + 0] = "Mean Square Value"; + rowMajor[baseIndex + 1] = msB; + rowMajor[baseIndex + 2] = msW; + + m_statsTable += getHtmlTable(rowCount, columnCount, rowMajor); + + delete[] ni; + delete[] sum; + delete[] mean; + delete[] std; + delete[] colNames; + + printLine(1, i18n("F Value is %1", round(m_statisticValue[0])), "green"); + printLine(2, i18n("P Value is %1 ", m_pValue[0]), "green"); + + if (m_pValue[0] <= m_significanceLevel) + printTooltip(2, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); + else + printTooltip(2, i18n("There is a plausibility for Null Hypothesis to be true")); + + return; } /*************************************Two Way Anova***************************************/ // all formulas and symbols are taken from: http://statweb.stanford.edu/~susan/courses/s141/exanova.pdf //TODO: suppress warning of variable length array are a C99 feature. //TODO: add assumptions verification option //TODO: add tail option (if needed) void HypothesisTest::performTwoWayAnova() { - int np_a, totalRows_a; - int np_b, totalRows_b; - countPartitions(m_columns[0], np_a, totalRows_a); - countPartitions(m_columns[1], np_b, totalRows_b); - - QVector> groupMean(np_a, QVector(np_b)); - QVector> replicates(np_a, QVector(np_b)); - - for (int i = 0; i < np_a; i++) - for (int j = 0; j < np_b; j++) { - groupMean[i][j] = 0; - replicates[i][j] = 0; - } - - if (totalRows_a != totalRows_b) { - printError("There is missing data in at least one of the rows"); - return; - } - - QMap catToNumber_a; - QMap catToNumber_b; - - int partitionNumber_a = 1; - int partitionNumber_b = 1; - for (int i = 0; i < totalRows_a; i++) { - QString name_a = m_columns[0]->textAt(i); - QString name_b = m_columns[1]->textAt(i); - double value = m_columns[2]->valueAt(i); - - if (catToNumber_a[name_a] == 0) { - catToNumber_a[name_a] = partitionNumber_a; - partitionNumber_a++; - } - - if (catToNumber_b[name_b] == 0) { - catToNumber_b[name_b] = partitionNumber_b; - partitionNumber_b++; - } - - groupMean[catToNumber_a[name_a] - 1][catToNumber_b[name_b] - 1] += value; - replicates[catToNumber_a[name_a] - 1][catToNumber_b[name_b] - 1] += 1; - } - - int replicate = replicates[0][0]; - for (int i = 0; i < np_a; i++) - for (int j = 0; j < np_b; j++) { - if (replicates[i][j] == 0) { - printError("Dataset should have at least one data value corresponding to each feature combination"); - return; - } - if (replicates[i][j] != replicate) { - printError("Number of experiments perfomed for each combination of levels
" - "between Independet Var.1 and Independent Var.2 must be equal"); - return; - } - groupMean[i][j] /= replicates[i][j]; - } - - double ss_within = 0; - for (int i = 0; i < totalRows_a; i++) { - QString name_a = m_columns[0]->textAt(i); - QString name_b = m_columns[1]->textAt(i); - double value = m_columns[2]->valueAt(i); - - ss_within += gsl_pow_2(value - groupMean[catToNumber_a[name_a] - 1][catToNumber_b[name_b] - 1]); - } - - int df_within = (replicate - 1) * np_a * np_b; - double ms_within = ss_within / df_within; - - double* mean_a = new double[np_a]; - double* mean_b = new double[np_b]; - for (int i = 0; i < np_a; i++) { - for (int j = 0; j < np_b; j++) { - mean_a[i] += groupMean[i][j] / np_b; - mean_b[j] += groupMean[i][j] / np_a; - } - } - - double mean = 0; - for (int i = 0; i < np_a; i++) - mean += mean_a[i] / np_a; - - - double ss_a = 0; - for (int i = 0; i < np_a; i++) - ss_a += gsl_pow_2(mean_a[i] - mean); - ss_a *= replicate * np_b; - - int df_a = np_a - 1; - double ms_a = ss_a / df_a; - - double ss_b = 0; - for (int i = 0; i < np_b; i++) - ss_b += gsl_pow_2(mean_b[i] - mean); - ss_b *= replicate * np_a; - - int df_b = np_b - 1; - double ms_b = ss_b / df_b; - - double ss_interaction = 0; - - for (int i = 0; i < np_a; i++) - for (int j = 0; j < np_b; j++) - ss_interaction += gsl_pow_2(groupMean[i][j] - mean_a[i] - mean_b[j] + mean); - - ss_interaction *= replicate; - int df_interaction = (np_a - 1) * (np_b - 1); - double ms_interaction = ss_interaction / df_interaction; - - QString* partitionNames_a = new QString[np_a]; - QString* partitionNames_b = new QString[np_b]; - - QMapIterator itr_a(catToNumber_a); - while (itr_a.hasNext()) { - itr_a.next(); - partitionNames_a[itr_a.value()-1] = itr_a.key(); - } - - QMapIterator itr_b(catToNumber_b); - while (itr_b.hasNext()) { - itr_b.next(); - partitionNames_b[itr_b.value()-1] = itr_b.key(); - } - - // printing table; - // cell constructor structure; data, level, rowSpanCount, m_columnspanCount, isHeader; - QList rowMajor; - rowMajor.append(new Cell("", 0, true, "", 2, 1)); - for (int i = 0; i < np_b; i++) - rowMajor.append(new Cell(partitionNames_b[i], 0, true, "", 1, 2)); - rowMajor.append(new Cell("Mean", 0, true, "", 2)); - - for (int i = 0; i < np_b; i++) { - rowMajor.append(new Cell("Mean", 1, true)); - rowMajor.append(new Cell("Replicate", 1, true)); - } - - int level = 2; - for (int i = 0; i < np_a; i++) { - rowMajor.append(new Cell(partitionNames_a[i], level, true)); - for (int j = 0; j < np_b; j++) { - rowMajor.append(new Cell(round(groupMean[i][j]), level)); - rowMajor.append(new Cell(replicates[i][j], level)); - } - rowMajor.append(new Cell(round(mean_a[i]), level)); - level++; - } - - rowMajor.append(new Cell("Mean", level, true)); - for (int i = 0; i < np_b; i++) - rowMajor.append(new Cell(round(mean_b[i]), level, false, "", 1, 2)); - rowMajor.append(new Cell(round(mean), level)); - - m_statsTable = "

" + i18n("Contingency Table") + "

"; - m_statsTable += getHtmlTable3(rowMajor); - - m_statsTable += "
"; - m_statsTable += "

" + i18n("results table") + "

"; - - rowMajor.clear(); - level = 0; - rowMajor.append(new Cell("", level, true)); - rowMajor.append(new Cell("SS", level, true)); - rowMajor.append(new Cell("DF", level, true, "degree of freedom")); - rowMajor.append(new Cell("MS", level, true)); - - level++; - rowMajor.append(new Cell(m_columns[0]->name(), level, true)); - rowMajor.append(new Cell(round(ss_a), level)); - rowMajor.append(new Cell(df_a, level)); - rowMajor.append(new Cell(round(ms_a), level)); - - level++; - rowMajor.append(new Cell(m_columns[1]->name(), level, true)); - rowMajor.append(new Cell(round(ss_b), level)); - rowMajor.append(new Cell(df_b, level)); - rowMajor.append(new Cell(round(ms_b), level)); - - level++; - rowMajor.append(new Cell("Interaction", level, true)); - rowMajor.append(new Cell(round(ss_interaction), level)); - rowMajor.append(new Cell(df_interaction, level)); - rowMajor.append(new Cell(round(ms_interaction), level)); - - level++; - rowMajor.append(new Cell("Within", level, true)); - rowMajor.append(new Cell(round(ss_within), level)); - rowMajor.append(new Cell(df_within, level)); - rowMajor.append(new Cell(round(ms_within), level)); - - m_statsTable += getHtmlTable3(rowMajor); - - double fValue_a = ms_a / ms_within; - double fValue_b = ms_b / ms_within; - double fValue_interaction = ms_interaction / ms_within; - - double m_pValue_a = nsl_stats_fdist_p(fValue_a, static_cast(np_a - 1), df_a); - double m_pValue_b = nsl_stats_fdist_p(fValue_b, static_cast(np_b - 1), df_b); - - printLine(0, "F(df" + m_columns[0]->name() + ", dfwithin) is " + round(fValue_a), "blue"); - printLine(1, "F(df" + m_columns[1]->name() + ", dfwithin) is " + round(fValue_b), "blue"); - printLine(2, "F(dfinteraction, dfwithin) is " + round(fValue_interaction), "blue"); - - printLine(4, "P(df" + m_columns[0]->name() + ", dfwithin) is " + round(m_pValue_a), "blue"); - printLine(5, "P(df" + m_columns[1]->name() + ", dfwithin) is " + round(m_pValue_b), "blue"); - // printLine(2, "P(dfinteraction, dfwithin) is " + round(fValue_interaction), "blue"); - - m_statisticValue.append(fValue_a); - m_statisticValue.append(fValue_b); - m_statisticValue.append(fValue_interaction); - - m_pValue.append(m_pValue_a); - m_pValue.append(m_pValue_b); - - delete[] mean_a; - delete[] mean_b; - delete[] partitionNames_a; - delete[] partitionNames_b; - - return; + int np_a, totalRows_a; + int np_b, totalRows_b; + countPartitions(m_columns[0], np_a, totalRows_a); + countPartitions(m_columns[1], np_b, totalRows_b); + + QVector> groupMean(np_a, QVector(np_b)); + QVector> replicates(np_a, QVector(np_b)); + + for (int i = 0; i < np_a; i++) + for (int j = 0; j < np_b; j++) { + groupMean[i][j] = 0; + replicates[i][j] = 0; + } + + if (totalRows_a != totalRows_b) { + printError("There is missing data in at least one of the rows"); + return; + } + + QMap catToNumber_a; + QMap catToNumber_b; + + int partitionNumber_a = 1; + int partitionNumber_b = 1; + for (int i = 0; i < totalRows_a; i++) { + QString name_a = m_columns[0]->textAt(i); + QString name_b = m_columns[1]->textAt(i); + double value = m_columns[2]->valueAt(i); + + if (catToNumber_a[name_a] == 0) { + catToNumber_a[name_a] = partitionNumber_a; + partitionNumber_a++; + } + + if (catToNumber_b[name_b] == 0) { + catToNumber_b[name_b] = partitionNumber_b; + partitionNumber_b++; + } + + groupMean[catToNumber_a[name_a] - 1][catToNumber_b[name_b] - 1] += value; + replicates[catToNumber_a[name_a] - 1][catToNumber_b[name_b] - 1] += 1; + } + + int replicate = replicates[0][0]; + for (int i = 0; i < np_a; i++) + for (int j = 0; j < np_b; j++) { + if (replicates[i][j] == 0) { + printError("Dataset should have at least one data value corresponding to each feature combination"); + return; + } + if (replicates[i][j] != replicate) { + printError("Number of experiments perfomed for each combination of levels
" + "between Independet Var.1 and Independent Var.2 must be equal"); + return; + } + groupMean[i][j] /= replicates[i][j]; + } + + double ss_within = 0; + for (int i = 0; i < totalRows_a; i++) { + QString name_a = m_columns[0]->textAt(i); + QString name_b = m_columns[1]->textAt(i); + double value = m_columns[2]->valueAt(i); + + ss_within += gsl_pow_2(value - groupMean[catToNumber_a[name_a] - 1][catToNumber_b[name_b] - 1]); + } + + int df_within = (replicate - 1) * np_a * np_b; + double ms_within = ss_within / df_within; + + double* mean_a = new double[np_a]; + double* mean_b = new double[np_b]; + for (int i = 0; i < np_a; i++) { + for (int j = 0; j < np_b; j++) { + mean_a[i] += groupMean[i][j] / np_b; + mean_b[j] += groupMean[i][j] / np_a; + } + } + + double mean = 0; + for (int i = 0; i < np_a; i++) + mean += mean_a[i] / np_a; + + + double ss_a = 0; + for (int i = 0; i < np_a; i++) + ss_a += gsl_pow_2(mean_a[i] - mean); + ss_a *= replicate * np_b; + + int df_a = np_a - 1; + double ms_a = ss_a / df_a; + + double ss_b = 0; + for (int i = 0; i < np_b; i++) + ss_b += gsl_pow_2(mean_b[i] - mean); + ss_b *= replicate * np_a; + + int df_b = np_b - 1; + double ms_b = ss_b / df_b; + + double ss_interaction = 0; + + for (int i = 0; i < np_a; i++) + for (int j = 0; j < np_b; j++) + ss_interaction += gsl_pow_2(groupMean[i][j] - mean_a[i] - mean_b[j] + mean); + + ss_interaction *= replicate; + int df_interaction = (np_a - 1) * (np_b - 1); + double ms_interaction = ss_interaction / df_interaction; + + QString* partitionNames_a = new QString[np_a]; + QString* partitionNames_b = new QString[np_b]; + + QMapIterator itr_a(catToNumber_a); + while (itr_a.hasNext()) { + itr_a.next(); + partitionNames_a[itr_a.value()-1] = itr_a.key(); + } + + QMapIterator itr_b(catToNumber_b); + while (itr_b.hasNext()) { + itr_b.next(); + partitionNames_b[itr_b.value()-1] = itr_b.key(); + } + + // printing table; + // cell constructor structure; data, level, rowSpanCount, m_columnspanCount, isHeader; + QList rowMajor; + rowMajor.append(new Cell("", 0, true, "", 2, 1)); + for (int i = 0; i < np_b; i++) + rowMajor.append(new Cell(partitionNames_b[i], 0, true, "", 1, 2)); + rowMajor.append(new Cell("Mean", 0, true, "", 2)); + + for (int i = 0; i < np_b; i++) { + rowMajor.append(new Cell("Mean", 1, true)); + rowMajor.append(new Cell("Replicate", 1, true)); + } + + int level = 2; + for (int i = 0; i < np_a; i++) { + rowMajor.append(new Cell(partitionNames_a[i], level, true)); + for (int j = 0; j < np_b; j++) { + rowMajor.append(new Cell(round(groupMean[i][j]), level)); + rowMajor.append(new Cell(replicates[i][j], level)); + } + rowMajor.append(new Cell(round(mean_a[i]), level)); + level++; + } + + rowMajor.append(new Cell("Mean", level, true)); + for (int i = 0; i < np_b; i++) + rowMajor.append(new Cell(round(mean_b[i]), level, false, "", 1, 2)); + rowMajor.append(new Cell(round(mean), level)); + + m_statsTable = "

" + i18n("Contingency Table") + "

"; + m_statsTable += getHtmlTable3(rowMajor); + + m_statsTable += "
"; + m_statsTable += "

" + i18n("results table") + "

"; + + rowMajor.clear(); + level = 0; + rowMajor.append(new Cell("", level, true)); + rowMajor.append(new Cell("SS", level, true)); + rowMajor.append(new Cell("DF", level, true, "degree of freedom")); + rowMajor.append(new Cell("MS", level, true)); + + level++; + rowMajor.append(new Cell(m_columns[0]->name(), level, true)); + rowMajor.append(new Cell(round(ss_a), level)); + rowMajor.append(new Cell(df_a, level)); + rowMajor.append(new Cell(round(ms_a), level)); + + level++; + rowMajor.append(new Cell(m_columns[1]->name(), level, true)); + rowMajor.append(new Cell(round(ss_b), level)); + rowMajor.append(new Cell(df_b, level)); + rowMajor.append(new Cell(round(ms_b), level)); + + level++; + rowMajor.append(new Cell("Interaction", level, true)); + rowMajor.append(new Cell(round(ss_interaction), level)); + rowMajor.append(new Cell(df_interaction, level)); + rowMajor.append(new Cell(round(ms_interaction), level)); + + level++; + rowMajor.append(new Cell("Within", level, true)); + rowMajor.append(new Cell(round(ss_within), level)); + rowMajor.append(new Cell(df_within, level)); + rowMajor.append(new Cell(round(ms_within), level)); + + m_statsTable += getHtmlTable3(rowMajor); + + double fValue_a = ms_a / ms_within; + double fValue_b = ms_b / ms_within; + double fValue_interaction = ms_interaction / ms_within; + + double m_pValue_a = nsl_stats_fdist_p(fValue_a, static_cast(np_a - 1), df_a); + double m_pValue_b = nsl_stats_fdist_p(fValue_b, static_cast(np_b - 1), df_b); + + printLine(0, "F(df" + m_columns[0]->name() + ", dfwithin) is " + round(fValue_a), "blue"); + printLine(1, "F(df" + m_columns[1]->name() + ", dfwithin) is " + round(fValue_b), "blue"); + printLine(2, "F(dfinteraction, dfwithin) is " + round(fValue_interaction), "blue"); + + printLine(4, "P(df" + m_columns[0]->name() + ", dfwithin) is " + round(m_pValue_a), "blue"); + printLine(5, "P(df" + m_columns[1]->name() + ", dfwithin) is " + round(m_pValue_b), "blue"); + // printLine(2, "P(dfinteraction, dfwithin) is " + round(fValue_interaction), "blue"); + + m_statisticValue.append(fValue_a); + m_statisticValue.append(fValue_b); + m_statisticValue.append(fValue_interaction); + + m_pValue.append(m_pValue_a); + m_pValue.append(m_pValue_b); + + delete[] mean_a; + delete[] mean_b; + delete[] partitionNames_a; + delete[] partitionNames_b; + + return; } /**************************************Levene Test****************************************/ // Some reference to local variables. // np = number of partitions // df = degree of fredom // totalRows = total number of rows in column // these variables are taken from: https://en.wikipedia.org/wiki/Levene%27s_test // yiBar = mean of ith group; // Zij = |Yij - yiBar| // ziBar = mean of Zij for group i // ziBarBar = mean for all zij // ni = number of elements in group i void HypothesisTest::m_performLeveneTest(bool categoricalVariable) { - if (m_columns.size() != 2) { - printError("Inappropriate number of m_columns selected"); - return; - } - - int np = 0; - int n = 0; - - if (!categoricalVariable && m_columns[0]->isNumeric()) - np = m_columns.size(); - else - countPartitions(m_columns[0], np, n); - - if (np < 2) { - printError("Select at least two m_columns / classes"); - return; - } - - double* yiBar = new double[np]; - double* ziBar = new double[np]; - double ziBarBar = 0; - double* ni = new double[np]; - - for (int i = 0; i < np; i++) { - yiBar[i] = 0; - ziBar[i] = 0; - ni[i] = 0; - } - - double fValue; - int df = 0; - - int totalRows = 0; - - QString* colNames = new QString[np]; - if (!categoricalVariable && m_columns[0]->isNumeric()) { - totalRows = m_columns[0]->rowCount(); - - double value = 0; - for (int j = 0; j < totalRows; j++) { - int numberNaNCols = 0; - for (int i = 0; i < np; i++) { - value = m_columns[i]->valueAt(j); - if (std::isnan(value)) { - numberNaNCols++; - continue; - } - yiBar[i] += value; - ni[i]++; - n++; - } - if (numberNaNCols == np) { - totalRows = j; - break; - } - } - - for (int i = 0; i < np; i++) { - if (ni[i] > 0) - yiBar[i] = yiBar[i] / ni[i]; - else { - printError("One of the selected m_columns is empty
" - "or have choosen Independent Var.1 wrongly"); - return; - } - } - - for (int j = 0; j < totalRows; j++) { - for (int i = 0; i < np; i++) { - value = m_columns[i]->valueAt(j); - if (!(std::isnan(value))) - ziBar[i] += fabs(value - yiBar[i]); - } - } - - for (int i = 0; i < np; i++) { - ziBarBar += ziBar[i]; - if (ni[i] > 0) - ziBar[i] = ziBar[i] / ni[i]; - } - - ziBarBar = ziBarBar / n; - - double numberatorValue = 0; - double denominatorValue = 0; - - for (int j = 0; j < totalRows; j++) { - for (int i = 0; i < np; i++) { - value = m_columns[i]->valueAt(j); - if (!(std::isnan(value))) { - double zij = fabs(value - yiBar[i]); - denominatorValue += gsl_pow_2( (zij - ziBar[i])); - } - } - } - - - if (denominatorValue == 0.0) { - printError( i18n("Denominator value is %1", denominatorValue)); - return; - } - - for (int i = 0; i < np; i++) { - colNames[i] = m_columns[i]->name(); - numberatorValue += ni[i]*gsl_pow_2( (ziBar[i]-ziBarBar)); - } - - fValue = ((n - np) / (np - 1)) * (numberatorValue / denominatorValue); - - } else { - QMap classnameToIndex; - - AbstractColumn::ColumnMode originalColMode = m_columns[0]->columnMode(); - m_columns[0]->setColumnMode(AbstractColumn::Text); - - int partitionNumber = 1; - QString name; - double value; - int classIndex; - - for (int j = 0; j < n; j++) { - name = m_columns[0]->textAt(j); - value = m_columns[1]->valueAt(j); - if (std::isnan(value)) { - n = j; - break; - } - - if (classnameToIndex[name] == 0) { - classnameToIndex[name] = partitionNumber; - partitionNumber++; - } - - classIndex = classnameToIndex[name]-1; - ni[classIndex]++; - yiBar[classIndex] += value; - } - - for (int i = 0; i < np; i++) { - if (ni[i] > 0) - yiBar[i] = yiBar[i] / ni[i]; - else { - printError("One of the selected m_columns is empty
" - "or have choosen Independent Var.1 wrongly"); - m_columns[0]->setColumnMode(originalColMode); - return; - } - } - - for (int j = 0; j < n; j++) { - name = m_columns[0]->textAt(j); - value = m_columns[1]->valueAt(j); - classIndex = classnameToIndex[name] - 1; - ziBar[classIndex] += fabs(value - yiBar[classIndex]); - } - - for (int i = 0; i < np; i++) { - ziBarBar += ziBar[i]; - ziBar[i] = ziBar[i] / ni[i]; - } - - ziBarBar = ziBarBar / n; - - double numberatorValue = 0; - double denominatorValue = 0; - - for (int j = 0; j < n; j++) { - name = m_columns[0]->textAt(j); - value = m_columns[1]->valueAt(j); - classIndex = classnameToIndex[name] - 1; - double zij = fabs(value - yiBar[classIndex]); - denominatorValue += gsl_pow_2( (zij - ziBar[classIndex])); - } - - for (int i = 0; i < np; i++) - numberatorValue += ni[i]*gsl_pow_2( (ziBar[i]-ziBarBar)); - - if (denominatorValue == 0.0) { - printError( "number of data points is less or than equal to number of categorical variables"); - m_columns[0]->setColumnMode(originalColMode); - return; - } - - fValue = ((n - np) / (np - 1)) * (numberatorValue / denominatorValue); - - QMapIterator i(classnameToIndex); - while (i.hasNext()) { - i.next(); - colNames[i.value()-1] = m_columns[0]->name() + " " + i.key(); - } - - m_columns[0]->setColumnMode(originalColMode); - } - - df = n - np; - - // now making the stats table. - int rowCount = np+1; - int columnCount = 4; - - QVariant* rowMajor = new QVariant[rowCount*columnCount]; - // header data; - rowMajor[0] = ""; - rowMajor[1] = "Ni"; - rowMajor[2] = "yiBar"; - rowMajor[3] = "ziBar"; - - // table data - for (int row_i = 1; row_i < rowCount; row_i++) { - rowMajor[row_i*columnCount] = colNames[row_i-1]; - rowMajor[row_i*columnCount + 1] = ni[row_i-1]; - rowMajor[row_i*columnCount + 2] = yiBar[row_i-1]; - rowMajor[row_i*columnCount + 3] = ziBar[row_i-1]; - } - - m_statsTable = getHtmlTable(rowCount, columnCount, rowMajor); - - delete[] rowMajor; - delete[] yiBar; - delete[] ziBar; - delete[] ni; - - m_pValue.append(nsl_stats_fdist_p(fValue, static_cast(np-1), df)); - - printLine(0, "Null Hypothesis: Variance is equal between all classes", "blue"); - printLine(1, "Alternate Hypothesis: Variance is not equal in at-least one pair of classes", "blue"); - printLine(2, i18n("Significance level is %1", round(m_significanceLevel)), "blue"); - printLine(4, i18n("F Value is %1 ", round(fValue)), "green"); - printLine(5, i18n("P Value is %1 ", m_pValue[0]), "green"); - printLine(6, i18n("Degree of Freedom is %1", df), "green"); - - if (m_pValue[0] <= m_significanceLevel) { - printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); - printLine(8, "Requirement for homogeneity is not met", "red"); - } else { - printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); - printLine(8, "Requirement for homogeneity is met", "green"); - } - - m_statisticValue.append(fValue); - return; + if (m_columns.size() != 2) { + printError("Inappropriate number of m_columns selected"); + return; + } + + int np = 0; + int n = 0; + + if (!categoricalVariable && m_columns[0]->isNumeric()) + np = m_columns.size(); + else + countPartitions(m_columns[0], np, n); + + if (np < 2) { + printError("Select at least two m_columns / classes"); + return; + } + + double* yiBar = new double[np]; + double* ziBar = new double[np]; + double ziBarBar = 0; + double* ni = new double[np]; + + for (int i = 0; i < np; i++) { + yiBar[i] = 0; + ziBar[i] = 0; + ni[i] = 0; + } + + double fValue; + int df = 0; + + int totalRows = 0; + + QString* colNames = new QString[np]; + if (!categoricalVariable && m_columns[0]->isNumeric()) { + totalRows = m_columns[0]->rowCount(); + + double value = 0; + for (int j = 0; j < totalRows; j++) { + int numberNaNCols = 0; + for (int i = 0; i < np; i++) { + value = m_columns[i]->valueAt(j); + if (std::isnan(value)) { + numberNaNCols++; + continue; + } + yiBar[i] += value; + ni[i]++; + n++; + } + if (numberNaNCols == np) { + totalRows = j; + break; + } + } + + for (int i = 0; i < np; i++) { + if (ni[i] > 0) + yiBar[i] = yiBar[i] / ni[i]; + else { + printError("One of the selected m_columns is empty
" + "or have choosen Independent Var.1 wrongly"); + return; + } + } + + for (int j = 0; j < totalRows; j++) { + for (int i = 0; i < np; i++) { + value = m_columns[i]->valueAt(j); + if (!(std::isnan(value))) + ziBar[i] += fabs(value - yiBar[i]); + } + } + + for (int i = 0; i < np; i++) { + ziBarBar += ziBar[i]; + if (ni[i] > 0) + ziBar[i] = ziBar[i] / ni[i]; + } + + ziBarBar = ziBarBar / n; + + double numberatorValue = 0; + double denominatorValue = 0; + + for (int j = 0; j < totalRows; j++) { + for (int i = 0; i < np; i++) { + value = m_columns[i]->valueAt(j); + if (!(std::isnan(value))) { + double zij = fabs(value - yiBar[i]); + denominatorValue += gsl_pow_2( (zij - ziBar[i])); + } + } + } + + + if (denominatorValue == 0.0) { + printError( i18n("Denominator value is %1", denominatorValue)); + return; + } + + for (int i = 0; i < np; i++) { + colNames[i] = m_columns[i]->name(); + numberatorValue += ni[i]*gsl_pow_2( (ziBar[i]-ziBarBar)); + } + + fValue = ((n - np) / (np - 1)) * (numberatorValue / denominatorValue); + + } else { + QMap classnameToIndex; + + AbstractColumn::ColumnMode originalColMode = m_columns[0]->columnMode(); + m_columns[0]->setColumnMode(AbstractColumn::Text); + + int partitionNumber = 1; + QString name; + double value; + int classIndex; + + for (int j = 0; j < n; j++) { + name = m_columns[0]->textAt(j); + value = m_columns[1]->valueAt(j); + if (std::isnan(value)) { + n = j; + break; + } + + if (classnameToIndex[name] == 0) { + classnameToIndex[name] = partitionNumber; + partitionNumber++; + } + + classIndex = classnameToIndex[name]-1; + ni[classIndex]++; + yiBar[classIndex] += value; + } + + for (int i = 0; i < np; i++) { + if (ni[i] > 0) + yiBar[i] = yiBar[i] / ni[i]; + else { + printError("One of the selected m_columns is empty
" + "or have choosen Independent Var.1 wrongly"); + m_columns[0]->setColumnMode(originalColMode); + return; + } + } + + for (int j = 0; j < n; j++) { + name = m_columns[0]->textAt(j); + value = m_columns[1]->valueAt(j); + classIndex = classnameToIndex[name] - 1; + ziBar[classIndex] += fabs(value - yiBar[classIndex]); + } + + for (int i = 0; i < np; i++) { + ziBarBar += ziBar[i]; + ziBar[i] = ziBar[i] / ni[i]; + } + + ziBarBar = ziBarBar / n; + + double numberatorValue = 0; + double denominatorValue = 0; + + for (int j = 0; j < n; j++) { + name = m_columns[0]->textAt(j); + value = m_columns[1]->valueAt(j); + classIndex = classnameToIndex[name] - 1; + double zij = fabs(value - yiBar[classIndex]); + denominatorValue += gsl_pow_2( (zij - ziBar[classIndex])); + } + + for (int i = 0; i < np; i++) + numberatorValue += ni[i]*gsl_pow_2( (ziBar[i]-ziBarBar)); + + if (denominatorValue == 0.0) { + printError( "number of data points is less or than equal to number of categorical variables"); + m_columns[0]->setColumnMode(originalColMode); + return; + } + + fValue = ((n - np) / (np - 1)) * (numberatorValue / denominatorValue); + + QMapIterator i(classnameToIndex); + while (i.hasNext()) { + i.next(); + colNames[i.value()-1] = m_columns[0]->name() + " " + i.key(); + } + + m_columns[0]->setColumnMode(originalColMode); + } + + df = n - np; + + // now making the stats table. + int rowCount = np+1; + int columnCount = 4; + + QVariant* rowMajor = new QVariant[rowCount*columnCount]; + // header data; + rowMajor[0] = ""; + rowMajor[1] = "Ni"; + rowMajor[2] = "yiBar"; + rowMajor[3] = "ziBar"; + + // table data + for (int row_i = 1; row_i < rowCount; row_i++) { + rowMajor[row_i*columnCount] = colNames[row_i-1]; + rowMajor[row_i*columnCount + 1] = ni[row_i-1]; + rowMajor[row_i*columnCount + 2] = yiBar[row_i-1]; + rowMajor[row_i*columnCount + 3] = ziBar[row_i-1]; + } + + m_statsTable = getHtmlTable(rowCount, columnCount, rowMajor); + + delete[] rowMajor; + delete[] yiBar; + delete[] ziBar; + delete[] ni; + + m_pValue.append(nsl_stats_fdist_p(fValue, static_cast(np-1), df)); + + printLine(0, "Null Hypothesis: Variance is equal between all classes", "blue"); + printLine(1, "Alternate Hypothesis: Variance is not equal in at-least one pair of classes", "blue"); + printLine(2, i18n("Significance level is %1", round(m_significanceLevel)), "blue"); + printLine(4, i18n("F Value is %1 ", round(fValue)), "green"); + printLine(5, i18n("P Value is %1 ", m_pValue[0]), "green"); + printLine(6, i18n("Degree of Freedom is %1", df), "green"); + + if (m_pValue[0] <= m_significanceLevel) { + printTooltip(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significanceLevel)); + printLine(8, "Requirement for homogeneity is not met", "red"); + } else { + printTooltip(5, i18n("There is a plausibility for Null Hypothesis to be true")); + printLine(8, "Requirement for homogeneity is met", "green"); + } + + m_statisticValue.append(fValue); + return; } //TODO change ("⋖") symbol to ("<"), currently macro UTF8_QSTRING is not working properly if used "<" symbol; // TODO: check for correctness between: for TestZ with TailTwo // m_pValue.append(2*gsl_cdf_tdist_P(value, df) v/s // m_pValue.append(gsl_cdf_tdis_P(value, df) + gsl_cdf_tdis_P(-value, df); double HypothesisTest::getPValue(const HypothesisTest::Test::Type& test, double& value, const QString& col1Name, const QString& col2Name, const double mean, const double sp, const int df) { - switch (test) { - case HypothesisTest::Test::Type::TTest: { - switch (m_tailType) { - case HypothesisTest::Test::Tail::Negative: { - m_pValue.append(gsl_cdf_tdist_P(value, df)); - printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("≥"), col2Name), "blue"); - printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("⋖"), col2Name), "blue"); - break; - } - case HypothesisTest::Test::Tail::Positive: { - value *= -1; - m_pValue.append(gsl_cdf_tdist_P(value, df)); - printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("≤"), col2Name), "blue"); - printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING(">"), col2Name), "blue"); - break; - } - case HypothesisTest::Test::Tail::Two: { - m_pValue.append(2.*gsl_cdf_tdist_P(-fabs(value), df)); - - printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("="), col2Name), "blue"); - printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("≠"), col2Name), "blue"); - break; - } - } - break; - } - case HypothesisTest::Test::Type::ZTest: { - switch (m_tailType) { - case HypothesisTest::Test::Tail::Negative: { - m_pValue.append(gsl_cdf_gaussian_P(value - mean, sp)); - printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("≥"), col2Name), "blue"); - printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("⋖"), col2Name), "blue"); - break; - } - case HypothesisTest::Test::Tail::Positive: { - value *= -1; - m_pValue.append(nsl_stats_tdist_p(value - mean, sp)); - printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("≤"), col2Name), "blue"); - printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING(">"), col2Name), "blue"); - break; - } - case HypothesisTest::Test::Tail::Two: { - m_pValue.append(2.*gsl_cdf_gaussian_P(value - mean, sp)); - printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("="), col2Name), "blue"); - printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("≠"), col2Name), "blue"); - break; - } - } - break; - } - case HypothesisTest::Test::Type::Anova: - case HypothesisTest::Test::Type::NoneType: - break; - } - - if (m_pValue[0] > 1) - return 1; - return m_pValue[0]; + switch (test) { + case HypothesisTest::Test::Type::TTest: { + switch (m_tailType) { + case HypothesisTest::Test::Tail::Negative: { + m_pValue.append(gsl_cdf_tdist_P(value, df)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("≥"), col2Name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("⋖"), col2Name), "blue"); + break; + } + case HypothesisTest::Test::Tail::Positive: { + value *= -1; + m_pValue.append(gsl_cdf_tdist_P(value, df)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("≤"), col2Name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING(">"), col2Name), "blue"); + break; + } + case HypothesisTest::Test::Tail::Two: { + m_pValue.append(2.*gsl_cdf_tdist_P(-fabs(value), df)); + + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("="), col2Name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1Name, UTF8_QSTRING("≠"), col2Name), "blue"); + break; + } + } + break; + } + case HypothesisTest::Test::Type::ZTest: { + switch (m_tailType) { + case HypothesisTest::Test::Tail::Negative: { + m_pValue.append(gsl_cdf_gaussian_P(value - mean, sp)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("≥"), col2Name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("⋖"), col2Name), "blue"); + break; + } + case HypothesisTest::Test::Tail::Positive: { + value *= -1; + m_pValue.append(nsl_stats_tdist_p(value - mean, sp)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("≤"), col2Name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING(">"), col2Name), "blue"); + break; + } + case HypothesisTest::Test::Tail::Two: { + m_pValue.append(2.*gsl_cdf_gaussian_P(value - mean, sp)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("="), col2Name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1Name, UTF8_QSTRING("≠"), col2Name), "blue"); + break; + } + } + break; + } + case HypothesisTest::Test::Type::Anova: + case HypothesisTest::Test::Type::NoneType: + break; + } + + if (m_pValue[0] > 1) + return 1; + return m_pValue[0]; } // Virtual functions QWidget* HypothesisTest::view() const { - if (!m_partView) { - m_view = new HypothesisTestView(const_cast(this)); - m_partView = m_view; - } - return m_partView; + if (!m_partView) { + m_view = new HypothesisTestView(const_cast(this)); + m_partView = m_view; + } + return m_partView; } diff --git a/src/backend/generalTest/HypothesisTest.h b/src/backend/generalTest/HypothesisTest.h index d76f13412..6a1f9d59c 100644 --- a/src/backend/generalTest/HypothesisTest.h +++ b/src/backend/generalTest/HypothesisTest.h @@ -1,91 +1,91 @@ /*************************************************************************** File : HypothesisTest.h Project : LabPlot Description : Doing Hypothesis-Test on data provided -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTEST_H #define HYPOTHESISTEST_H #include "GeneralTest.h" class HypothesisTest : public GeneralTest { Q_OBJECT public: - explicit HypothesisTest(const QString& name); + explicit HypothesisTest(const QString& name); ~HypothesisTest() override; - struct Test { - enum Type { - NoneType = 0, - TTest = 1 << 0, - ZTest = 1 << 1, - Anova = 1 << 2 - }; - enum SubType { - NoneSubType = 0, - TwoSampleIndependent = 1 << 0, - TwoSamplePaired = 1 << 1, - OneSample = 1 << 2, - OneWay = 1 << 3, - TwoWay = 1 << 4 - }; - enum Tail {Positive, Negative, Two}; - Type type = NoneType; - SubType subtype = NoneSubType; - Tail tail; - }; + struct Test { + enum Type { + NoneType = 0, + TTest = 1 << 0, + ZTest = 1 << 1, + Anova = 1 << 2 + }; + enum SubType { + NoneSubType = 0, + TwoSampleIndependent = 1 << 0, + TwoSamplePaired = 1 << 1, + OneSample = 1 << 2, + OneWay = 1 << 3, + TwoWay = 1 << 4 + }; + enum Tail {Positive, Negative, Two}; + Type type = NoneType; + SubType subtype = NoneSubType; + Tail tail; + }; void setPopulationMean(QVariant populationMean); void setSignificanceLevel(QVariant alpha); - void performTest(Test m_test, bool categoricalVariable = true, bool equalVariance = true); - void performLeveneTest(bool categoricalVariable); + void performTest(Test m_test, bool categoricalVariable = true, bool equalVariance = true); + void performLeveneTest(bool categoricalVariable); - QList& statisticValue(); - QList& pValue(); - QWidget* view() const override; + QList& statisticValue(); + QList& pValue(); + QWidget* view() const override; private: - void performTwoSampleIndependentTest(HypothesisTest::Test::Type test, bool categoricalVariable = false, bool equalVariance = true); - void performTwoSamplePairedTest(HypothesisTest::Test::Type test); - void performOneSampleTest(HypothesisTest::Test::Type test); - void performOneWayAnova(); - void performTwoWayAnova(); - void m_performLeveneTest(bool categoricalVariable); + void performTwoSampleIndependentTest(HypothesisTest::Test::Type test, bool categoricalVariable = false, bool equalVariance = true); + void performTwoSamplePairedTest(HypothesisTest::Test::Type test); + void performOneSampleTest(HypothesisTest::Test::Type test); + void performOneWayAnova(); + void performTwoWayAnova(); + void m_performLeveneTest(bool categoricalVariable); - double getPValue(const HypothesisTest::Test::Type& test, double& value, - const QString& col1Name, const QString& col2name, - const double mean, const double sp, const int df); + double getPValue(const HypothesisTest::Test::Type& test, double& value, + const QString& col1Name, const QString& col2name, + const double mean, const double sp, const int df); - double m_populationMean; - double m_significanceLevel; - HypothesisTest::Test::Tail m_tailType; - QList m_pValue; - QList m_statisticValue; + double m_populationMean; + double m_significanceLevel; + HypothesisTest::Test::Tail m_tailType; + QList m_pValue; + QList m_statisticValue; }; #endif // HypothesisTest_H diff --git a/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.cpp b/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.cpp index 7d78d2ed8..558f87c07 100644 --- a/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.cpp +++ b/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.cpp @@ -1,513 +1,513 @@ /*************************************************************************** File : CorrelationCoefficientDock.cpp Project : LabPlot Description : widget for correlation test properties -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "CorrelationCoefficientDock.h" #include "backend/core/AspectTreeModel.h" #include "backend/core/AbstractAspect.h" #include "backend/core/Project.h" #include "backend/spreadsheet/Spreadsheet.h" #include "commonfrontend/widgets/TreeViewComboBox.h" #include "kdefrontend/datasources/DatabaseManagerDialog.h" #include "kdefrontend/datasources/DatabaseManagerWidget.h" #include "kdefrontend/TemplateHandler.h" #include #include #include #include #include #include #include #include /*! \class CorrelationCoefficientDock \brief Provides a dock (widget) for correlation testing: \ingroup kdefrontend */ //TODO: To add tooltips in docks for non obvious widgets. //TODO: Add functionality for database along with spreadsheet. CorrelationCoefficientDock::CorrelationCoefficientDock(QWidget* parent) : QWidget(parent) { ui.setupUi(this); ui.cbDataSourceType->addItem(i18n("Spreadsheet")); ui.cbDataSourceType->addItem(i18n("Database")); cbSpreadsheet = new TreeViewComboBox; ui.gridLayout->addWidget(cbSpreadsheet, 5, 4, 1, 3); ui.bDatabaseManager->setIcon(QIcon::fromTheme("network-server-database")); ui.bDatabaseManager->setToolTip(i18n("Manage connections")); m_configPath = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).constFirst() + "sql_connections"; - ui.cbTest->addItem( i18n("Pearson r"), CorrelationCoefficient::Test::Pearson); - ui.cbTest->addItem( i18n("Kendall"), CorrelationCoefficient::Test::Kendall); - ui.cbTest->addItem( i18n("Spearman"), CorrelationCoefficient::Test::Spearman); + ui.cbTest->addItem( i18n("Pearson r"), CorrelationCoefficient::Test::Pearson); + ui.cbTest->addItem( i18n("Kendall"), CorrelationCoefficient::Test::Kendall); + ui.cbTest->addItem( i18n("Spearman"), CorrelationCoefficient::Test::Spearman); // adding item to tests and testtype combo box; // making all test blocks invisible at starting. ui.lCategorical->hide(); ui.chbCategorical->hide(); ui.lCol1->hide(); ui.cbCol1->hide(); ui.lCol2->hide(); ui.cbCol2->hide(); ui.pbPerformTest->setEnabled(false); ui.pbPerformTest->setIcon(QIcon::fromTheme("run-build")); // readConnections(); connect(ui.cbDataSourceType, static_cast(&QComboBox::currentIndexChanged), - this, &CorrelationCoefficientDock::dataSourceTypeChanged); + this, &CorrelationCoefficientDock::dataSourceTypeChanged); - connect(cbSpreadsheet, &TreeViewComboBox::currentModelIndexChanged, this, &CorrelationCoefficientDock::spreadsheetChanged); + connect(cbSpreadsheet, &TreeViewComboBox::currentModelIndexChanged, this, &CorrelationCoefficientDock::spreadsheetChanged); // connect(ui.cbConnection, static_cast(&QComboBox::currentIndexChanged), - // this, &CorrelationCoefficientDock::connectionChanged); + // this, &CorrelationCoefficientDock::connectionChanged); // connect(ui.cbTable, static_cast(&QComboBox::currentIndexChanged), - // this, &CorrelationCoefficientDock::tableChanged); - // connect(ui.bDatabaseManager, &QPushButton::clicked, this, &CorrelationCoefficientDock::showDatabaseManager); + // this, &CorrelationCoefficientDock::tableChanged); + // connect(ui.bDatabaseManager, &QPushButton::clicked, this, &CorrelationCoefficientDock::showDatabaseManager); - // connect(ui.bAddRow, &QPushButton::clicked, this, &CorrelationCoefficientDock::addRow); - // connect(ui.bRemoveRow, &QPushButton::clicked, this,&CorrelationCoefficientDock::removeRow); - // connect(ui.bAddColumn, &QPushButton::clicked, this, &CorrelationCoefficientDock::addColumn); - // connect(ui.bRemoveColumn, &QPushButton::clicked, this,&CorrelationCoefficientDock::removeColumn); + // connect(ui.bAddRow, &QPushButton::clicked, this, &CorrelationCoefficientDock::addRow); + // connect(ui.bRemoveRow, &QPushButton::clicked, this,&CorrelationCoefficientDock::removeRow); + // connect(ui.bAddColumn, &QPushButton::clicked, this, &CorrelationCoefficientDock::addColumn); + // connect(ui.bRemoveColumn, &QPushButton::clicked, this,&CorrelationCoefficientDock::removeColumn); - // connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::doTTest); - // connect(ui.cbCol2, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::doTTest); + // connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::doTTest); + // connect(ui.cbCol2, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::doTTest); // connect(ui.lwFields, &QListWidget::itemSelectionChanged, this, [=]() { // bool enabled = !ui.lwFields->selectedItems().isEmpty(); // ui.bAddRow->setEnabled(enabled); // ui.bAddColumn->setEnabled(enabled); // }); - // connect(ui.lwRows, &QListWidget::doubleClicked, this,&CorrelationCoefficientDock::removeRow); + // connect(ui.lwRows, &QListWidget::doubleClicked, this,&CorrelationCoefficientDock::removeRow); // connect(ui.lwRows, &QListWidget::itemSelectionChanged, this, [=]() { // ui.bRemoveRow->setEnabled(!ui.lwRows->selectedItems().isEmpty()); // }); - // connect(ui.lwColumns, &QListWidget::doubleClicked, this,&CorrelationCoefficientDock::removeColumn); + // connect(ui.lwColumns, &QListWidget::doubleClicked, this,&CorrelationCoefficientDock::removeColumn); // connect(ui.lwColumns, &QListWidget::itemSelectionChanged, this, [=]() { // ui.bRemoveColumn->setEnabled(!ui.lwColumns->selectedItems().isEmpty()); // }); - connect(ui.cbTest, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::showCorrelationCoefficient); - connect(ui.chbCategorical, &QCheckBox::stateChanged, this, &CorrelationCoefficientDock::changeCbCol2Label); + connect(ui.cbTest, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::showCorrelationCoefficient); + connect(ui.chbCategorical, &QCheckBox::stateChanged, this, &CorrelationCoefficientDock::changeCbCol2Label); - connect(ui.pbPerformTest, &QPushButton::clicked, this, &CorrelationCoefficientDock::findCorrelationCoefficient); - connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::col1IndexChanged); + connect(ui.pbPerformTest, &QPushButton::clicked, this, &CorrelationCoefficientDock::findCorrelationCoefficient); + connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &CorrelationCoefficientDock::col1IndexChanged); - ui.cbTest->setCurrentIndex(0); - emit ui.cbTest->currentIndexChanged(0); + ui.cbTest->setCurrentIndex(0); + emit ui.cbTest->currentIndexChanged(0); } void CorrelationCoefficientDock::setCorrelationCoefficient(CorrelationCoefficient* CorrelationCoefficient) { - m_initializing = true; - m_correlationCoefficient = CorrelationCoefficient; + m_initializing = true; + m_correlationCoefficient = CorrelationCoefficient; - m_aspectTreeModel = new AspectTreeModel(m_correlationCoefficient->project()); + m_aspectTreeModel = new AspectTreeModel(m_correlationCoefficient->project()); - QList list{AspectType::Folder, AspectType::Workbook, - AspectType::Spreadsheet, AspectType::LiveDataSource}; - cbSpreadsheet->setTopLevelClasses(list); + QList list{AspectType::Folder, AspectType::Workbook, + AspectType::Spreadsheet, AspectType::LiveDataSource}; + cbSpreadsheet->setTopLevelClasses(list); - list = {AspectType::Spreadsheet, AspectType::LiveDataSource}; - m_aspectTreeModel->setSelectableAspects(list); + list = {AspectType::Spreadsheet, AspectType::LiveDataSource}; + m_aspectTreeModel->setSelectableAspects(list); cbSpreadsheet->setModel(m_aspectTreeModel); //show the properties - ui.leName->setText(m_correlationCoefficient->name()); - ui.leComment->setText(m_correlationCoefficient->comment()); - ui.cbDataSourceType->setCurrentIndex(m_correlationCoefficient->dataSourceType()); - if (m_correlationCoefficient->dataSourceType() == CorrelationCoefficient::DataSourceType::DataSourceSpreadsheet) - setModelIndexFromAspect(cbSpreadsheet, m_correlationCoefficient->dataSourceSpreadsheet()); + ui.leName->setText(m_correlationCoefficient->name()); + ui.leComment->setText(m_correlationCoefficient->comment()); + ui.cbDataSourceType->setCurrentIndex(m_correlationCoefficient->dataSourceType()); + if (m_correlationCoefficient->dataSourceType() == CorrelationCoefficient::DataSourceType::DataSourceSpreadsheet) + setModelIndexFromAspect(cbSpreadsheet, m_correlationCoefficient->dataSourceSpreadsheet()); // else - // ui.cbConnection->setCurrentIndex(ui.cbConnection->findText(m_correlationCoefficient->dataSourceConnection())); + // ui.cbConnection->setCurrentIndex(ui.cbConnection->findText(m_correlationCoefficient->dataSourceConnection())); - setColumnsComboBoxModel(m_correlationCoefficient->dataSourceSpreadsheet()); + setColumnsComboBoxModel(m_correlationCoefficient->dataSourceSpreadsheet()); this->dataSourceTypeChanged(ui.cbDataSourceType->currentIndex()); //setting rows and columns in combo box; //undo functions // connect(m_correlationCoefficient, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(CorrelationCoefficientDescriptionChanged(const AbstractAspect*))); m_initializing = false; } void CorrelationCoefficientDock::showCorrelationCoefficient() { - if (ui.cbTest->count() == 0) + if (ui.cbTest->count() == 0) return; - m_test = CorrelationCoefficient::Test(ui.cbTest->currentData().toInt()); + m_test = CorrelationCoefficient::Test(ui.cbTest->currentData().toInt()); ui.lCol1->show(); ui.cbCol1->show(); - ui.lCol2->show(); - ui.cbCol2->show(); + ui.lCol2->show(); + ui.cbCol2->show(); - ui.lCategorical->setVisible(bool(m_test & CorrelationCoefficient::Test::Pearson)); - ui.chbCategorical->setVisible(bool(m_test & CorrelationCoefficient::Test::Pearson)); + ui.lCategorical->setVisible(bool(m_test & CorrelationCoefficient::Test::Pearson)); + ui.chbCategorical->setVisible(bool(m_test & CorrelationCoefficient::Test::Pearson)); setColumnsComboBoxView(); ui.pbPerformTest->setEnabled(nonEmptySelectedColumns()); } void CorrelationCoefficientDock::findCorrelationCoefficient() { - QVector cols; + QVector cols; - if (ui.cbCol1->count() == 0) - return; + if (ui.cbCol1->count() == 0) + return; - cols << reinterpret_cast(ui.cbCol1->currentData().toLongLong()); - cols << reinterpret_cast(ui.cbCol2->currentData().toLongLong()); + cols << reinterpret_cast(ui.cbCol1->currentData().toLongLong()); + cols << reinterpret_cast(ui.cbCol2->currentData().toLongLong()); - m_correlationCoefficient->setColumns(cols); - m_correlationCoefficient->performTest(m_test, ui.chbCategorical->isChecked()); + m_correlationCoefficient->setColumns(cols); + m_correlationCoefficient->performTest(m_test, ui.chbCategorical->isChecked()); } void CorrelationCoefficientDock::setModelIndexFromAspect(TreeViewComboBox* cb, const AbstractAspect* aspect) { if (aspect) cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(aspect)); else cb->setCurrentModelIndex(QModelIndex()); } ////************************************************************* ////****** SLOTs for changes triggered in CorrelationCoefficientDock ******* ////************************************************************* //void CorrelationCoefficientDock::nameChanged() { // if (m_initializing) // return; // m_correlationCoefficient->setName(ui.leName->text()); //} //void CorrelationCoefficientDock::commentChanged() { // if (m_initializing) // return; // m_correlationCoefficient->setComment(ui.leComment->text()); //} void CorrelationCoefficientDock::dataSourceTypeChanged(int index) { - //QDEBUG("in dataSourceTypeChanged"); - CorrelationCoefficient::DataSourceType type = static_cast(index); - bool showDatabase = (type == CorrelationCoefficient::DataSourceType::DataSourceDatabase); + //QDEBUG("in dataSourceTypeChanged"); + CorrelationCoefficient::DataSourceType type = static_cast(index); + bool showDatabase = (type == CorrelationCoefficient::DataSourceType::DataSourceDatabase); ui.lSpreadsheet->setVisible(!showDatabase); cbSpreadsheet->setVisible(!showDatabase); ui.lConnection->setVisible(showDatabase); ui.cbConnection->setVisible(showDatabase); ui.bDatabaseManager->setVisible(showDatabase); ui.lTable->setVisible(showDatabase); ui.cbTable->setVisible(showDatabase); if (m_initializing) return; - m_correlationCoefficient->setComment(ui.leComment->text()); + m_correlationCoefficient->setComment(ui.leComment->text()); } void CorrelationCoefficientDock::spreadsheetChanged(const QModelIndex& index) { - //QDEBUG("in spreadsheetChanged"); - auto* aspect = static_cast(index.internalPointer()); + //QDEBUG("in spreadsheetChanged"); + auto* aspect = static_cast(index.internalPointer()); Spreadsheet* spreadsheet = dynamic_cast(aspect); setColumnsComboBoxModel(spreadsheet); - m_correlationCoefficient->setDataSourceSpreadsheet(spreadsheet); + m_correlationCoefficient->setDataSourceSpreadsheet(spreadsheet); } void CorrelationCoefficientDock::col1IndexChanged(int index) { - if (index < 0) return; - changeCbCol2Label(); + if (index < 0) return; + changeCbCol2Label(); } //void CorrelationCoefficientDock::connectionChanged() { // if (ui.cbConnection->currentIndex() == -1) { // ui.lTable->hide(); // ui.cbTable->hide(); // return; // } // //clear the previously shown tables // ui.cbTable->clear(); // ui.lTable->show(); // ui.cbTable->show(); // const QString& connection = ui.cbConnection->currentText(); // //connection name was changed, determine the current connections settings // KConfig config(m_configPath, KConfig::SimpleConfig); // KConfigGroup group = config.group(connection); // //close and remove the previos connection, if available // if (m_db.isOpen()) { // m_db.close(); // QSqlDatabase::removeDatabase(m_db.driverName()); // } // //open the selected connection // //QDEBUG("CorrelationCoefficientDock: connecting to " + connection); // const QString& driver = group.readEntry("Driver"); // m_db = QSqlDatabase::addDatabase(driver); // const QString& dbName = group.readEntry("DatabaseName"); // if (DatabaseManagerWidget::isFileDB(driver)) { // if (!QFile::exists(dbName)) { // KMessageBox::error(this, i18n("Couldn't find the database file '%1'. Please check the connection settings.", dbName), // appendRow i18n("Connection Failed")); // return; // } else // m_db.setDatabaseName(dbName); // } else if (DatabaseManagerWidget::isODBC(driver)) { // if (group.readEntry("CustomConnectionEnabled", false)) // m_db.setDatabaseName(group.readEntry("CustomConnectionString")); // else // m_db.setDatabaseName(dbName); // } else { // m_db.setDatabaseName(dbName); // m_db.setHostName( group.readEntry("HostName") ); // m_db.setPort( group.readEntry("Port", 0) ); // m_db.setUserName( group.readEntry("UserName") ); // m_db.setPassword( group.readEntry("Password") ); // } // WAIT_CURSOR; // if (!m_db.open()) { // RESET_CURSOR; // KMessageBox::error(this, i18n("Failed to connect to the database '%1'. Please check the connection settings.", ui.cbConnection->currentText()) + // QLatin1String("\n\n") + m_db.lastError().databaseText(), // i18n("Connection Failed")); // return; // } // //show all available database tables // if (m_db.tables().size()) { // for (auto table : m_db.tables()) // ui.cbTable->addItem(QIcon::fromTheme("view-form-table"), table); // ui.cbTable->setCurrentIndex(0); // } // RESET_CURSOR; // if (m_initializing) // return; //// m_correlationCoefficient->setDataSourceConnection(connection); //} //void CorrelationCoefficientDock::tableChanged() { // const QString& table = ui.cbTable->currentText(); // //show all attributes of the selected table //// for (const auto* col : spreadsheet->children()) { //// QListWidgetItem* item = new QListWidgetItem(col->icon(), col->name()); //// ui.lwFields->addItem(item); //// } // if (m_initializing) // return; //// m_correlationCoefficient->setDataSourceTable(table); //} ////************************************************************* ////******** SLOTs for changes triggered in Spreadsheet ********* ////************************************************************* void CorrelationCoefficientDock::CorrelationCoefficientDescriptionChanged(const AbstractAspect* aspect) { - if (m_correlationCoefficient != aspect) - return; + if (m_correlationCoefficient != aspect) + return; - m_initializing = true; - if (aspect->name() != ui.leName->text()) - ui.leName->setText(aspect->name()); - else if (aspect->comment() != ui.leComment->text()) - ui.leComment->setText(aspect->comment()); + m_initializing = true; + if (aspect->name() != ui.leName->text()) + ui.leName->setText(aspect->name()); + else if (aspect->comment() != ui.leComment->text()) + ui.leComment->setText(aspect->comment()); - m_initializing = false; + m_initializing = false; } void CorrelationCoefficientDock::changeCbCol2Label() { - if (ui.cbCol1->count() == 0) return; - - QString selected_text = ui.cbCol1->currentText(); - Column* col1 = m_correlationCoefficient->dataSourceSpreadsheet()->column(selected_text); - - if (bool(m_test & (CorrelationCoefficient::Test::Kendall | CorrelationCoefficient::Test::Spearman)) || - (!ui.chbCategorical->isChecked() && - (col1->columnMode() == AbstractColumn::Integer || col1->columnMode() == AbstractColumn::Numeric))) { - ui.lCol2->setText( i18n("Independent Var. 2")); - ui.chbCategorical->setChecked(false); - ui.chbCategorical->setEnabled(true); - } else { - ui.lCol2->setText( i18n("Dependent Var. 1")); - if (!ui.chbCategorical->isChecked()) - ui.chbCategorical->setEnabled(false); - else - ui.chbCategorical->setEnabled(true); - ui.chbCategorical->setChecked(true); - } + if (ui.cbCol1->count() == 0) return; + + QString selected_text = ui.cbCol1->currentText(); + Column* col1 = m_correlationCoefficient->dataSourceSpreadsheet()->column(selected_text); + + if (bool(m_test & (CorrelationCoefficient::Test::Kendall | CorrelationCoefficient::Test::Spearman)) || + (!ui.chbCategorical->isChecked() && + (col1->columnMode() == AbstractColumn::Integer || col1->columnMode() == AbstractColumn::Numeric))) { + ui.lCol2->setText( i18n("Independent Var. 2")); + ui.chbCategorical->setChecked(false); + ui.chbCategorical->setEnabled(true); + } else { + ui.lCol2->setText( i18n("Dependent Var. 1")); + if (!ui.chbCategorical->isChecked()) + ui.chbCategorical->setEnabled(false); + else + ui.chbCategorical->setEnabled(true); + ui.chbCategorical->setChecked(true); + } } ////************************************************************* ////******************** SETTINGS ******************************* ////************************************************************* //void CorrelationCoefficientDock::load() { //} //void CorrelationCoefficientDock::loadConfigFromTemplate(KConfig& config) { // Q_UNUSED(config); //} ///*! // loads saved matrix properties from \c config. // */ //void CorrelationCoefficientDock::loadConfig(KConfig& config) { // Q_UNUSED(config); //} ///*! // saves matrix properties to \c config. // */ //void CorrelationCoefficientDock::saveConfigAsTemplate(KConfig& config) { // Q_UNUSED(config); //} void CorrelationCoefficientDock::setColumnsComboBoxModel(Spreadsheet* spreadsheet) { - m_onlyValuesCols.clear(); - m_twoCategoricalCols.clear(); - m_multiCategoricalCols.clear(); - - for (auto* col : spreadsheet->children()) { - if (col->columnMode() == AbstractColumn::Integer || col->columnMode() == AbstractColumn::Numeric) - m_onlyValuesCols.append(col); - else { - int np = 0, n_rows = 0; - countPartitions(col, np, n_rows); - if (np <= 1) - continue; - else if (np == 2) - m_twoCategoricalCols.append(col); - else - m_multiCategoricalCols.append(col); - } - } - setColumnsComboBoxView(); - showCorrelationCoefficient(); + m_onlyValuesCols.clear(); + m_twoCategoricalCols.clear(); + m_multiCategoricalCols.clear(); + + for (auto* col : spreadsheet->children()) { + if (col->columnMode() == AbstractColumn::Integer || col->columnMode() == AbstractColumn::Numeric) + m_onlyValuesCols.append(col); + else { + int np = 0, n_rows = 0; + countPartitions(col, np, n_rows); + if (np <= 1) + continue; + else if (np == 2) + m_twoCategoricalCols.append(col); + else + m_multiCategoricalCols.append(col); + } + } + setColumnsComboBoxView(); + showCorrelationCoefficient(); } //TODO: change from if else to switch case: void CorrelationCoefficientDock::setColumnsComboBoxView() { - ui.cbCol1->clear(); - ui.cbCol2->clear(); - - QList::iterator i; - - switch (m_test) { - case (CorrelationCoefficient::Test::Pearson): { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - break; - } - case CorrelationCoefficient::Test::Kendall: { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - for (i = m_multiCategoricalCols.begin(); i != m_multiCategoricalCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - break; - } - case CorrelationCoefficient::Test::Spearman: { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - break; - } - } + ui.cbCol1->clear(); + ui.cbCol2->clear(); + + QList::iterator i; + + switch (m_test) { + case (CorrelationCoefficient::Test::Pearson): { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + break; + } + case CorrelationCoefficient::Test::Kendall: { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + for (i = m_multiCategoricalCols.begin(); i != m_multiCategoricalCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + break; + } + case CorrelationCoefficient::Test::Spearman: { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + break; + } + } } bool CorrelationCoefficientDock::nonEmptySelectedColumns() { - if ((ui.cbCol1->isVisible() && ui.cbCol1->count() < 1) || - (ui.cbCol2->isVisible() && ui.cbCol2->count() < 1)) - return false; - return true; + if ((ui.cbCol1->isVisible() && ui.cbCol1->count() < 1) || + (ui.cbCol2->isVisible() && ui.cbCol2->count() < 1)) + return false; + return true; } void CorrelationCoefficientDock::countPartitions(Column *column, int &np, int &total_rows) { - total_rows = column->rowCount(); - np = 0; - QString cell_value; - QMap discovered_categorical_var; + total_rows = column->rowCount(); + np = 0; + QString cell_value; + QMap discovered_categorical_var; - AbstractColumn::ColumnMode original_col_mode = column->columnMode(); - column->setColumnMode(AbstractColumn::Text); + AbstractColumn::ColumnMode original_col_mode = column->columnMode(); + column->setColumnMode(AbstractColumn::Text); - for (int i = 0; i < total_rows; i++) { - cell_value = column->textAt(i); + for (int i = 0; i < total_rows; i++) { + cell_value = column->textAt(i); - if (cell_value.isEmpty()) { - total_rows = i; - break; - } + if (cell_value.isEmpty()) { + total_rows = i; + break; + } - if (discovered_categorical_var[cell_value]) - continue; + if (discovered_categorical_var[cell_value]) + continue; - discovered_categorical_var[cell_value] = true; - np++; - } - column->setColumnMode(original_col_mode); + discovered_categorical_var[cell_value] = true; + np++; + } + column->setColumnMode(original_col_mode); } diff --git a/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.h b/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.h index c396e70bd..a668734a1 100644 --- a/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.h +++ b/src/kdefrontend/dockwidgets/CorrelationCoefficientDock.h @@ -1,105 +1,105 @@ /*************************************************************************** File : CorrelationCoefficientDock.h Project : LabPlot Description : widget for hypothesis testing properties -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef CORRELATIONCOEFFICIENTDOCK_H #define CORRELATIONCOEFFICIENTDOCK_H #include "backend/generalTest/CorrelationCoefficient.h" #include "ui_correlationcoefficientdock.h" #include //class Column; //class Spreadsheet; //class AbstractAspect; class AspectTreeModel; //class CorrelationCoefficient; class TreeViewComboBox; //class KConfig; //class QStandardItemModel; //class QStandardItem; //class QComboBox; class CorrelationCoefficientDock : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit CorrelationCoefficientDock(QWidget*); - void setCorrelationCoefficient(CorrelationCoefficient*); + explicit CorrelationCoefficientDock(QWidget*); + void setCorrelationCoefficient(CorrelationCoefficient*); private: - Ui::CorrelationCoefficientDock ui; - bool m_initializing{false}; - TreeViewComboBox* cbSpreadsheet{nullptr}; - CorrelationCoefficient* m_correlationCoefficient{nullptr}; - AspectTreeModel* m_aspectTreeModel{nullptr}; - QSqlDatabase m_db; - QString m_configPath; - // void load(); - // void loadConfig(KConfig&); - void setModelIndexFromAspect(TreeViewComboBox*, const AbstractAspect*); - // void readConnections(); - // void updateFields(); - // bool fieldSelected(const QString&); - CorrelationCoefficient::Test m_test; - void countPartitions(Column *column, int &np, int &total_rows); - - void setColumnsComboBoxModel(Spreadsheet* spreadsheet); - void setColumnsComboBoxView(); - bool nonEmptySelectedColumns(); - - QList m_onlyValuesCols; - QList m_twoCategoricalCols; - QList m_multiCategoricalCols; + Ui::CorrelationCoefficientDock ui; + bool m_initializing{false}; + TreeViewComboBox* cbSpreadsheet{nullptr}; + CorrelationCoefficient* m_correlationCoefficient{nullptr}; + AspectTreeModel* m_aspectTreeModel{nullptr}; + QSqlDatabase m_db; + QString m_configPath; + // void load(); + // void loadConfig(KConfig&); + void setModelIndexFromAspect(TreeViewComboBox*, const AbstractAspect*); + // void readConnections(); + // void updateFields(); + // bool fieldSelected(const QString&); + CorrelationCoefficient::Test m_test; + void countPartitions(Column *column, int &np, int &total_rows); + + void setColumnsComboBoxModel(Spreadsheet* spreadsheet); + void setColumnsComboBoxView(); + bool nonEmptySelectedColumns(); + + QList m_onlyValuesCols; + QList m_twoCategoricalCols; + QList m_multiCategoricalCols; private slots: - //SLOTs for changes triggered in PivotTableDock - // void nameChanged(); - // void commentChanged(); - void dataSourceTypeChanged(int); - void showCorrelationCoefficient(); - void findCorrelationCoefficient(); - void spreadsheetChanged(const QModelIndex&); - void col1IndexChanged(int index); - void changeCbCol2Label(); + //SLOTs for changes triggered in PivotTableDock + // void nameChanged(); + // void commentChanged(); + void dataSourceTypeChanged(int); + void showCorrelationCoefficient(); + void findCorrelationCoefficient(); + void spreadsheetChanged(const QModelIndex&); + void col1IndexChanged(int index); + void changeCbCol2Label(); - // void connectionChanged(); - // void tableChanged(); - // void showDatabaseManager(); + // void connectionChanged(); + // void tableChanged(); + // void showDatabaseManager(); - // //SLOTs for changes triggered in PivotTable - void CorrelationCoefficientDescriptionChanged(const AbstractAspect*); + // //SLOTs for changes triggered in PivotTable + void CorrelationCoefficientDescriptionChanged(const AbstractAspect*); - // //save/load template - // void loadConfigFromTemplate(KConfig&); - // void saveConfigAsTemplate(KConfig&); + // //save/load template + // void loadConfigFromTemplate(KConfig&); + // void saveConfigAsTemplate(KConfig&); signals: - // void info(const QString&); + // void info(const QString&); }; #endif // CORRELATIONCOEFFICIENTDOCK_H diff --git a/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp b/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp index 217441d20..a19d78df7 100644 --- a/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp +++ b/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp @@ -1,875 +1,876 @@ /*************************************************************************** File : HypothesisTestDock.cpp Project : LabPlot Description : widget for hypothesis test properties -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "HypothesisTestDock.h" #include "backend/core/AspectTreeModel.h" #include "backend/core/AbstractAspect.h" #include "backend/core/Project.h" #include "backend/spreadsheet/Spreadsheet.h" #include "commonfrontend/widgets/TreeViewComboBox.h" #include "kdefrontend/datasources/DatabaseManagerDialog.h" #include "kdefrontend/datasources/DatabaseManagerWidget.h" #include "kdefrontend/TemplateHandler.h" #include #include #include #include #include #include #include #include /*! \class HypothesisTestDock \brief Provides a dock (widget) for hypothesis testing: \ingroup kdefrontend */ //TODO: To add tooltips in docks for non obvious widgets. //TODO: Add functionality for database along with spreadsheet. HypothesisTestDock::HypothesisTestDock(QWidget* parent) : QWidget(parent) { - //QDEBUG("in hypothesis test constructor "); - ui.setupUi(this); - - ui.cbDataSourceType->addItem(i18n("Spreadsheet")); - ui.cbDataSourceType->addItem(i18n("Database")); - - cbSpreadsheet = new TreeViewComboBox; - ui.gridLayout->addWidget(cbSpreadsheet, 5, 4, 1, 3); - - ui.bDatabaseManager->setIcon(QIcon::fromTheme("network-server-database")); - ui.bDatabaseManager->setToolTip(i18n("Manage connections")); - m_configPath = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).constFirst() + "sql_connections"; - - // adding item to tests and testtype combo box; - - ui.cbTest->addItem( i18n("T Test"), HypothesisTest::Test::Type::TTest); - ui.cbTest->addItem( i18n("Z Test"), HypothesisTest::Test::Type::ZTest); - ui.cbTest->addItem( i18n("ANOVA"), HypothesisTest::Test::Type::Anova); - - ui.lPopulationSigma->setText( UTF8_QSTRING("σ")); - - // making all test blocks invisible at starting. - ui.pbLeveneTest->hide(); - ui.lCategorical->hide(); - ui.chbCategorical->hide(); - ui.lCol1->hide(); - ui.cbCol1->hide(); - ui.lCol2->hide(); - ui.cbCol2->hide(); - ui.lCol3->hide(); - ui.cbCol3->hide(); - ui.lEqualVariance->hide(); - ui.chbEqualVariance->hide(); - ui.chbEqualVariance->setChecked(true); - ui.lPopulationSigma->hide(); - ui.lPopulationSigma->setToolTip( i18n("Sigma of Population

" - "Hint: Z-Test if preffered over T-Test if this is known")); - ui.chbPopulationSigma->hide(); - ui.lePopulationSigma->hide(); - ui.pbPerformTest->setEnabled(false); - ui.rbH1OneTail2->hide(); - ui.rbH1OneTail1->hide(); - ui.rbH1TwoTail->hide(); - ui.rbH0OneTail1->hide(); - ui.rbH0OneTail2->hide(); - ui.rbH0TwoTail->hide(); - ui.lH0->hide(); - ui.lH1->hide(); - - QString mu = UTF8_QSTRING("μ"); - QString mu0 = UTF8_QSTRING("μₒ"); - - // radio button for null and alternate hypothesis - // for alternative hypothesis (h1) - // one_tail_1 is mu > mu0; one_tail_2 is mu < mu0; two_tail = mu != mu0; - - ui.rbH1OneTail1->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING(">"), mu0)); - ui.rbH1OneTail2->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("<"), mu0)); - ui.rbH1TwoTail->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("≠"), mu0)); - - ui.rbH0OneTail1->setText( i18n("%1 %2 %3",mu, UTF8_QSTRING("≤"), mu0)); - ui.rbH0OneTail2->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("≥"), mu0)); - ui.rbH0TwoTail->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("="), mu0)); - - ui.rbH0TwoTail->setEnabled(false); - ui.rbH0OneTail1->setEnabled(false); - ui.rbH0OneTail2->setEnabled(false); - - - // setting muo and alpha buttons - ui.lMuo->setText( i18n("%1", mu0)); - ui.lAlpha->setText( i18n("%1", UTF8_QSTRING("α"))); - ui.leMuo->setText( i18n("%1", m_populationMean)); - ui.leAlpha->setText( i18n("%1", m_significanceLevel)); - - ui.lMuo->hide(); - ui.lMuo->setToolTip( i18n("Population Mean")); - ui.lAlpha->hide(); - ui.lAlpha->setToolTip( i18n("Significance Level")); - ui.leMuo->hide(); - ui.leAlpha->hide(); - ui.pbPerformTest->setIcon(QIcon::fromTheme("run-build")); - - ui.leMuo->setText( i18n("%1", m_populationMean)); - ui.leAlpha->setText( i18n("%1", m_significanceLevel)); - - // readConnections(); - - // auto* style = ui.bAddRow->style(); - // ui.bAddRow->setIcon(style->standardIcon(QStyle::SP_ArrowRight)); - // ui.bAddRow->setToolTip(i18n("Add the selected field to rows")); - // ui.bRemoveRow->setIcon(style->standardIcon(QStyle::SP_ArrowLeft)); - // ui.bRemoveRow->setToolTip(i18n("Remove the selected field from rows")); - - // ui.bAddColumn->setIcon(style->standardIcon(QStyle::SP_ArrowRight)); - // ui.bAddColumn->setToolTip(i18n("Add the selected field to columns")); - // ui.bRemoveColumn->setIcon(style->standardIcon(QStyle::SP_ArrowLeft)); - // ui.bRemoveColumn->setToolTip(i18n("Remove the selected field from columns")); - - // //add/remove buttons only enabled if something was selected - // ui.bAddRow->setEnabled(false); - // ui.bRemoveRow->setEnabled(false); - // ui.bAddColumn->setEnabled(false); - // ui.bRemoveColumn->setEnabled(false); - - // connect(ui.leName, &QLineEdit::textChanged, this, &HypothesisTestDock::nameChanged); - // connect(ui.leComment, &QLineEdit::textChanged, this, &HypothesisTestDock::commentChanged); - connect(ui.cbDataSourceType, static_cast(&QComboBox::currentIndexChanged), - this, &HypothesisTestDock::dataSourceTypeChanged); - - connect(cbSpreadsheet, &TreeViewComboBox::currentModelIndexChanged, this, &HypothesisTestDock::spreadsheetChanged); - // connect(ui.cbConnection, static_cast(&QComboBox::currentIndexChanged), - // this, &HypothesisTestDock::connectionChanged); - // connect(ui.cbTable, static_cast(&QComboBox::currentIndexChanged), - // this, &HypothesisTestDock::tableChanged); - // connect(ui.bDatabaseManager, &QPushButton::clicked, this, &HypothesisTestDock::showDatabaseManager); - - // connect(ui.bAddRow, &QPushButton::clicked, this, &HypothesisTestDock::addRow); - // connect(ui.bRemoveRow, &QPushButton::clicked, this,&HypothesisTestDock::removeRow); - // connect(ui.bAddColumn, &QPushButton::clicked, this, &HypothesisTestDock::addColumn); - // connect(ui.bRemoveColumn, &QPushButton::clicked, this,&HypothesisTestDock::removeColumn); - - // connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::doTTest); - // connect(ui.cbCol2, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::doTTest); - - // connect(ui.lwFields, &QListWidget::itemSelectionChanged, this, [=]() { - // bool enabled = !ui.lwFields->selectedItems().isEmpty(); - // ui.bAddRow->setEnabled(enabled); - // ui.bAddColumn->setEnabled(enabled); - // }); - - // connect(ui.lwRows, &QListWidget::doubleClicked, this,&HypothesisTestDock::removeRow); - // connect(ui.lwRows, &QListWidget::itemSelectionChanged, this, [=]() { - // ui.bRemoveRow->setEnabled(!ui.lwRows->selectedItems().isEmpty()); - // }); - - // connect(ui.lwColumns, &QListWidget::doubleClicked, this,&HypothesisTestDock::removeColumn); - // connect(ui.lwColumns, &QListWidget::itemSelectionChanged, this, [=]() { - // ui.bRemoveColumn->setEnabled(!ui.lwColumns->selectedItems().isEmpty()); - // }); - - connect(ui.cbTest, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showTestType); - connect(ui.cbTestType, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showHypothesisTest); - // connect(ui.cbTest, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showHypothesisTest); - // connect(ui.cbTestType, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showHypothesisTest); - connect(ui.pbPerformTest, &QPushButton::clicked, this, &HypothesisTestDock::doHypothesisTest); - connect(ui.pbLeveneTest, &QPushButton::clicked, this, &HypothesisTestDock::performLeveneTest); - - - //connecting null hypothesis and alternate hypothesis radio button - connect(ui.rbH1OneTail1, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail1Toggled); - connect(ui.rbH1OneTail2, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail2Toggled); - connect(ui.rbH1TwoTail, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1TwoTailToggled); - - connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::col1IndexChanged); - connect(ui.chbCategorical, &QCheckBox::stateChanged, this, &HypothesisTestDock::changeCbCol2Label); - - connect(ui.chbPopulationSigma, &QCheckBox::stateChanged, this, &HypothesisTestDock::chbPopulationSigmaStateChanged); - - ui.cbTest->setCurrentIndex(0); - emit ui.cbTest->currentIndexChanged(0); - ui.cbTestType->setCurrentIndex(0); - emit ui.cbTestType->currentIndexChanged(0); + //QDEBUG("in hypothesis test constructor "); + ui.setupUi(this); + + ui.cbDataSourceType->addItem(i18n("Spreadsheet")); + ui.cbDataSourceType->addItem(i18n("Database")); + + cbSpreadsheet = new TreeViewComboBox; + ui.gridLayout->addWidget(cbSpreadsheet, 5, 4, 1, 3); + + ui.bDatabaseManager->setIcon(QIcon::fromTheme("network-server-database")); + ui.bDatabaseManager->setToolTip(i18n("Manage connections")); + m_configPath = QStandardPaths::standardLocations(QStandardPaths::AppDataLocation).constFirst() + "sql_connections"; + + // adding item to tests and testtype combo box; + + ui.cbTest->addItem( i18n("T Test"), HypothesisTest::Test::Type::TTest); + ui.cbTest->addItem( i18n("Z Test"), HypothesisTest::Test::Type::ZTest); + ui.cbTest->addItem( i18n("ANOVA"), HypothesisTest::Test::Type::Anova); + + ui.lPopulationSigma->setText( UTF8_QSTRING("σ")); + + // making all test blocks invisible at starting. + ui.pbLeveneTest->hide(); + ui.lCategorical->hide(); + ui.chbCategorical->hide(); + ui.lCol1->hide(); + ui.cbCol1->hide(); + ui.lCol2->hide(); + ui.cbCol2->hide(); + ui.lCol3->hide(); + ui.cbCol3->hide(); + ui.lEqualVariance->hide(); + ui.chbEqualVariance->hide(); + ui.chbEqualVariance->setChecked(true); + ui.lPopulationSigma->hide(); + ui.lPopulationSigma->setToolTip( i18n("Sigma of Population

" + "Hint: Z-Test if preffered over T-Test if this is known")); + ui.chbPopulationSigma->hide(); + ui.lePopulationSigma->hide(); + ui.pbPerformTest->setEnabled(false); + ui.rbH1OneTail2->hide(); + ui.rbH1OneTail1->hide(); + ui.rbH1TwoTail->hide(); + ui.rbH0OneTail1->hide(); + ui.rbH0OneTail2->hide(); + ui.rbH0TwoTail->hide(); + ui.lH0->hide(); + ui.lH1->hide(); + + QString mu = UTF8_QSTRING("μ"); + QString mu0 = UTF8_QSTRING("μₒ"); + + // radio button for null and alternate hypothesis + // for alternative hypothesis (h1) + // one_tail_1 is mu > mu0; one_tail_2 is mu < mu0; two_tail = mu != mu0; + + ui.rbH1OneTail1->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING(">"), mu0)); + ui.rbH1OneTail2->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("<"), mu0)); + ui.rbH1TwoTail->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("≠"), mu0)); + + ui.rbH0OneTail1->setText( i18n("%1 %2 %3",mu, UTF8_QSTRING("≤"), mu0)); + ui.rbH0OneTail2->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("≥"), mu0)); + ui.rbH0TwoTail->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("="), mu0)); + + ui.rbH0TwoTail->setEnabled(false); + ui.rbH0OneTail1->setEnabled(false); + ui.rbH0OneTail2->setEnabled(false); + + + // setting muo and alpha buttons + ui.lMuo->setText( i18n("%1", mu0)); + ui.lAlpha->setText( i18n("%1", UTF8_QSTRING("α"))); + ui.leMuo->setText( i18n("%1", m_populationMean)); + ui.leAlpha->setText( i18n("%1", m_significanceLevel)); + + ui.lMuo->hide(); + ui.lMuo->setToolTip( i18n("Population Mean")); + ui.lAlpha->hide(); + ui.lAlpha->setToolTip( i18n("Significance Level")); + ui.leMuo->hide(); + ui.leAlpha->hide(); + ui.pbPerformTest->setIcon(QIcon::fromTheme("run-build")); + + ui.leMuo->setText( i18n("%1", m_populationMean)); + ui.leAlpha->setText( i18n("%1", m_significanceLevel)); + + // readConnections(); + + // auto* style = ui.bAddRow->style(); + // ui.bAddRow->setIcon(style->standardIcon(QStyle::SP_ArrowRight)); + // ui.bAddRow->setToolTip(i18n("Add the selected field to rows")); + // ui.bRemoveRow->setIcon(style->standardIcon(QStyle::SP_ArrowLeft)); + // ui.bRemoveRow->setToolTip(i18n("Remove the selected field from rows")); + + // ui.bAddColumn->setIcon(style->standardIcon(QStyle::SP_ArrowRight)); + // ui.bAddColumn->setToolTip(i18n("Add the selected field to columns")); + // ui.bRemoveColumn->setIcon(style->standardIcon(QStyle::SP_ArrowLeft)); + // ui.bRemoveColumn->setToolTip(i18n("Remove the selected field from columns")); + + // //add/remove buttons only enabled if something was selected + // ui.bAddRow->setEnabled(false); + // ui.bRemoveRow->setEnabled(false); + // ui.bAddColumn->setEnabled(false); + // ui.bRemoveColumn->setEnabled(false); + + // connect(ui.leName, &QLineEdit::textChanged, this, &HypothesisTestDock::nameChanged); + // connect(ui.leComment, &QLineEdit::textChanged, this, &HypothesisTestDock::commentChanged); + connect(ui.cbDataSourceType, static_cast(&QComboBox::currentIndexChanged), + this, &HypothesisTestDock::dataSourceTypeChanged); + + connect(cbSpreadsheet, &TreeViewComboBox::currentModelIndexChanged, this, &HypothesisTestDock::spreadsheetChanged); + // connect(ui.cbConnection, static_cast(&QComboBox::currentIndexChanged), + // this, &HypothesisTestDock::connectionChanged); + // connect(ui.cbTable, static_cast(&QComboBox::currentIndexChanged), + // this, &HypothesisTestDock::tableChanged); + // connect(ui.bDatabaseManager, &QPushButton::clicked, this, &HypothesisTestDock::showDatabaseManager); + + // connect(ui.bAddRow, &QPushButton::clicked, this, &HypothesisTestDock::addRow); + // connect(ui.bRemoveRow, &QPushButton::clicked, this,&HypothesisTestDock::removeRow); + // connect(ui.bAddColumn, &QPushButton::clicked, this, &HypothesisTestDock::addColumn); + // connect(ui.bRemoveColumn, &QPushButton::clicked, this,&HypothesisTestDock::removeColumn); + + // connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::doTTest); + // connect(ui.cbCol2, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::doTTest); + + // connect(ui.lwFields, &QListWidget::itemSelectionChanged, this, [=]() { + // bool enabled = !ui.lwFields->selectedItems().isEmpty(); + // ui.bAddRow->setEnabled(enabled); + // ui.bAddColumn->setEnabled(enabled); + // }); + + // connect(ui.lwRows, &QListWidget::doubleClicked, this,&HypothesisTestDock::removeRow); + // connect(ui.lwRows, &QListWidget::itemSelectionChanged, this, [=]() { + // ui.bRemoveRow->setEnabled(!ui.lwRows->selectedItems().isEmpty()); + // }); + + // connect(ui.lwColumns, &QListWidget::doubleClicked, this,&HypothesisTestDock::removeColumn); + // connect(ui.lwColumns, &QListWidget::itemSelectionChanged, this, [=]() { + // ui.bRemoveColumn->setEnabled(!ui.lwColumns->selectedItems().isEmpty()); + // }); + + connect(ui.cbTest, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showTestType); + connect(ui.cbTestType, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showHypothesisTest); + // connect(ui.cbTest, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showHypothesisTest); + // connect(ui.cbTestType, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::showHypothesisTest); + connect(ui.pbPerformTest, &QPushButton::clicked, this, &HypothesisTestDock::doHypothesisTest); + connect(ui.pbLeveneTest, &QPushButton::clicked, this, &HypothesisTestDock::performLeveneTest); + + + //connecting null hypothesis and alternate hypothesis radio button + connect(ui.rbH1OneTail1, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail1Toggled); + connect(ui.rbH1OneTail2, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail2Toggled); + connect(ui.rbH1TwoTail, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1TwoTailToggled); + + connect(ui.cbCol1, static_cast(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::col1IndexChanged); + connect(ui.chbCategorical, &QCheckBox::stateChanged, this, &HypothesisTestDock::changeCbCol2Label); + + connect(ui.chbPopulationSigma, &QCheckBox::stateChanged, this, &HypothesisTestDock::chbPopulationSigmaStateChanged); + + ui.cbTest->setCurrentIndex(0); + emit ui.cbTest->currentIndexChanged(0); + ui.cbTestType->setCurrentIndex(0); + emit ui.cbTestType->currentIndexChanged(0); } void HypothesisTestDock::setHypothesisTest(HypothesisTest* HypothesisTest) { - //QDEBUG("in set hypothesis test"); - m_initializing = true; - m_hypothesisTest = HypothesisTest; + //QDEBUG("in set hypothesis test"); + m_initializing = true; + m_hypothesisTest = HypothesisTest; - m_aspectTreeModel = new AspectTreeModel(m_hypothesisTest->project()); + m_aspectTreeModel = new AspectTreeModel(m_hypothesisTest->project()); - QList list{AspectType::Folder, AspectType::Workbook, - AspectType::Spreadsheet, AspectType::LiveDataSource}; - cbSpreadsheet->setTopLevelClasses(list); + QList list{AspectType::Folder, AspectType::Workbook, + AspectType::Spreadsheet, AspectType::LiveDataSource}; + cbSpreadsheet->setTopLevelClasses(list); - list = {AspectType::Spreadsheet, AspectType::LiveDataSource}; - m_aspectTreeModel->setSelectableAspects(list); + list = {AspectType::Spreadsheet, AspectType::LiveDataSource}; + m_aspectTreeModel->setSelectableAspects(list); - cbSpreadsheet->setModel(m_aspectTreeModel); + cbSpreadsheet->setModel(m_aspectTreeModel); - //show the properties - ui.leName->setText(m_hypothesisTest->name()); - ui.leComment->setText(m_hypothesisTest->comment()); - ui.cbDataSourceType->setCurrentIndex(m_hypothesisTest->dataSourceType()); - if (m_hypothesisTest->dataSourceType() == HypothesisTest::DataSourceType::DataSourceSpreadsheet) - setModelIndexFromAspect(cbSpreadsheet, m_hypothesisTest->dataSourceSpreadsheet()); - // else - // ui.cbConnection->setCurrentIndex(ui.cbConnection->findText(m_hypothesisTest->dataSourceConnection())); + //show the properties + ui.leName->setText(m_hypothesisTest->name()); + ui.leComment->setText(m_hypothesisTest->comment()); + ui.cbDataSourceType->setCurrentIndex(m_hypothesisTest->dataSourceType()); + if (m_hypothesisTest->dataSourceType() == HypothesisTest::DataSourceType::DataSourceSpreadsheet) + setModelIndexFromAspect(cbSpreadsheet, m_hypothesisTest->dataSourceSpreadsheet()); + // else + // ui.cbConnection->setCurrentIndex(ui.cbConnection->findText(m_hypothesisTest->dataSourceConnection())); - setColumnsComboBoxModel(m_hypothesisTest->dataSourceSpreadsheet()); + setColumnsComboBoxModel(m_hypothesisTest->dataSourceSpreadsheet()); - this->dataSourceTypeChanged(ui.cbDataSourceType->currentIndex()); + this->dataSourceTypeChanged(ui.cbDataSourceType->currentIndex()); - //setting rows and columns in combo box; + //setting rows and columns in combo box; - //undo functions - // connect(m_hypothesisTest, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(hypothesisTestDescriptionChanged(const AbstractAspect*))); + //undo functions + // connect(m_hypothesisTest, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(hypothesisTestDescriptionChanged(const AbstractAspect*))); - m_initializing = false; + m_initializing = false; } void HypothesisTestDock::showTestType() { - //QDEBUG("in show test type"); - m_test.type = HypothesisTest::Test::Type(ui.cbTest->currentData().toInt()); - - ui.cbTestType->clear(); - if (m_test.type & (HypothesisTest::Test::Type::TTest | HypothesisTest::Test::Type::ZTest)) { - ui.cbTestType->addItem( i18n("Two Sample Independent"), HypothesisTest::Test::SubType::TwoSampleIndependent); - ui.cbTestType->addItem( i18n("Two Sample Paired"), HypothesisTest::Test::SubType::TwoSamplePaired); - ui.cbTestType->addItem( i18n("One Sample"), HypothesisTest::Test::SubType::OneSample); - } else if (m_test.type & HypothesisTest::Test::Type::Anova) { - ui.cbTestType->addItem( i18n("One Way"), HypothesisTest::Test::SubType::OneWay); - ui.cbTestType->addItem( i18n("Two Way"), HypothesisTest::Test::SubType::TwoWay); - } + //QDEBUG("in show test type"); + m_test.type = HypothesisTest::Test::Type(ui.cbTest->currentData().toInt()); + + ui.cbTestType->clear(); + if (m_test.type & (HypothesisTest::Test::Type::TTest | HypothesisTest::Test::Type::ZTest)) { + ui.cbTestType->addItem( i18n("Two Sample Independent"), HypothesisTest::Test::SubType::TwoSampleIndependent); + ui.cbTestType->addItem( i18n("Two Sample Paired"), HypothesisTest::Test::SubType::TwoSamplePaired); + ui.cbTestType->addItem( i18n("One Sample"), HypothesisTest::Test::SubType::OneSample); + } else if (m_test.type & HypothesisTest::Test::Type::Anova) { + ui.cbTestType->addItem( i18n("One Way"), HypothesisTest::Test::SubType::OneWay); + ui.cbTestType->addItem( i18n("Two Way"), HypothesisTest::Test::SubType::TwoWay); + } } void HypothesisTestDock::showHypothesisTest() { - //QDEBUG("in showHypothesisTest"); + //QDEBUG("in showHypothesisTest"); - if (ui.cbTestType->count() == 0) - return; + if (ui.cbTestType->count() == 0) + return; - m_test.subtype = HypothesisTest::Test::SubType(ui.cbTestType->currentData().toInt()); + m_test.subtype = HypothesisTest::Test::SubType(ui.cbTestType->currentData().toInt()); - ui.lCol1->show(); - ui.cbCol1->show(); + ui.lCol1->show(); + ui.cbCol1->show(); - ui.lCol2->setVisible(bool(m_test.subtype & (~HypothesisTest::Test::SubType::OneSample))); - ui.cbCol2->setVisible(bool(m_test.subtype & (~HypothesisTest::Test::SubType::OneSample))); + ui.lCol2->setVisible(bool(m_test.subtype & (~HypothesisTest::Test::SubType::OneSample))); + ui.cbCol2->setVisible(bool(m_test.subtype & (~HypothesisTest::Test::SubType::OneSample))); - ui.lCol3->setVisible(bool(m_test.type & (HypothesisTest::Test::Anova) & - setAllBits(m_test.subtype & HypothesisTest::Test::SubType::TwoWay))); - ui.cbCol3->setVisible(bool(m_test.type & (HypothesisTest::Test::Anova) & - setAllBits(m_test.subtype & HypothesisTest::Test::SubType::TwoWay))); + ui.lCol3->setVisible(bool(m_test.type & (HypothesisTest::Test::Anova) & + setAllBits(m_test.subtype & HypothesisTest::Test::SubType::TwoWay))); + ui.cbCol3->setVisible(bool(m_test.type & (HypothesisTest::Test::Anova) & + setAllBits(m_test.subtype & HypothesisTest::Test::SubType::TwoWay))); - ui.lEqualVariance->setVisible(bool( (m_test.type & HypothesisTest::Test::Type::TTest) & - (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); - ui.chbEqualVariance->setVisible(bool( (m_test.type & HypothesisTest::Test::Type::TTest) & - (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); + ui.lEqualVariance->setVisible(bool( (m_test.type & HypothesisTest::Test::Type::TTest) & + (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); + ui.chbEqualVariance->setVisible(bool( (m_test.type & HypothesisTest::Test::Type::TTest) & + (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); - ui.lCategorical->setVisible(bool((m_test.type & HypothesisTest::Test::Type::TTest) & - (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); - ui.chbCategorical->setVisible(bool((m_test.type & HypothesisTest::Test::Type::TTest) & - (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); - ui.chbEqualVariance->setChecked(true); + ui.lCategorical->setVisible(bool((m_test.type & HypothesisTest::Test::Type::TTest) & + (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); + ui.chbCategorical->setVisible(bool((m_test.type & HypothesisTest::Test::Type::TTest) & + (m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent))); + ui.chbEqualVariance->setChecked(true); - ui.lPopulationSigma->setVisible(bool((m_test.type & (HypothesisTest::Test::Type::TTest | - HypothesisTest::Test::Type::ZTest)) & - ~(setAllBits(m_test.subtype & HypothesisTest::Test::SubType::OneSample)))); + ui.lPopulationSigma->setVisible(bool((m_test.type & (HypothesisTest::Test::Type::TTest | + HypothesisTest::Test::Type::ZTest)) & + ~(setAllBits(m_test.subtype & HypothesisTest::Test::SubType::OneSample)))); - ui.chbPopulationSigma->setVisible(bool((m_test.type & (HypothesisTest::Test::Type::TTest | - HypothesisTest::Test::Type::ZTest)) & - ~(setAllBits(m_test.subtype & HypothesisTest::Test::SubType::OneSample)))); ui.chbPopulationSigma->setChecked(false); + ui.chbPopulationSigma->setVisible(bool((m_test.type & (HypothesisTest::Test::Type::TTest | + HypothesisTest::Test::Type::ZTest)) & + ~(setAllBits(m_test.subtype & HypothesisTest::Test::SubType::OneSample)))); + ui.chbPopulationSigma->setChecked(false); - ui.pbLeveneTest->setVisible(bool((m_test.type & HypothesisTest::Test::Type::Anova & - setAllBits(m_test.subtype & HypothesisTest::Test::SubType::OneWay)) | - (HypothesisTest::Test::Type::TTest & - setAllBits(m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent)))); + ui.pbLeveneTest->setVisible(bool((m_test.type & HypothesisTest::Test::Type::Anova & + setAllBits(m_test.subtype & HypothesisTest::Test::SubType::OneWay)) | + (HypothesisTest::Test::Type::TTest & + setAllBits(m_test.subtype & HypothesisTest::Test::SubType::TwoSampleIndependent)))); - ui.lH1->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH1OneTail1->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH1OneTail2->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH1TwoTail->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.lH1->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.rbH1OneTail1->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.rbH1OneTail2->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.rbH1TwoTail->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.lH0->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH0OneTail1->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH0OneTail2->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH0TwoTail->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.lH0->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.rbH0OneTail1->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.rbH0OneTail2->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); + ui.rbH0TwoTail->setVisible(bool(m_test.type & ~HypothesisTest::Test::Type::Anova)); - ui.rbH1TwoTail->setChecked(true); + ui.rbH1TwoTail->setChecked(true); - ui.lMuo->setVisible(bool(m_test.subtype & HypothesisTest::Test::SubType::OneSample)); - ui.leMuo->setVisible(bool(ui.lMuo->isVisible())); + ui.lMuo->setVisible(bool(m_test.subtype & HypothesisTest::Test::SubType::OneSample)); + ui.leMuo->setVisible(bool(ui.lMuo->isVisible())); - ui.lAlpha->show(); - ui.leAlpha->show(); + ui.lAlpha->show(); + ui.leAlpha->show(); - setColumnsComboBoxView(); + setColumnsComboBoxView(); - ui.pbPerformTest->setEnabled(nonEmptySelectedColumns()); - ui.pbLeveneTest->setEnabled(nonEmptySelectedColumns()); + ui.pbPerformTest->setEnabled(nonEmptySelectedColumns()); + ui.pbLeveneTest->setEnabled(nonEmptySelectedColumns()); } void HypothesisTestDock::doHypothesisTest() { - //QDEBUG("in doHypothesisTest"); - m_hypothesisTest->setPopulationMean(ui.leMuo->text()); - m_hypothesisTest->setSignificanceLevel(ui.leAlpha->text()); + //QDEBUG("in doHypothesisTest"); + m_hypothesisTest->setPopulationMean(ui.leMuo->text()); + m_hypothesisTest->setSignificanceLevel(ui.leAlpha->text()); - QVector cols; + QVector cols; - if (ui.cbCol1->count() == 0) - return; + if (ui.cbCol1->count() == 0) + return; - cols << reinterpret_cast(ui.cbCol1->currentData().toLongLong()); + cols << reinterpret_cast(ui.cbCol1->currentData().toLongLong()); - if (m_test.subtype & HypothesisTest::Test::SubType::TwoWay) - cols << reinterpret_cast(ui.cbCol3->currentData().toLongLong()); + if (m_test.subtype & HypothesisTest::Test::SubType::TwoWay) + cols << reinterpret_cast(ui.cbCol3->currentData().toLongLong()); - if (m_test.subtype & (~HypothesisTest::Test::SubType::OneSample)) - if (ui.cbCol2->count() > 0) - cols << reinterpret_cast(ui.cbCol2->currentData().toLongLong()); + if (m_test.subtype & (~HypothesisTest::Test::SubType::OneSample)) + if (ui.cbCol2->count() > 0) + cols << reinterpret_cast(ui.cbCol2->currentData().toLongLong()); - m_hypothesisTest->setColumns(cols); + m_hypothesisTest->setColumns(cols); - m_hypothesisTest->performTest(m_test, ui.chbCategorical->isChecked(), ui.chbEqualVariance->isChecked()); + m_hypothesisTest->performTest(m_test, ui.chbCategorical->isChecked(), ui.chbEqualVariance->isChecked()); } void HypothesisTestDock::performLeveneTest() { - QVector cols; + QVector cols; - if (ui.cbCol1->count() == 0 || ui.cbCol2->count() == 0) - return; + if (ui.cbCol1->count() == 0 || ui.cbCol2->count() == 0) + return; - cols << reinterpret_cast(ui.cbCol1->currentData().toLongLong()); - cols << reinterpret_cast(ui.cbCol2->currentData().toLongLong()); - m_hypothesisTest->setColumns(cols); + cols << reinterpret_cast(ui.cbCol1->currentData().toLongLong()); + cols << reinterpret_cast(ui.cbCol2->currentData().toLongLong()); + m_hypothesisTest->setColumns(cols); - m_hypothesisTest->setSignificanceLevel(ui.leAlpha->text()); - m_hypothesisTest->performLeveneTest(ui.chbCategorical->isChecked()); + m_hypothesisTest->setSignificanceLevel(ui.leAlpha->text()); + m_hypothesisTest->performLeveneTest(ui.chbCategorical->isChecked()); } void HypothesisTestDock::setModelIndexFromAspect(TreeViewComboBox* cb, const AbstractAspect* aspect) { - if (aspect) - cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(aspect)); - else - cb->setCurrentModelIndex(QModelIndex()); + if (aspect) + cb->setCurrentModelIndex(m_aspectTreeModel->modelIndexOfAspect(aspect)); + else + cb->setCurrentModelIndex(QModelIndex()); } ///*! // shows the database manager where the connections are created and edited. // The selected connection is selected in the connection combo box in this widget. //**/ //void HypothesisTestDock::showDatabaseManager() { // DatabaseManagerDialog* dlg = new DatabaseManagerDialog(this, ui.cbConnection->currentText()); // if (dlg->exec() == QDialog::Accepted) { // //re-read the available connections to be in sync with the changes in DatabaseManager // m_initializing = true; // ui.cbConnection->clear(); // readConnections(); // //select the connection the user has selected in DatabaseManager // const QString& conn = dlg->connection(); // ui.cbConnection->setCurrentIndex(ui.cbConnection->findText(conn)); // m_initializing = false; // connectionChanged(); // } // delete dlg; //} ///*! // loads all available saved connections //*/ //void HypothesisTestDock::readConnections() { // DEBUG("ImportSQLDatabaseWidget: reading available connections"); // KConfig config(m_configPath, KConfig::SimpleConfig); // for (const auto& name : config.groupList()) // ui.cbConnection->addItem(name); //} ///*! // * adds the selected field to the rows // */ //void HypothesisTestDock::addRow() { // QString field = ui.lwFields->currentItem()->text(); // ui.lwRows->addItem(field); // ui.lwFields->takeItem(ui.lwFields->currentRow()); // m_hypothesisTest->addToRows(field); //} ///*! // * removes the selected field from the rows // */ //void HypothesisTestDock::removeRow() { // const QString& field = ui.lwRows->currentItem()->text(); // ui.lwRows->takeItem(ui.lwRows->currentRow()); // m_hypothesisTest->removeFromRows(field); // updateFields(); //} ///*! // * adds the selected field to the columns // */ //void HypothesisTestDock::addColumn() { // QString field = ui.lwFields->currentItem()->text(); // ui.lwColumns->addItem(field); // ui.lwFields->takeItem(ui.lwFields->currentRow()); // m_hypothesisTest->addToColumns(field); //} ///*! // * removes the selected field from the columns // */ //void HypothesisTestDock::removeColumn() { // const QString& field = ui.lwColumns->currentItem()->text(); // ui.lwColumns->takeItem(ui.lwColumns->currentRow()); // m_hypothesisTest->removeFromColumns(field); // updateFields(); //} ///*! // * re-populates the content of the "Fields" list widget by adding the non-selected fields only. // * called when a selected field is removed from rows or columns. // */ //void HypothesisTestDock::updateFields() { // ui.lwFields->clear(); // for (auto dimension : m_hypothesisTest->dimensions()) // if (!fieldSelected(dimension)) // ui.lwFields->addItem(new QListWidgetItem(QIcon::fromTheme("draw-text"), dimension)); // for (auto measure : m_hypothesisTest->measures()) // if (!fieldSelected(measure)) // ui.lwFields->addItem(new QListWidgetItem(measure)); //} ///*! // * return \c true if the field name \c field was selected among rows or columns, // * return \c false otherwise. // * */ //bool HypothesisTestDock::fieldSelected(const QString& field) { // for (int i = 0; icount(); ++i) // if (ui.lwRows->item(i)->text() == field) // return true; // for (int i = 0; icount(); ++i) // if (ui.lwColumns->item(i)->text() == field) // return true; // return false; //} ////************************************************************* ////****** SLOTs for changes triggered in HypothesisTestDock ******* ////************************************************************* //void HypothesisTestDock::nameChanged() { // if (m_initializing) // return; // m_hypothesisTest->setName(ui.leName->text()); //} //void HypothesisTestDock::commentChanged() { // if (m_initializing) // return; // m_hypothesisTest->setComment(ui.leComment->text()); //} void HypothesisTestDock::dataSourceTypeChanged(int index) { - //QDEBUG("in dataSourceTypeChanged"); - HypothesisTest::DataSourceType type = static_cast(index); - bool showDatabase = (type == HypothesisTest::DataSourceType::DataSourceDatabase); - ui.lSpreadsheet->setVisible(!showDatabase); - cbSpreadsheet->setVisible(!showDatabase); - ui.lConnection->setVisible(showDatabase); - ui.cbConnection->setVisible(showDatabase); - ui.bDatabaseManager->setVisible(showDatabase); - ui.lTable->setVisible(showDatabase); - ui.cbTable->setVisible(showDatabase); - - if (m_initializing) - return; - - m_hypothesisTest->setComment(ui.leComment->text()); + //QDEBUG("in dataSourceTypeChanged"); + HypothesisTest::DataSourceType type = static_cast(index); + bool showDatabase = (type == HypothesisTest::DataSourceType::DataSourceDatabase); + ui.lSpreadsheet->setVisible(!showDatabase); + cbSpreadsheet->setVisible(!showDatabase); + ui.lConnection->setVisible(showDatabase); + ui.cbConnection->setVisible(showDatabase); + ui.bDatabaseManager->setVisible(showDatabase); + ui.lTable->setVisible(showDatabase); + ui.cbTable->setVisible(showDatabase); + + if (m_initializing) + return; + + m_hypothesisTest->setComment(ui.leComment->text()); } void HypothesisTestDock::spreadsheetChanged(const QModelIndex& index) { - //QDEBUG("in spreadsheetChanged"); - auto* aspect = static_cast(index.internalPointer()); - Spreadsheet* spreadsheet = dynamic_cast(aspect); - setColumnsComboBoxModel(spreadsheet); - m_hypothesisTest->setDataSourceSpreadsheet(spreadsheet); + //QDEBUG("in spreadsheetChanged"); + auto* aspect = static_cast(index.internalPointer()); + Spreadsheet* spreadsheet = dynamic_cast(aspect); + setColumnsComboBoxModel(spreadsheet); + m_hypothesisTest->setDataSourceSpreadsheet(spreadsheet); } void HypothesisTestDock::changeCbCol2Label() { - //QDEBUG("in changeCbCol2Label"); - if ( (m_test.type & ~HypothesisTest::Test::Type::Anova) & (m_test.subtype & ~HypothesisTest::Test::SubType::TwoSampleIndependent)) { - ui.lCol2->setText( i18n("Independent Var. 2")); - return; - } - - if (ui.cbCol1->count() == 0) return; - - QString selected_text = ui.cbCol1->currentText(); - Column* col1 = m_hypothesisTest->dataSourceSpreadsheet()->column(selected_text); - - if (!ui.chbCategorical->isChecked() && (col1->columnMode() == AbstractColumn::Integer || col1->columnMode() == AbstractColumn::Numeric)) { - ui.lCol2->setText( i18n("Independent Var. 2")); - ui.chbCategorical->setChecked(false); - ui.chbCategorical->setEnabled(true); - } else { - ui.lCol2->setText( i18n("Dependent Var. 1")); - if (!ui.chbCategorical->isChecked()) - ui.chbCategorical->setEnabled(false); - else - ui.chbCategorical->setEnabled(true); - ui.chbCategorical->setChecked(true); - } + //QDEBUG("in changeCbCol2Label"); + if ( (m_test.type & ~HypothesisTest::Test::Type::Anova) & (m_test.subtype & ~HypothesisTest::Test::SubType::TwoSampleIndependent)) { + ui.lCol2->setText( i18n("Independent Var. 2")); + return; + } + + if (ui.cbCol1->count() == 0) return; + + QString selected_text = ui.cbCol1->currentText(); + Column* col1 = m_hypothesisTest->dataSourceSpreadsheet()->column(selected_text); + + if (!ui.chbCategorical->isChecked() && (col1->columnMode() == AbstractColumn::Integer || col1->columnMode() == AbstractColumn::Numeric)) { + ui.lCol2->setText( i18n("Independent Var. 2")); + ui.chbCategorical->setChecked(false); + ui.chbCategorical->setEnabled(true); + } else { + ui.lCol2->setText( i18n("Dependent Var. 1")); + if (!ui.chbCategorical->isChecked()) + ui.chbCategorical->setEnabled(false); + else + ui.chbCategorical->setEnabled(true); + ui.chbCategorical->setChecked(true); + } } void HypothesisTestDock::chbPopulationSigmaStateChanged() { - if (ui.chbPopulationSigma->isVisible() && ui.chbPopulationSigma->isChecked()) - ui.lePopulationSigma->show(); - else - ui.lePopulationSigma->hide(); + if (ui.chbPopulationSigma->isVisible() && ui.chbPopulationSigma->isChecked()) + ui.lePopulationSigma->show(); + else + ui.lePopulationSigma->hide(); } void HypothesisTestDock::col1IndexChanged(int index) { - if (index < 0) return; - changeCbCol2Label(); + if (index < 0) return; + changeCbCol2Label(); } //void HypothesisTestDock::connectionChanged() { // if (ui.cbConnection->currentIndex() == -1) { // ui.lTable->hide(); // ui.cbTable->hide(); // return; // } // //clear the previously shown tables // ui.cbTable->clear(); // ui.lTable->show(); // ui.cbTable->show(); // const QString& connection = ui.cbConnection->currentText(); // //connection name was changed, determine the current connections settings // KConfig config(m_configPath, KConfig::SimpleConfig); // KConfigGroup group = config.group(connection); // //close and remove the previos connection, if available // if (m_db.isOpen()) { // m_db.close(); // QSqlDatabase::removeDatabase(m_db.driverName()); // } // //open the selected connection // //QDEBUG("HypothesisTestDock: connecting to " + connection); // const QString& driver = group.readEntry("Driver"); // m_db = QSqlDatabase::addDatabase(driver); // const QString& dbName = group.readEntry("DatabaseName"); // if (DatabaseManagerWidget::isFileDB(driver)) { // if (!QFile::exists(dbName)) { // KMessageBox::error(this, i18n("Couldn't find the database file '%1'. Please check the connection settings.", dbName), // appendRow i18n("Connection Failed")); // return; // } else // m_db.setDatabaseName(dbName); // } else if (DatabaseManagerWidget::isODBC(driver)) { // if (group.readEntry("CustomConnectionEnabled", false)) // m_db.setDatabaseName(group.readEntry("CustomConnectionString")); // else // m_db.setDatabaseName(dbName); // } else { // m_db.setDatabaseName(dbName); // m_db.setHostName( group.readEntry("HostName") ); // m_db.setPort( group.readEntry("Port", 0) ); // m_db.setUserName( group.readEntry("UserName") ); // m_db.setPassword( group.readEntry("Password") ); // } // WAIT_CURSOR; // if (!m_db.open()) { // RESET_CURSOR; // KMessageBox::error(this, i18n("Failed to connect to the database '%1'. Please check the connection settings.", ui.cbConnection->currentText()) + // QLatin1String("\n\n") + m_db.lastError().databaseText(), // i18n("Connection Failed")); // return; // } // //show all available database tables // if (m_db.tables().size()) { // for (auto table : m_db.tables()) // ui.cbTable->addItem(QIcon::fromTheme("view-form-table"), table); // ui.cbTable->setCurrentIndex(0); // } // RESET_CURSOR; // if (m_initializing) // return; //// m_hypothesisTest->setDataSourceConnection(connection); //} //void HypothesisTestDock::tableChanged() { // const QString& table = ui.cbTable->currentText(); // //show all attributes of the selected table //// for (const auto* col : spreadsheet->children()) { //// QListWidgetItem* item = new QListWidgetItem(col->icon(), col->name()); //// ui.lwFields->addItem(item); //// } // if (m_initializing) // return; //// m_hypothesisTest->setDataSourceTable(table); //} ////************************************************************* ////******** SLOTs for changes triggered in Spreadsheet ********* ////************************************************************* void HypothesisTestDock::hypothesisTestDescriptionChanged(const AbstractAspect* aspect) { - //QDEBUG("in hypothesisTestDescriptionChanged"); + //QDEBUG("in hypothesisTestDescriptionChanged"); - if (m_hypothesisTest != aspect) - return; + if (m_hypothesisTest != aspect) + return; - m_initializing = true; - if (aspect->name() != ui.leName->text()) - ui.leName->setText(aspect->name()); - else if (aspect->comment() != ui.leComment->text()) - ui.leComment->setText(aspect->comment()); + m_initializing = true; + if (aspect->name() != ui.leName->text()) + ui.leName->setText(aspect->name()); + else if (aspect->comment() != ui.leComment->text()) + ui.leComment->setText(aspect->comment()); - m_initializing = false; + m_initializing = false; } ////************************************************************* ////******************** SETTINGS ******************************* ////************************************************************* //void HypothesisTestDock::load() { //} //void HypothesisTestDock::loadConfigFromTemplate(KConfig& config) { // Q_UNUSED(config); //} ///*! // loads saved matrix properties from \c config. // */ //void HypothesisTestDock::loadConfig(KConfig& config) { // Q_UNUSED(config); //} ///*! // saves matrix properties to \c config. // */ //void HypothesisTestDock::saveConfigAsTemplate(KConfig& config) { // Q_UNUSED(config); //} //TODO: Rather than inbuilt slots use own decided slots for checked rather than clicked // for alternate hypothesis // one_tail_1 is mu > mu0; one_tail_2 is mu < mu0; two_tail = mu != mu0; void HypothesisTestDock::onRbH1OneTail1Toggled(bool checked) { - if (!checked) return; - ui.rbH0OneTail1->setChecked(true); - m_test.tail = HypothesisTest::Test::Tail::Positive; + if (!checked) return; + ui.rbH0OneTail1->setChecked(true); + m_test.tail = HypothesisTest::Test::Tail::Positive; } void HypothesisTestDock::onRbH1OneTail2Toggled(bool checked) { - if (!checked) return; - ui.rbH0OneTail2->setChecked(true); - m_test.tail = HypothesisTest::Test::Tail::Negative; + if (!checked) return; + ui.rbH0OneTail2->setChecked(true); + m_test.tail = HypothesisTest::Test::Tail::Negative; } void HypothesisTestDock::onRbH1TwoTailToggled(bool checked) { - if (!checked) return; - ui.rbH0TwoTail->setChecked(true); - m_test.tail = HypothesisTest::Test::Tail::Two; + if (!checked) return; + ui.rbH0TwoTail->setChecked(true); + m_test.tail = HypothesisTest::Test::Tail::Two; } /**************************************Helper Functions********************************************/ void HypothesisTestDock::countPartitions(Column *column, int &np, int &total_rows) { - total_rows = column->rowCount(); - np = 0; - QString cell_value; - QMap discovered_categorical_var; + total_rows = column->rowCount(); + np = 0; + QString cell_value; + QMap discovered_categorical_var; - AbstractColumn::ColumnMode original_col_mode = column->columnMode(); - column->setColumnMode(AbstractColumn::Text); + AbstractColumn::ColumnMode original_col_mode = column->columnMode(); + column->setColumnMode(AbstractColumn::Text); - for (int i = 0; i < total_rows; i++) { - cell_value = column->textAt(i); + for (int i = 0; i < total_rows; i++) { + cell_value = column->textAt(i); - if (cell_value.isEmpty()) { - total_rows = i; - break; - } + if (cell_value.isEmpty()) { + total_rows = i; + break; + } - if (discovered_categorical_var[cell_value]) - continue; + if (discovered_categorical_var[cell_value]) + continue; - discovered_categorical_var[cell_value] = true; - np++; - } - column->setColumnMode(original_col_mode); + discovered_categorical_var[cell_value] = true; + np++; + } + column->setColumnMode(original_col_mode); } void HypothesisTestDock::setColumnsComboBoxModel(Spreadsheet* spreadsheet) { - m_onlyValuesCols.clear(); - m_twoCategoricalCols.clear(); - m_multiCategoricalCols.clear(); - - for (auto* col : spreadsheet->children()) { - if (col->columnMode() == AbstractColumn::Integer || col->columnMode() == AbstractColumn::Numeric) - m_onlyValuesCols.append(col); - else { - int np = 0, n_rows = 0; - countPartitions(col, np, n_rows); - if (np <= 1) - continue; - else if (np == 2) - m_twoCategoricalCols.append(col); - else - m_multiCategoricalCols.append(col); - } - } - setColumnsComboBoxView(); - showHypothesisTest(); + m_onlyValuesCols.clear(); + m_twoCategoricalCols.clear(); + m_multiCategoricalCols.clear(); + + for (auto* col : spreadsheet->children()) { + if (col->columnMode() == AbstractColumn::Integer || col->columnMode() == AbstractColumn::Numeric) + m_onlyValuesCols.append(col); + else { + int np = 0, n_rows = 0; + countPartitions(col, np, n_rows); + if (np <= 1) + continue; + else if (np == 2) + m_twoCategoricalCols.append(col); + else + m_multiCategoricalCols.append(col); + } + } + setColumnsComboBoxView(); + showHypothesisTest(); } //TODO: change from if else to switch case: void HypothesisTestDock::setColumnsComboBoxView() { - ui.cbCol1->clear(); - ui.cbCol2->clear(); - ui.cbCol3->clear(); - - QList::iterator i; - - switch (m_test.type) { - case (HypothesisTest::Test::Type::ZTest): - case (HypothesisTest::Test::Type::TTest): { - switch (m_test.subtype) { - case (HypothesisTest::Test::SubType::TwoSampleIndependent): { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - break; - } - case (HypothesisTest::Test::SubType::TwoSamplePaired): { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - } - break; - } - case (HypothesisTest::Test::SubType::OneSample): { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - break; - } - case HypothesisTest::Test::SubType::OneWay: - case HypothesisTest::Test::SubType::TwoWay: - case HypothesisTest::Test::SubType::NoneSubType: - break; - } - break; - } - case HypothesisTest::Test::Type::Anova: { - switch (m_test.subtype) { - case HypothesisTest::Test::SubType::OneWay: { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - for (i = m_multiCategoricalCols.begin(); i != m_multiCategoricalCols.end(); i++) - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - break; - } - case HypothesisTest::Test::SubType::TwoWay: { - for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) - ui.cbCol2->addItem( (*i)->name(), qint64(*i)); - - for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol3->addItem( (*i)->name(), qint64(*i)); - } - for (i = m_multiCategoricalCols.begin(); i != m_multiCategoricalCols.end(); i++) { - ui.cbCol1->addItem( (*i)->name(), qint64(*i)); - ui.cbCol3->addItem( (*i)->name(), qint64(*i)); - } - break; - } - case HypothesisTest::Test::SubType::TwoSampleIndependent: - case HypothesisTest::Test::SubType::TwoSamplePaired: - case HypothesisTest::Test::SubType::OneSample: - case HypothesisTest::Test::SubType::NoneSubType: - break; - } - break; - } - case HypothesisTest::Test::Type::NoneType: - break; - } + ui.cbCol1->clear(); + ui.cbCol2->clear(); + ui.cbCol3->clear(); + + QList::iterator i; + + switch (m_test.type) { + case (HypothesisTest::Test::Type::ZTest): + case (HypothesisTest::Test::Type::TTest): { + switch (m_test.subtype) { + case (HypothesisTest::Test::SubType::TwoSampleIndependent): { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + break; + } + case (HypothesisTest::Test::SubType::TwoSamplePaired): { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + } + break; + } + case (HypothesisTest::Test::SubType::OneSample): { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + break; + } + case HypothesisTest::Test::SubType::OneWay: + case HypothesisTest::Test::SubType::TwoWay: + case HypothesisTest::Test::SubType::NoneSubType: + break; + } + break; + } + case HypothesisTest::Test::Type::Anova: { + switch (m_test.subtype) { + case HypothesisTest::Test::SubType::OneWay: { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + for (i = m_multiCategoricalCols.begin(); i != m_multiCategoricalCols.end(); i++) + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + break; + } + case HypothesisTest::Test::SubType::TwoWay: { + for (i = m_onlyValuesCols.begin(); i != m_onlyValuesCols.end(); i++) + ui.cbCol2->addItem( (*i)->name(), qint64(*i)); + + for (i = m_twoCategoricalCols.begin(); i != m_twoCategoricalCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol3->addItem( (*i)->name(), qint64(*i)); + } + for (i = m_multiCategoricalCols.begin(); i != m_multiCategoricalCols.end(); i++) { + ui.cbCol1->addItem( (*i)->name(), qint64(*i)); + ui.cbCol3->addItem( (*i)->name(), qint64(*i)); + } + break; + } + case HypothesisTest::Test::SubType::TwoSampleIndependent: + case HypothesisTest::Test::SubType::TwoSamplePaired: + case HypothesisTest::Test::SubType::OneSample: + case HypothesisTest::Test::SubType::NoneSubType: + break; + } + break; + } + case HypothesisTest::Test::Type::NoneType: + break; + } } bool HypothesisTestDock::nonEmptySelectedColumns() { - if ((ui.cbCol1->isVisible() && ui.cbCol1->count() < 1) || - (ui.cbCol2->isVisible() && ui.cbCol2->count() < 1) || - (ui.cbCol3->isVisible() && ui.cbCol3->count() < 1)) - return false; - return true; + if ((ui.cbCol1->isVisible() && ui.cbCol1->count() < 1) || + (ui.cbCol2->isVisible() && ui.cbCol2->count() < 1) || + (ui.cbCol3->isVisible() && ui.cbCol3->count() < 1)) + return false; + return true; } uint8_t HypothesisTestDock::setAllBits(const uint8_t& bits) { - if (!bits) - return 0; - return ~(bits & (bits-1)); + if (!bits) + return 0; + return ~(bits & (bits-1)); } diff --git a/src/kdefrontend/dockwidgets/HypothesisTestDock.h b/src/kdefrontend/dockwidgets/HypothesisTestDock.h index 719535dfb..d7a6f1d21 100644 --- a/src/kdefrontend/dockwidgets/HypothesisTestDock.h +++ b/src/kdefrontend/dockwidgets/HypothesisTestDock.h @@ -1,119 +1,119 @@ /*************************************************************************** File : HypothesisTestDock.h Project : LabPlot Description : widget for hypothesis testing properties -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTESTDOCK_H #define HYPOTHESISTESTDOCK_H #include "backend/generalTest/HypothesisTest.h" #include "ui_hypothesistestdock.h" #include class AbstractAspect; class AspectTreeModel; class HypothesisTest; class TreeViewComboBox; class KConfig; class QScrollArea; class QStandardItemModel; class QStandardItem; class QComboBox; class HypothesisTestDock : public QWidget { Q_OBJECT public: explicit HypothesisTestDock(QWidget*); void setHypothesisTest(HypothesisTest*); private: Ui::HypothesisTestDock ui; bool m_initializing{false}; TreeViewComboBox* cbSpreadsheet{nullptr}; HypothesisTest* m_hypothesisTest{nullptr}; AspectTreeModel* m_aspectTreeModel{nullptr}; QSqlDatabase m_db; QString m_configPath; double m_populationMean{0}; double m_significanceLevel{0.05}; // void load(); // void loadConfig(KConfig&); void setModelIndexFromAspect(TreeViewComboBox*, const AbstractAspect*); // void readConnections(); // void updateFields(); // bool fieldSelected(const QString&); HypothesisTest::Test m_test; QScrollArea* scrollDock; void countPartitions(Column *column, int &np, int &total_rows); void setColumnsComboBoxModel(Spreadsheet* spreadsheet); void setColumnsComboBoxView(); bool nonEmptySelectedColumns(); std::uint8_t setAllBits(const std::uint8_t& bits); QList m_onlyValuesCols; QList m_twoCategoricalCols; QList m_multiCategoricalCols; private slots: //SLOTs for changes triggered in PivotTableDock // void nameChanged(); // void commentChanged(); void dataSourceTypeChanged(int); void showTestType(); void showHypothesisTest(); void doHypothesisTest(); void performLeveneTest(); void spreadsheetChanged(const QModelIndex&); void changeCbCol2Label(); void chbPopulationSigmaStateChanged(); void col1IndexChanged(int index); void onRbH1OneTail1Toggled(bool checked); void onRbH1OneTail2Toggled(bool checked); void onRbH1TwoTailToggled(bool checked); // void connectionChanged(); // void tableChanged(); // void showDatabaseManager(); // //SLOTs for changes triggered in PivotTable - void hypothesisTestDescriptionChanged(const AbstractAspect*); + void hypothesisTestDescriptionChanged(const AbstractAspect*); // void addRow(); // void removeRow(); // void addColumn(); // void removeColumn(); // //save/load template // void loadConfigFromTemplate(KConfig&); // void saveConfigAsTemplate(KConfig&); signals: // void info(const QString&); }; #endif // PIVOTTABLEDOCK_H diff --git a/src/kdefrontend/generalTest/CorrelationCoefficientView.cpp b/src/kdefrontend/generalTest/CorrelationCoefficientView.cpp index 4a5582945..afe217849 100644 --- a/src/kdefrontend/generalTest/CorrelationCoefficientView.cpp +++ b/src/kdefrontend/generalTest/CorrelationCoefficientView.cpp @@ -1,46 +1,46 @@ /*************************************************************************** File : CorrelationCoefficientView.cpp Project : LabPlot Description : View class for Correlation Coefficient' Table -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "CorrelationCoefficientView.h" #include "backend/generalTest/CorrelationCoefficient.h" #include "backend/lib/macros.h" #include "backend/lib/trace.h" /*! \class CorrelationCoefficientView \brief View class for Hypothesis Test \ingroup kdefrontend */ CorrelationCoefficientView::CorrelationCoefficientView(CorrelationCoefficient* CorrelationCoefficient) : GeneralTestView (static_cast(CorrelationCoefficient)), - m_CorrelationCoefficient(CorrelationCoefficient) { + m_CorrelationCoefficient(CorrelationCoefficient) { } CorrelationCoefficientView::~CorrelationCoefficientView() = default; diff --git a/src/kdefrontend/generalTest/CorrelationCoefficientView.h b/src/kdefrontend/generalTest/CorrelationCoefficientView.h index 20c6b3ace..71c93a82c 100644 --- a/src/kdefrontend/generalTest/CorrelationCoefficientView.h +++ b/src/kdefrontend/generalTest/CorrelationCoefficientView.h @@ -1,52 +1,52 @@ /*************************************************************************** File : CorrelationCoefficientView.h Project : LabPlot Description : View class for Correlation Coefficient' -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef CORRELATIONCOEFFICIENTVIEW_H #define CORRELATIONCOEFFICIENTVIEW_H #include "GeneralTestView.h" #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class CorrelationCoefficient; class CorrelationCoefficientView : public GeneralTestView { - Q_OBJECT + Q_OBJECT public: - explicit CorrelationCoefficientView(CorrelationCoefficient*); - ~CorrelationCoefficientView() override; + explicit CorrelationCoefficientView(CorrelationCoefficient*); + ~CorrelationCoefficientView() override; private: - CorrelationCoefficient* m_CorrelationCoefficient; + CorrelationCoefficient* m_CorrelationCoefficient; public slots: private slots: }; #endif // CORRELATIONCOEFFICIENTVIEW_H diff --git a/src/kdefrontend/generalTest/GeneralTestView.cpp b/src/kdefrontend/generalTest/GeneralTestView.cpp index 8e34b0952..a42ab7642 100644 --- a/src/kdefrontend/generalTest/GeneralTestView.cpp +++ b/src/kdefrontend/generalTest/GeneralTestView.cpp @@ -1,198 +1,197 @@ /*************************************************************************** File : GeneralTestView.cpp Project : LabPlot Description : View class for Hypothesis Tests' Table -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "GeneralTestView.h" #include "backend/generalTest/GeneralTest.h" #include "backend/lib/macros.h" #include "backend/lib/trace.h" #include #include #include #include #include #include #include #include #include #include #include /*! \class GeneralTestView \brief View class for Hypothesis Test \ingroup kdefrontend */ GeneralTestView::GeneralTestView(GeneralTest* GeneralTest) : QWidget(), - m_generalTest(GeneralTest), - m_testName(new QLabel()), - m_statsTable(new QTextEdit()), - m_summaryResults(new QWidget()) { + m_generalTest(GeneralTest), + m_testName(new QLabel()), + m_statsTable(new QTextEdit()), + m_summaryResults(new QWidget()) { - m_statsTable->setReadOnly(true); + m_statsTable->setReadOnly(true); - auto* layout = new QVBoxLayout(this); - layout->addWidget(m_testName); - layout->addWidget(m_statsTable); - layout->addWidget(m_summaryResults); - layout->addStretch(1); - init(); + auto* layout = new QVBoxLayout(this); + layout->addWidget(m_testName); + layout->addWidget(m_statsTable); + layout->addWidget(m_summaryResults); + layout->addStretch(1); + init(); } GeneralTestView::~GeneralTestView() { } void GeneralTestView::init() { - initActions(); - initMenus(); + initActions(); + initMenus(); - m_statsTable->setMouseTracking(true); - // m_summaryResults->setStyleSheet("background-color:white; border: 0px; margin: 0px; padding 0px;qproperty-frame: false;"); - connect(m_generalTest, &GeneralTest::changed, this, &GeneralTestView::changed); - connect(m_statsTable, &QTextEdit::cursorPositionChanged, this, &GeneralTestView::cursorPositionChanged); + m_statsTable->setMouseTracking(true); + // m_summaryResults->setStyleSheet("background-color:white; border: 0px; margin: 0px; padding 0px;qproperty-frame: false;"); + connect(m_generalTest, &GeneralTest::changed, this, &GeneralTestView::changed); + connect(m_statsTable, &QTextEdit::cursorPositionChanged, this, &GeneralTestView::cursorPositionChanged); } void GeneralTestView::initActions() { } void GeneralTestView::initMenus() { } void GeneralTestView::clearResult() { - for (int i = 0; i < RESULTLINESCOUNT; i++) - m_resultLine[i]->clear(); + for (int i = 0; i < RESULTLINESCOUNT; i++) + m_resultLine[i]->clear(); } void GeneralTestView::connectActions() { } void GeneralTestView::fillToolBar(QToolBar* toolBar) { - Q_UNUSED(toolBar); + Q_UNUSED(toolBar); } /*! * Populates the menu \c menu with the pivot table and pivot table view relevant actions. * The menu is used * - as the context menu in PivotTableView * - as the "pivot table menu" in the main menu-bar (called form MainWin) * - as a part of the pivot table context menu in project explorer */ void GeneralTestView::createContextMenu(QMenu* menu) { - Q_ASSERT(menu); + Q_ASSERT(menu); } bool GeneralTestView::exportView() { - return true; + return true; } bool GeneralTestView::printView() { - QPrinter printer; - auto* dlg = new QPrintDialog(&printer, this); - dlg->setWindowTitle(i18nc("@title:window", "Print Spreadsheet")); + QPrinter printer; + auto* dlg = new QPrintDialog(&printer, this); + dlg->setWindowTitle(i18nc("@title:window", "Print Spreadsheet")); - bool ret; - if ((ret = dlg->exec()) == QDialog::Accepted) { - print(&printer); - } - delete dlg; - return ret; + bool ret; + if ((ret = dlg->exec()) == QDialog::Accepted) + print(&printer); + delete dlg; + return ret; } bool GeneralTestView::printPreview() { - QPrintPreviewDialog* dlg = new QPrintPreviewDialog(this); - connect(dlg, &QPrintPreviewDialog::paintRequested, this, &GeneralTestView::print); - return dlg->exec(); + QPrintPreviewDialog* dlg = new QPrintPreviewDialog(this); + connect(dlg, &QPrintPreviewDialog::paintRequested, this, &GeneralTestView::print); + return dlg->exec(); } /*! prints the complete spreadsheet to \c printer. */ void GeneralTestView::print(QPrinter* printer) const { - WAIT_CURSOR; - QPainter painter (printer); - RESET_CURSOR; + WAIT_CURSOR; + QPainter painter (printer); + RESET_CURSOR; } void GeneralTestView::changed() { - m_testName->setText(m_generalTest->testName()); + m_testName->setText(m_generalTest->testName()); - if (m_generalTest->statsTable().isEmpty()) - m_statsTable->hide(); - else { - m_statsTable->setHtml(m_generalTest->statsTable()); - m_statsTable->show(); - } + if (m_generalTest->statsTable().isEmpty()) + m_statsTable->hide(); + else { + m_statsTable->setHtml(m_generalTest->statsTable()); + m_statsTable->show(); + } - m_summaryResults->setLayout(m_generalTest->summaryLayout()); + m_summaryResults->setLayout(m_generalTest->summaryLayout()); } void GeneralTestView::cursorPositionChanged() { - QTextCursor cursor = m_statsTable->textCursor(); - cursor.select(QTextCursor::LineUnderCursor); - QMap tooltips = m_generalTest->tooltips(); - if (!cursor.selectedText().isEmpty()) - QToolTip::showText(QCursor::pos(), - QString("%1") - .arg(tooltips.value(cursor.selectedText()))); - else - QToolTip::hideText(); + QTextCursor cursor = m_statsTable->textCursor(); + cursor.select(QTextCursor::LineUnderCursor); + QMap tooltips = m_generalTest->tooltips(); + if (!cursor.selectedText().isEmpty()) + QToolTip::showText(QCursor::pos(), + QString("%1") + .arg(tooltips.value(cursor.selectedText()))); + else + QToolTip::hideText(); } void GeneralTestView::exportToFile(const QString& path, const bool exportHeader, const QString& separator, QLocale::Language language) const { - Q_UNUSED(exportHeader); - Q_UNUSED(separator); - Q_UNUSED(language); - QFile file(path); - if (!file.open(QFile::WriteOnly | QFile::Truncate)) - return; + Q_UNUSED(exportHeader); + Q_UNUSED(separator); + Q_UNUSED(language); + QFile file(path); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) + return; - PERFTRACE("export pivot table to file"); + PERFTRACE("export pivot table to file"); } void GeneralTestView::exportToLaTeX(const QString & path, const bool exportHeaders, const bool gridLines, const bool captions, const bool latexHeaders, const bool skipEmptyRows, const bool exportEntire) const { - Q_UNUSED(exportHeaders); - Q_UNUSED(gridLines); - Q_UNUSED(captions); - Q_UNUSED(latexHeaders); - Q_UNUSED(skipEmptyRows); - Q_UNUSED(exportEntire); - QFile file(path); - if (!file.open(QFile::WriteOnly | QFile::Truncate)) - return; - - PERFTRACE("export pivot table to latex"); + Q_UNUSED(exportHeaders); + Q_UNUSED(gridLines); + Q_UNUSED(captions); + Q_UNUSED(latexHeaders); + Q_UNUSED(skipEmptyRows); + Q_UNUSED(exportEntire); + QFile file(path); + if (!file.open(QFile::WriteOnly | QFile::Truncate)) + return; + + PERFTRACE("export pivot table to latex"); } diff --git a/src/kdefrontend/generalTest/GeneralTestView.h b/src/kdefrontend/generalTest/GeneralTestView.h index e7e127686..c434f7ea5 100644 --- a/src/kdefrontend/generalTest/GeneralTestView.h +++ b/src/kdefrontend/generalTest/GeneralTestView.h @@ -1,86 +1,86 @@ /*************************************************************************** File : GeneralTestView.h Project : LabPlot Description : View class for Hypothesis Tests' -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef GENERALTESTVIEW_H #define GENERALTESTVIEW_H #include #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class Column; class GeneralTest; class AbstractAspect; class QPrinter; class QToolBar; class QLabel; class QTextEdit; #define RESULTLINESCOUNT 10 class GeneralTestView : public QWidget { - Q_OBJECT + Q_OBJECT public: - explicit GeneralTestView(GeneralTest*); - ~GeneralTestView() override; + explicit GeneralTestView(GeneralTest*); + ~GeneralTestView() override; - bool exportView(); - bool printView(); - bool printPreview(); + bool exportView(); + bool printView(); + bool printPreview(); protected: - void init(); - void initActions(); - void initMenus(); - void connectActions(); - - void exportToFile(const QString&, const bool, const QString&, QLocale::Language) const; - void exportToLaTeX(const QString&, const bool exportHeaders, - const bool gridLines, const bool captions, const bool latexHeaders, - const bool skipEmptyRows,const bool exportEntire) const; - - GeneralTest* m_generalTest; - QLabel* m_testName; - QTextEdit* m_statsTable; - QWidget* m_summaryResults{nullptr}; - QLabel* m_resultLine[RESULTLINESCOUNT]; + void init(); + void initActions(); + void initMenus(); + void connectActions(); + + void exportToFile(const QString&, const bool, const QString&, QLocale::Language) const; + void exportToLaTeX(const QString&, const bool exportHeaders, + const bool gridLines, const bool captions, const bool latexHeaders, + const bool skipEmptyRows,const bool exportEntire) const; + + GeneralTest* m_generalTest; + QLabel* m_testName; + QTextEdit* m_statsTable; + QWidget* m_summaryResults{nullptr}; + QLabel* m_resultLine[RESULTLINESCOUNT]; public slots: - void createContextMenu(QMenu*); - void fillToolBar(QToolBar*); - void print(QPrinter*) const; - void changed(); - void cursorPositionChanged(); - void clearResult(); + void createContextMenu(QMenu*); + void fillToolBar(QToolBar*); + void print(QPrinter*) const; + void changed(); + void cursorPositionChanged(); + void clearResult(); protected slots: }; #endif diff --git a/src/kdefrontend/generalTest/HypothesisTestView.cpp b/src/kdefrontend/generalTest/HypothesisTestView.cpp index 54cb2fcb7..a03ad5810 100644 --- a/src/kdefrontend/generalTest/HypothesisTestView.cpp +++ b/src/kdefrontend/generalTest/HypothesisTestView.cpp @@ -1,46 +1,46 @@ /*************************************************************************** File : HypothesisTestView.cpp Project : LabPlot Description : View class for Hypothesis Tests' Table -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "HypothesisTestView.h" #include "backend/generalTest/HypothesisTest.h" #include "backend/lib/macros.h" #include "backend/lib/trace.h" /*! \class HypothesisTestView \brief View class for Hypothesis Test \ingroup kdefrontend */ HypothesisTestView::HypothesisTestView(HypothesisTest* hypothesisTest) : GeneralTestView (static_cast(hypothesisTest)), - m_hypothesisTest(hypothesisTest) { + m_hypothesisTest(hypothesisTest) { } HypothesisTestView::~HypothesisTestView() = default; diff --git a/src/kdefrontend/generalTest/HypothesisTestView.h b/src/kdefrontend/generalTest/HypothesisTestView.h index 46126cb90..04ceefdc3 100644 --- a/src/kdefrontend/generalTest/HypothesisTestView.h +++ b/src/kdefrontend/generalTest/HypothesisTestView.h @@ -1,52 +1,52 @@ /*************************************************************************** File : HypothesisTestView.h Project : LabPlot Description : View class for Hypothesis Tests' -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal(agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef HYPOTHESISTESTVIEW_H #define HYPOTHESISTESTVIEW_H #include "GeneralTestView.h" #include "backend/core/AbstractColumn.h" #include "backend/lib/IntervalAttribute.h" class HypothesisTest; class HypothesisTestView : public GeneralTestView { - Q_OBJECT + Q_OBJECT public: - explicit HypothesisTestView(HypothesisTest*); - ~HypothesisTestView() override; + explicit HypothesisTestView(HypothesisTest*); + ~HypothesisTestView() override; private: - HypothesisTest* m_hypothesisTest; + HypothesisTest* m_hypothesisTest; public slots: private slots: }; #endif diff --git a/tests/stats/anova/AnovaTest.cpp b/tests/stats/anova/AnovaTest.cpp index d29fd0f1e..70444d23c 100644 --- a/tests/stats/anova/AnovaTest.cpp +++ b/tests/stats/anova/AnovaTest.cpp @@ -1,183 +1,185 @@ /*************************************************************************** File : AnovaTest.cpp Project : LabPlot Description : Tests for data correlation -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal (agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "AnovaTest.h" #include "backend/generalTest/HypothesisTest.h" #include "backend/core/AbstractColumn.h" #include "backend/core/column/Column.h" void AnovaTest::oneWayAnova_data() { - QTest::addColumn>("col1Data"); + QTest::addColumn>("col1Data"); QTest::addColumn>("col2Data"); - QTest::addColumn("fValue_expected"); + QTest::addColumn("fValue_expected"); QTest::addColumn("pValue_expected"); // First Sample - QVector col1Data = {"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", - "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", - "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", - "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", - "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5"}; - - QVector col2Data = {1, 43, 15, 40, 8, 17, 30, 34, 34, 26, 1, 7, 22, 30, 40, 15, 20, 9, 14, 15, - 6, 30, 15, 30, 12, 17, 21, 23, 20, 27, -19, -18, -8, -6, -6, -9, -17, -12, -11, -6, - 5, 8, 12, 19, 8, 15, 21, 28, 26, 27, -10, 6, 4, 3, 0, 4, 9, -5, 7, 13, - 38, 20, 20, 28, 11, 17, 15, 27, 24, 23, 28, 26, 34, 32, 24, 29, 30, 24, 34, 23, - -5, -12, -15, -4, -2, -6, -2, -7, -10, -15, -13, -16, -23, -22, -9, -18, -17, -15, -14, -15}; - double fValue_expected = 33.1288915411; - double pValue_expected = 0; - - QTest::newRow("First Sample") << col1Data << col2Data << fValue_expected << pValue_expected; + QVector col1Data = {"1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", "1", + "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", "2", + "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", "3", + "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", "4", + "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5", "5" + }; + + QVector col2Data = {1, 43, 15, 40, 8, 17, 30, 34, 34, 26, 1, 7, 22, 30, 40, 15, 20, 9, 14, 15, + 6, 30, 15, 30, 12, 17, 21, 23, 20, 27, -19, -18, -8, -6, -6, -9, -17, -12, -11, -6, + 5, 8, 12, 19, 8, 15, 21, 28, 26, 27, -10, 6, 4, 3, 0, 4, 9, -5, 7, 13, + 38, 20, 20, 28, 11, 17, 15, 27, 24, 23, 28, 26, 34, 32, 24, 29, 30, 24, 34, 23, + -5, -12, -15, -4, -2, -6, -2, -7, -10, -15, -13, -16, -23, -22, -9, -18, -17, -15, -14, -15 + }; + double fValue_expected = 33.1288915411; + double pValue_expected = 0; + + QTest::newRow("First Sample") << col1Data << col2Data << fValue_expected << pValue_expected; } void AnovaTest::oneWayAnova() { - QFETCH(QVector, col1Data); + QFETCH(QVector, col1Data); QFETCH(QVector, col2Data); - QFETCH(double, fValue_expected); + QFETCH(double, fValue_expected); QFETCH(double, pValue_expected); - Column* col1 = new Column("col1", AbstractColumn::Text); + Column* col1 = new Column("col1", AbstractColumn::Text); Column* col2 = new Column("col2", AbstractColumn::Numeric); - col1->replaceTexts(0, col1Data); + col1->replaceTexts(0, col1Data); col2->replaceValues(0, col2Data); QVector cols; cols << col1 << col2; - HypothesisTest anovaTest("One Way Anova"); - anovaTest.setColumns(cols); + HypothesisTest anovaTest("One Way Anova"); + anovaTest.setColumns(cols); HypothesisTest::Test test; - test.type = HypothesisTest::Test::Type::Anova; - test.subtype = HypothesisTest::Test::SubType::OneWay; + test.type = HypothesisTest::Test::Type::Anova; + test.subtype = HypothesisTest::Test::SubType::OneWay; test.tail = HypothesisTest::Test::Tail::Two; bool categoricalVariable = true; bool equalVariance = true; - anovaTest.performTest(test, categoricalVariable, equalVariance); + anovaTest.performTest(test, categoricalVariable, equalVariance); - double fValue = anovaTest.statisticValue()[0]; - double pValue = anovaTest.pValue()[0]; + double fValue = anovaTest.statisticValue()[0]; + double pValue = anovaTest.pValue()[0]; - QDEBUG("fValue is " << fValue); - QDEBUG("pValue is: " << pValue); - QDEBUG("fValue_expected is " << fValue_expected); - QDEBUG("pValue_expected is: " << pValue_expected); + QDEBUG("fValue is " << fValue); + QDEBUG("pValue is: " << pValue); + QDEBUG("fValue_expected is " << fValue_expected); + QDEBUG("pValue_expected is: " << pValue_expected); - FuzzyCompare(fValue, fValue_expected, 1.e-5); - FuzzyCompare(pValue, pValue_expected, 1.e-5); + FuzzyCompare(fValue, fValue_expected, 1.e-5); + FuzzyCompare(pValue, pValue_expected, 1.e-5); } void AnovaTest::twoWayAnova_data() { - QTest::addColumn>("col1Data"); - QTest::addColumn>("col2Data"); - QTest::addColumn>("col3Data"); - QTest::addColumn("fCol1Value_expected"); - QTest::addColumn("fCol2Value_expected"); - QTest::addColumn("fInteractionValue_expected"); - QTest::addColumn("pCol1Value_expected"); - QTest::addColumn("pCol2Value_expected"); - - // First Sample - // This data set is taken from: http://statweb.stanford.edu/~susan/courses/s141/exanova.pdf - QVector col1Data = {"Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best"}; - QVector col2Data = {"cold", "cold", "cold", "cold", "warm", "warm", "warm", "warm", "hot", "hot", "hot", "hot", "cold", "cold", "cold", "cold", "warm", "warm", "warm", "warm", "hot", "hot", "hot", "hot"}; - QVector col3Data = {4, 5, 6, 5, 7, 9, 8, 12, 10, 12, 11, 9, 6, 6, 4, 4, 13, 15, 12, 12, 12, 13, 10, 13}; - double fCol1Value_expected = 9.80885214008; - double fCol2Value_expected = 48.7193579767; - double fInteractionValue_expected = 3.97227626459; - double pCol1Value_expected = 0.005758; - double pCol2Value_expected = 5.44e-08; + QTest::addColumn>("col1Data"); + QTest::addColumn>("col2Data"); + QTest::addColumn>("col3Data"); + QTest::addColumn("fCol1Value_expected"); + QTest::addColumn("fCol2Value_expected"); + QTest::addColumn("fInteractionValue_expected"); + QTest::addColumn("pCol1Value_expected"); + QTest::addColumn("pCol2Value_expected"); + + // First Sample + // This data set is taken from: http://statweb.stanford.edu/~susan/courses/s141/exanova.pdf + QVector col1Data = {"Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Super", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best", "Best"}; + QVector col2Data = {"cold", "cold", "cold", "cold", "warm", "warm", "warm", "warm", "hot", "hot", "hot", "hot", "cold", "cold", "cold", "cold", "warm", "warm", "warm", "warm", "hot", "hot", "hot", "hot"}; + QVector col3Data = {4, 5, 6, 5, 7, 9, 8, 12, 10, 12, 11, 9, 6, 6, 4, 4, 13, 15, 12, 12, 12, 13, 10, 13}; + double fCol1Value_expected = 9.80885214008; + double fCol2Value_expected = 48.7193579767; + double fInteractionValue_expected = 3.97227626459; + double pCol1Value_expected = 0.005758; + double pCol2Value_expected = 5.44e-08; // double pInteractionValue_expected = 0.037224; - QTest::newRow("detergent vs temperature") << col1Data << col2Data << col3Data << - fCol1Value_expected << fCol2Value_expected << fInteractionValue_expected << - pCol1Value_expected << pCol2Value_expected; + QTest::newRow("detergent vs temperature") << col1Data << col2Data << col3Data << + fCol1Value_expected << fCol2Value_expected << fInteractionValue_expected << + pCol1Value_expected << pCol2Value_expected; } //TODO: check for pValue. In document probabilty is Pr(>F) void AnovaTest::twoWayAnova() { - QFETCH(QVector, col1Data); - QFETCH(QVector, col2Data); - QFETCH(QVector, col3Data); - QFETCH(double, fCol1Value_expected); - QFETCH(double, fCol2Value_expected); - QFETCH(double, fInteractionValue_expected); - QFETCH(double, pCol1Value_expected); - QFETCH(double, pCol2Value_expected); - - Column* col1 = new Column("col1", AbstractColumn::Text); - Column* col2 = new Column("col2", AbstractColumn::Text); - Column* col3 = new Column("col3", AbstractColumn::Numeric); - - col1->replaceTexts(0, col1Data); - col2->replaceTexts(0, col2Data); - col3->replaceValues(0, col3Data); + QFETCH(QVector, col1Data); + QFETCH(QVector, col2Data); + QFETCH(QVector, col3Data); + QFETCH(double, fCol1Value_expected); + QFETCH(double, fCol2Value_expected); + QFETCH(double, fInteractionValue_expected); + QFETCH(double, pCol1Value_expected); + QFETCH(double, pCol2Value_expected); + + Column* col1 = new Column("col1", AbstractColumn::Text); + Column* col2 = new Column("col2", AbstractColumn::Text); + Column* col3 = new Column("col3", AbstractColumn::Numeric); + + col1->replaceTexts(0, col1Data); + col2->replaceTexts(0, col2Data); + col3->replaceValues(0, col3Data); QVector cols; - cols << col1 << col2 << col3; + cols << col1 << col2 << col3; - HypothesisTest anovaTest("Two Way Anova"); - anovaTest.setColumns(cols); + HypothesisTest anovaTest("Two Way Anova"); + anovaTest.setColumns(cols); HypothesisTest::Test test; - test.type = HypothesisTest::Test::Type::Anova; - test.subtype = HypothesisTest::Test::SubType::TwoWay; + test.type = HypothesisTest::Test::Type::Anova; + test.subtype = HypothesisTest::Test::SubType::TwoWay; test.tail = HypothesisTest::Test::Tail::Two; - anovaTest.performTest(test); - double fCol1Value = anovaTest.statisticValue()[0]; - double fCol2Value = anovaTest.statisticValue()[1]; - double fInteractionValue = anovaTest.statisticValue()[2]; - - double pCol1Value = anovaTest.pValue()[0]; - double pCol2Value = anovaTest.pValue()[1]; - - QDEBUG("size of statistic value is " << anovaTest.statisticValue().size()); - QDEBUG("fCol1Value is " << fCol1Value); - QDEBUG("fCol1Value_expected is " << fCol1Value_expected); - QDEBUG("fCol2Value is " << fCol2Value); - QDEBUG("fCol2Value_expected is " << fCol2Value_expected); - QDEBUG("fInteractionValue is " << fInteractionValue); - QDEBUG("fInteractionValue_expected is " << fInteractionValue_expected); - - QDEBUG("pCol1Value is " << pCol1Value); - QDEBUG("pCol1Value_expected is " << pCol1Value_expected); - QDEBUG("pCol2Value is " << pCol2Value); - QDEBUG("pCol2Value_expected is " << pCol2Value_expected); - - FuzzyCompare(fCol1Value, fCol1Value_expected, 1.e-5); - FuzzyCompare(fCol2Value, fCol2Value_expected, 1.e-5); - FuzzyCompare(fInteractionValue, fInteractionValue_expected, 1.e-5); - FuzzyCompare(pCol1Value, pCol1Value_expected, 1.e-5); - FuzzyCompare(pCol2Value, pCol2Value_expected, 1.e-5); + anovaTest.performTest(test); + double fCol1Value = anovaTest.statisticValue()[0]; + double fCol2Value = anovaTest.statisticValue()[1]; + double fInteractionValue = anovaTest.statisticValue()[2]; + + double pCol1Value = anovaTest.pValue()[0]; + double pCol2Value = anovaTest.pValue()[1]; + + QDEBUG("size of statistic value is " << anovaTest.statisticValue().size()); + QDEBUG("fCol1Value is " << fCol1Value); + QDEBUG("fCol1Value_expected is " << fCol1Value_expected); + QDEBUG("fCol2Value is " << fCol2Value); + QDEBUG("fCol2Value_expected is " << fCol2Value_expected); + QDEBUG("fInteractionValue is " << fInteractionValue); + QDEBUG("fInteractionValue_expected is " << fInteractionValue_expected); + + QDEBUG("pCol1Value is " << pCol1Value); + QDEBUG("pCol1Value_expected is " << pCol1Value_expected); + QDEBUG("pCol2Value is " << pCol2Value); + QDEBUG("pCol2Value_expected is " << pCol2Value_expected); + + FuzzyCompare(fCol1Value, fCol1Value_expected, 1.e-5); + FuzzyCompare(fCol2Value, fCol2Value_expected, 1.e-5); + FuzzyCompare(fInteractionValue, fInteractionValue_expected, 1.e-5); + FuzzyCompare(pCol1Value, pCol1Value_expected, 1.e-5); + FuzzyCompare(pCol2Value, pCol2Value_expected, 1.e-5); } QTEST_MAIN(AnovaTest) diff --git a/tests/stats/anova/AnovaTest.h b/tests/stats/anova/AnovaTest.h index df285311e..462eaa0a1 100644 --- a/tests/stats/anova/AnovaTest.h +++ b/tests/stats/anova/AnovaTest.h @@ -1,42 +1,42 @@ /*************************************************************************** File : AnovaTest.h Project : LabPlot Description : Tests for data correlation -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal (agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef ANOVATEST_H #define ANOVATEST_H #include <../../CommonTest.h> class AnovaTest : public CommonTest { Q_OBJECT private slots: - void oneWayAnova_data(); - void oneWayAnova(); + void oneWayAnova_data(); + void oneWayAnova(); - void twoWayAnova_data(); - void twoWayAnova(); + void twoWayAnova_data(); + void twoWayAnova(); }; #endif diff --git a/tests/stats/correlation_coefficient/CorrelationCoefficientTest.cpp b/tests/stats/correlation_coefficient/CorrelationCoefficientTest.cpp index 86c00c699..a03b93576 100644 --- a/tests/stats/correlation_coefficient/CorrelationCoefficientTest.cpp +++ b/tests/stats/correlation_coefficient/CorrelationCoefficientTest.cpp @@ -1,259 +1,259 @@ /*************************************************************************** File : CorrelationCoefficientTest.cpp Project : LabPlot Description : Unit Testing for Correlation Coefficient -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal (agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "CorrelationCoefficientTest.h" #include "backend/generalTest/CorrelationCoefficient.h" #include "backend/core/AbstractColumn.h" #include "backend/core/column/Column.h" void CorrelationCoefficientTest::pearsonCoefficient_data() { - QTest::addColumn>("col1Data"); - QTest::addColumn>("col2Data"); - QTest::addColumn("correlationValue_expected"); - QTest::addColumn("zValue_expected"); + QTest::addColumn>("col1Data"); + QTest::addColumn>("col2Data"); + QTest::addColumn("correlationValue_expected"); + QTest::addColumn("zValue_expected"); - // First Sample - // This sample is taken from: http://learntech.uwe.ac.uk/da/Default.aspx?pageid=1442 - QVector col1Data = {56, 56, 65, 65, 50, 25, 87, 44, 35}; - QVector col2Data = {87, 91, 85, 91, 75, 28, 122, 66, 58}; + // First Sample + // This sample is taken from: http://learntech.uwe.ac.uk/da/Default.aspx?pageid=1442 + QVector col1Data = {56, 56, 65, 65, 50, 25, 87, 44, 35}; + QVector col2Data = {87, 91, 85, 91, 75, 28, 122, 66, 58}; - double correlationValue_expected = 0.96619424909; - double zValue_expected = 0.; + double correlationValue_expected = 0.96619424909; + double zValue_expected = 0.; - QTest::newRow("Sample 1") << col1Data << col2Data << correlationValue_expected << zValue_expected; + QTest::newRow("Sample 1") << col1Data << col2Data << correlationValue_expected << zValue_expected; - // Second Sample - // This sample is taken from: - // https://www.statisticshowto.datasciencecentral.com/probability-and-statistics/correlation-coefficient-formula/ - col1Data = {43, 21, 25, 42, 57, 59}; - col2Data = {99, 65, 79, 75, 87, 81}; + // Second Sample + // This sample is taken from: + // https://www.statisticshowto.datasciencecentral.com/probability-and-statistics/correlation-coefficient-formula/ + col1Data = {43, 21, 25, 42, 57, 59}; + col2Data = {99, 65, 79, 75, 87, 81}; - correlationValue_expected = 0.52980897305; - zValue_expected = 0.; + correlationValue_expected = 0.52980897305; + zValue_expected = 0.; - QTest::newRow("Sample 2") << col1Data << col2Data << correlationValue_expected << zValue_expected; + QTest::newRow("Sample 2") << col1Data << col2Data << correlationValue_expected << zValue_expected; - // Third Sample - // This sample is taken from: - // https://www.myaccountingcourse.com/financial-ratios/correlation-coefficient - col1Data = {8, 8, 6, 5, 7, 6}; - col2Data = {81, 80, 75, 65, 91, 80}; + // Third Sample + // This sample is taken from: + // https://www.myaccountingcourse.com/financial-ratios/correlation-coefficient + col1Data = {8, 8, 6, 5, 7, 6}; + col2Data = {81, 80, 75, 65, 91, 80}; - correlationValue_expected = 0.64755960039; - zValue_expected = 0.; + correlationValue_expected = 0.64755960039; + zValue_expected = 0.; - QTest::newRow("Sample 3") << col1Data << col2Data << correlationValue_expected << zValue_expected; + QTest::newRow("Sample 3") << col1Data << col2Data << correlationValue_expected << zValue_expected; } void CorrelationCoefficientTest::pearsonCoefficient() { - QFETCH(QVector, col1Data); - QFETCH(QVector, col2Data); - QFETCH(double, correlationValue_expected); - QFETCH(double, zValue_expected); + QFETCH(QVector, col1Data); + QFETCH(QVector, col2Data); + QFETCH(double, correlationValue_expected); + QFETCH(double, zValue_expected); - Column* col1 = new Column("col1", AbstractColumn::Numeric); - Column* col2 = new Column("col2", AbstractColumn::Numeric); + Column* col1 = new Column("col1", AbstractColumn::Numeric); + Column* col2 = new Column("col2", AbstractColumn::Numeric); - col1->replaceValues(0, col1Data); - col2->replaceValues(0, col2Data); + col1->replaceValues(0, col1Data); + col2->replaceValues(0, col2Data); - QVector cols; - cols << col1 << col2; + QVector cols; + cols << col1 << col2; - CorrelationCoefficient correlationCoefficientTest("Pearson's R"); - correlationCoefficientTest.setColumns(cols); + CorrelationCoefficient correlationCoefficientTest("Pearson's R"); + correlationCoefficientTest.setColumns(cols); - CorrelationCoefficient::Test test; - test = CorrelationCoefficient::Test::Pearson; + CorrelationCoefficient::Test test; + test = CorrelationCoefficient::Test::Pearson; - bool categoricalVariable = false; + bool categoricalVariable = false; - correlationCoefficientTest.performTest(test, categoricalVariable); + correlationCoefficientTest.performTest(test, categoricalVariable); - double correlationValue = correlationCoefficientTest.correlationValue(); - double zValue = correlationCoefficientTest.statisticValue()[0]; + double correlationValue = correlationCoefficientTest.correlationValue(); + double zValue = correlationCoefficientTest.statisticValue()[0]; - QDEBUG("Correlation Value is " << correlationValue); - QDEBUG("Correlation Value Expected is " << correlationValue_expected); - QDEBUG("Z Value is: " << zValue); - QDEBUG("Z Value Expected is: " << zValue_expected); + QDEBUG("Correlation Value is " << correlationValue); + QDEBUG("Correlation Value Expected is " << correlationValue_expected); + QDEBUG("Z Value is: " << zValue); + QDEBUG("Z Value Expected is: " << zValue_expected); - FuzzyCompare(correlationValue, correlationValue_expected, 1.e-5); - FuzzyCompare(zValue, zValue_expected); + FuzzyCompare(correlationValue, correlationValue_expected, 1.e-5); + FuzzyCompare(zValue, zValue_expected); } void CorrelationCoefficientTest::kendallCoefficient_data() { - QTest::addColumn>("col1Values"); - QTest::addColumn>("col2Values"); - QTest::addColumn>("col1Texts"); - QTest::addColumn>("col2Texts"); - QTest::addColumn("isDouble"); - QTest::addColumn("correlationValue_expected"); - QTest::addColumn("zValue_expected"); - - // First Sample - // This sample is taken from: - // https://www.statsdirect.com/help/nonparametric_methods/kendall_correlation.htm - QVector col1Values = {4, 10, 3, 1, 9, 2, 6, 7, 8, 5}; - QVector col2Values = {5, 8, 6, 2, 10, 3, 9, 4, 7, 1}; - QVector col1Texts; - QVector col2Texts; - - bool isDouble = true; - - double correlationValue_expected = 0.51111114025116; - double zValue_expected = 2.05718265659; - - QTest::newRow("Sample 1") << col1Values << col2Values << col1Texts << col2Texts << isDouble << correlationValue_expected << zValue_expected; - - // Second Sample - // This sample is taken from: - // https://www.statisticshowto.datasciencecentral.com/kendalls-tau/ - col1Texts = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}; - col2Texts = {"A", "B", "D", "C", "F", "E", "H", "G", "J", "I", "L", "K"}; - col1Values = {}; - col2Values = {}; - isDouble = false; - - correlationValue_expected = 0.84848484848; - zValue_expected = 3.84006269541 -; - - QTest::newRow("Sample 2") << col1Values << col2Values << col1Texts << col2Texts << isDouble << correlationValue_expected << zValue_expected; + QTest::addColumn>("col1Values"); + QTest::addColumn>("col2Values"); + QTest::addColumn>("col1Texts"); + QTest::addColumn>("col2Texts"); + QTest::addColumn("isDouble"); + QTest::addColumn("correlationValue_expected"); + QTest::addColumn("zValue_expected"); + + // First Sample + // This sample is taken from: + // https://www.statsdirect.com/help/nonparametric_methods/kendall_correlation.htm + QVector col1Values = {4, 10, 3, 1, 9, 2, 6, 7, 8, 5}; + QVector col2Values = {5, 8, 6, 2, 10, 3, 9, 4, 7, 1}; + QVector col1Texts; + QVector col2Texts; + + bool isDouble = true; + + double correlationValue_expected = 0.51111114025116; + double zValue_expected = 2.05718265659; + + QTest::newRow("Sample 1") << col1Values << col2Values << col1Texts << col2Texts << isDouble << correlationValue_expected << zValue_expected; + + // Second Sample + // This sample is taken from: + // https://www.statisticshowto.datasciencecentral.com/kendalls-tau/ + col1Texts = {"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L"}; + col2Texts = {"A", "B", "D", "C", "F", "E", "H", "G", "J", "I", "L", "K"}; + col1Values = {}; + col2Values = {}; + isDouble = false; + + correlationValue_expected = 0.84848484848; + zValue_expected = 3.84006269541 + ; + + QTest::newRow("Sample 2") << col1Values << col2Values << col1Texts << col2Texts << isDouble << correlationValue_expected << zValue_expected; } void CorrelationCoefficientTest::kendallCoefficient() { - QFETCH(QVector, col1Values); - QFETCH(QVector, col2Values); - QFETCH(QVector, col1Texts); - QFETCH(QVector, col2Texts); - QFETCH(bool, isDouble); - QFETCH(double, correlationValue_expected); - QFETCH(double, zValue_expected); + QFETCH(QVector, col1Values); + QFETCH(QVector, col2Values); + QFETCH(QVector, col1Texts); + QFETCH(QVector, col2Texts); + QFETCH(bool, isDouble); + QFETCH(double, correlationValue_expected); + QFETCH(double, zValue_expected); - Column* col1; - Column* col2; + Column* col1; + Column* col2; - if (isDouble){ - col1 = new Column("col1", AbstractColumn::Numeric); - col2 = new Column("col2", AbstractColumn::Numeric); + if (isDouble) { + col1 = new Column("col1", AbstractColumn::Numeric); + col2 = new Column("col2", AbstractColumn::Numeric); - col1->replaceValues(0, col1Values); - col2->replaceValues(0, col2Values); - } else { - col1 = new Column("col1", AbstractColumn::Text); - col2 = new Column("col2", AbstractColumn::Text); + col1->replaceValues(0, col1Values); + col2->replaceValues(0, col2Values); + } else { + col1 = new Column("col1", AbstractColumn::Text); + col2 = new Column("col2", AbstractColumn::Text); - col1->replaceTexts(0, col1Texts); - col2->replaceTexts(0, col2Texts); - } + col1->replaceTexts(0, col1Texts); + col2->replaceTexts(0, col2Texts); + } - QVector cols; - cols << col1 << col2; + QVector cols; + cols << col1 << col2; - CorrelationCoefficient correlationCoefficientTest("Kendall's Tau"); - correlationCoefficientTest.setColumns(cols); + CorrelationCoefficient correlationCoefficientTest("Kendall's Tau"); + correlationCoefficientTest.setColumns(cols); - CorrelationCoefficient::Test test; - test = CorrelationCoefficient::Test::Kendall; + CorrelationCoefficient::Test test; + test = CorrelationCoefficient::Test::Kendall; - bool categoricalVariable = false; - correlationCoefficientTest.performTest(test, categoricalVariable); + bool categoricalVariable = false; + correlationCoefficientTest.performTest(test, categoricalVariable); - double correlationValue = correlationCoefficientTest.correlationValue(); - double zValue = correlationCoefficientTest.statisticValue()[0]; + double correlationValue = correlationCoefficientTest.correlationValue(); + double zValue = correlationCoefficientTest.statisticValue()[0]; - QDEBUG("Correlation Value is " << correlationValue); - QDEBUG("Correlation Value Expected is " << correlationValue_expected); - QDEBUG("Z Value is: " << zValue); - QDEBUG("Z Value Expected is: " << zValue_expected); + QDEBUG("Correlation Value is " << correlationValue); + QDEBUG("Correlation Value Expected is " << correlationValue_expected); + QDEBUG("Z Value is: " << zValue); + QDEBUG("Z Value Expected is: " << zValue_expected); - FuzzyCompare(correlationValue, correlationValue_expected, 1.e-7); - FuzzyCompare(zValue, zValue_expected, 1.e-7); + FuzzyCompare(correlationValue, correlationValue_expected, 1.e-7); + FuzzyCompare(zValue, zValue_expected, 1.e-7); } void CorrelationCoefficientTest::spearmanCoefficient_data() { - QTest::addColumn>("col1Data"); - QTest::addColumn>("col2Data"); - QTest::addColumn("correlationValue_expected"); + QTest::addColumn>("col1Data"); + QTest::addColumn>("col2Data"); + QTest::addColumn("correlationValue_expected"); - // First Sample - // This sample is taken: - // https://statistics.laerd.com/statistical-guides/spearmans-rank-order-correlation-statistical-guide-2.php - QVector col1Data = {56, 75, 45, 71, 62, 64, 58, 80, 76, 61}; - QVector col2Data = {66, 70, 40, 60, 65, 56, 59, 77, 67, 63}; + // First Sample + // This sample is taken: + // https://statistics.laerd.com/statistical-guides/spearmans-rank-order-correlation-statistical-guide-2.php + QVector col1Data = {56, 75, 45, 71, 62, 64, 58, 80, 76, 61}; + QVector col2Data = {66, 70, 40, 60, 65, 56, 59, 77, 67, 63}; - double correlationValue_expected = 0.67272727272; + double correlationValue_expected = 0.67272727272; - QTest::newRow("Sample 1") << col1Data << col2Data << correlationValue_expected; + QTest::newRow("Sample 1") << col1Data << col2Data << correlationValue_expected; - // Second Sample - // This sample is taken from: - // https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient - col1Data = {106, 86, 100, 101, 99, 103, 97, 113, 112, 110}; - col2Data = {7, 0, 27, 50, 28, 29, 20, 12, 6, 17}; + // Second Sample + // This sample is taken from: + // https://en.wikipedia.org/wiki/Spearman%27s_rank_correlation_coefficient + col1Data = {106, 86, 100, 101, 99, 103, 97, 113, 112, 110}; + col2Data = {7, 0, 27, 50, 28, 29, 20, 12, 6, 17}; - correlationValue_expected = -0.17575757575; + correlationValue_expected = -0.17575757575; - QTest::newRow("Sample 2") << col1Data << col2Data << correlationValue_expected; + QTest::newRow("Sample 2") << col1Data << col2Data << correlationValue_expected; } void CorrelationCoefficientTest::spearmanCoefficient() { - QFETCH(QVector, col1Data); - QFETCH(QVector, col2Data); - QFETCH(double, correlationValue_expected); + QFETCH(QVector, col1Data); + QFETCH(QVector, col2Data); + QFETCH(double, correlationValue_expected); - Column* col1 = new Column("col1", AbstractColumn::Numeric); - Column* col2 = new Column("col2", AbstractColumn::Numeric); + Column* col1 = new Column("col1", AbstractColumn::Numeric); + Column* col2 = new Column("col2", AbstractColumn::Numeric); - col1->replaceValues(0, col1Data); - col2->replaceValues(0, col2Data); + col1->replaceValues(0, col1Data); + col2->replaceValues(0, col2Data); - QVector cols; - cols << col1 << col2; + QVector cols; + cols << col1 << col2; - CorrelationCoefficient correlationCoefficientTest("Spearman Rank"); - correlationCoefficientTest.setColumns(cols); + CorrelationCoefficient correlationCoefficientTest("Spearman Rank"); + correlationCoefficientTest.setColumns(cols); - CorrelationCoefficient::Test test; - test = CorrelationCoefficient::Test::Spearman; + CorrelationCoefficient::Test test; + test = CorrelationCoefficient::Test::Spearman; - bool categoricalVariable = false; + bool categoricalVariable = false; - correlationCoefficientTest.performTest(test, categoricalVariable); + correlationCoefficientTest.performTest(test, categoricalVariable); - double correlationValue = correlationCoefficientTest.correlationValue(); + double correlationValue = correlationCoefficientTest.correlationValue(); - QDEBUG("Correlation Value is " << correlationValue); - QDEBUG("Correlation Value Expected is " << correlationValue_expected); + QDEBUG("Correlation Value is " << correlationValue); + QDEBUG("Correlation Value Expected is " << correlationValue_expected); - FuzzyCompare(correlationValue, correlationValue_expected, 1.e-5); + FuzzyCompare(correlationValue, correlationValue_expected, 1.e-5); } QTEST_MAIN(CorrelationCoefficientTest) diff --git a/tests/stats/correlation_coefficient/CorrelationCoefficientTest.h b/tests/stats/correlation_coefficient/CorrelationCoefficientTest.h index df86b1308..495e9c9b4 100644 --- a/tests/stats/correlation_coefficient/CorrelationCoefficientTest.h +++ b/tests/stats/correlation_coefficient/CorrelationCoefficientTest.h @@ -1,45 +1,45 @@ /*************************************************************************** File : CorrelationCoefficientTest.h Project : LabPlot Description : Unit Testing for Correlation Coefficients -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal (agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #ifndef CORRELATIONCOEFFICIENTTEST_H #define CORRELATIONCOEFFICIENTTEST_H #include <../../CommonTest.h> class CorrelationCoefficientTest : public CommonTest { - Q_OBJECT + Q_OBJECT private slots: - void pearsonCoefficient_data(); - void pearsonCoefficient(); + void pearsonCoefficient_data(); + void pearsonCoefficient(); - void kendallCoefficient_data(); - void kendallCoefficient(); + void kendallCoefficient_data(); + void kendallCoefficient(); - void spearmanCoefficient_data(); - void spearmanCoefficient(); + void spearmanCoefficient_data(); + void spearmanCoefficient(); }; #endif // CORRELATIONCOEFFICIENTTEST_H diff --git a/tests/stats/ttest/TTestTest.cpp b/tests/stats/ttest/TTestTest.cpp index 3be5937d2..807672d9c 100644 --- a/tests/stats/ttest/TTestTest.cpp +++ b/tests/stats/ttest/TTestTest.cpp @@ -1,202 +1,202 @@ /*************************************************************************** File : CorrelationTest.cpp Project : LabPlot Description : Tests for data correlation -------------------------------------------------------------------- Copyright : (C) 2019 Devanshu Agarwal (agarwaldevanshu8@gmail.com) ***************************************************************************/ /*************************************************************************** * * * This program is free software; you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation; either version 2 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program; if not, write to the Free Software * * Foundation, Inc., 51 Franklin Street, Fifth Floor, * * Boston, MA 02110-1301 USA * * * ***************************************************************************/ #include "TTestTest.h" #include "backend/generalTest/HypothesisTest.h" #include "backend/core/AbstractColumn.h" #include "backend/core/column/Column.h" //TODO: Decrease relative errors and increase more floating points for expected values. void TTestTest::twoSampleIndependent_data() { QTest::addColumn>("col1Data"); QTest::addColumn>("col2Data"); QTest::addColumn("tValue_expected"); QTest::addColumn("pValue_expected"); // First Sample // This data set is taken from "JASP" QVector col1Data = {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}; QVector col2Data = {3, 1, 5, 4, 6, 4, 6, 2, 0, 5, 4, 5, 4, 3, 6, 6, 8, 5, 5, 4, 2, 5, 7, 5}; - double tValue_expected = -1.71345710765; - double pValue_expected = 0.100686; + double tValue_expected = -1.71345710765; + double pValue_expected = 0.100686; QTest::newRow("invisible cloak") << col1Data << col2Data << tValue_expected << pValue_expected; // Second Sample // This data set is taken from "JASP" col1Data = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}; col2Data = {42, 46, 43, 10, 55, 17, 26, 60, 62, 53, 37, 42, 33, 37, 41, 42, 19, 55, 54, 28, 20, 48, 85, 24, 56, 43, 59, 58, 52, 71, 62, 43, 54, 49, 57, 61, 33, 44, 46, 67, 43, 49, 57, 53}; - tValue_expected = -2.2665512460934725; - pValue_expected = 0.028629483; + tValue_expected = -2.2665512460934725; + pValue_expected = 0.028629483; QTest::newRow("directed control activities") << col1Data << col2Data << tValue_expected << pValue_expected; } void TTestTest::twoSampleIndependent() { QFETCH(QVector, col1Data); QFETCH(QVector, col2Data); QFETCH(double, tValue_expected); QFETCH(double, pValue_expected); Column* col1 = new Column("col1", AbstractColumn::Numeric); Column* col2 = new Column("col2", AbstractColumn::Numeric); col1->replaceValues(0, col1Data); col2->replaceValues(0, col2Data); QVector cols; cols << col1 << col2; HypothesisTest tTest("Two Sample Independent"); tTest.setColumns(cols); HypothesisTest::Test test; test.type = HypothesisTest::Test::Type::TTest; test.subtype = HypothesisTest::Test::SubType::TwoSampleIndependent; test.tail = HypothesisTest::Test::Tail::Two; bool categoricalVariable = true; bool equalVariance = true; tTest.performTest(test, categoricalVariable, equalVariance); - double tValue = tTest.statisticValue()[0]; - double pValue = tTest.pValue()[0]; + double tValue = tTest.statisticValue()[0]; + double pValue = tTest.pValue()[0]; qDebug() << "tValue is " << tValue; qDebug() << "pValue is: " << pValue; qDebug() << "tValue_expected is " << tValue_expected; qDebug() << "pValue_expected is: " << pValue_expected; - FuzzyCompare(tValue, tValue_expected, 1.e-5); - FuzzyCompare(pValue, pValue_expected, 1.e-5); + FuzzyCompare(tValue, tValue_expected, 1.e-5); + FuzzyCompare(pValue, pValue_expected, 1.e-5); } void TTestTest::twoSamplePaired_data() { QTest::addColumn>("col1Data"); QTest::addColumn>("col2Data"); QTest::addColumn("tValue_expected"); QTest::addColumn("pValue_expected"); // First Sample // This data set is taken from "JASP" // DATA SET:: Moon and Aggression QVector col1Data = {3.33, 3.67, 2.67, 3.33, 3.33, 3.67, 4.67, 2.67, 6, 4.33, 3.33, 0.67, 1.33, 0.33, 2}; QVector col2Data = {0.27, 0.59, 0.32, 0.19, 1.26, 0.11, 0.3, 0.4, 1.59, 0.6, 0.65, 0.69, 1.26, 0.23, 0.38}; - double tValue_expected = 6.451788554; - double pValue_expected = 1.51815e-05; + double tValue_expected = 6.451788554; + double pValue_expected = 1.51815e-05; QTest::newRow("Moon and Aggression") << col1Data << col2Data << tValue_expected << pValue_expected; } void TTestTest::twoSamplePaired() { QFETCH(QVector, col1Data); QFETCH(QVector, col2Data); QFETCH(double, tValue_expected); QFETCH(double, pValue_expected); Column* col1 = new Column("col1", AbstractColumn::Numeric); Column* col2 = new Column("col2", AbstractColumn::Numeric); col1->replaceValues(0, col1Data); col2->replaceValues(0, col2Data); QVector cols; cols << col1 << col2; HypothesisTest tTest("Two Sample Paried"); tTest.setColumns(cols); HypothesisTest::Test test; test.type = HypothesisTest::Test::Type::TTest; test.subtype = HypothesisTest::Test::SubType::TwoSamplePaired; test.tail = HypothesisTest::Test::Tail::Two; tTest.performTest(test); - double tValue = tTest.statisticValue()[0]; - double pValue = tTest.pValue()[0]; + double tValue = tTest.statisticValue()[0]; + double pValue = tTest.pValue()[0]; qDebug() << "tValue is " << tValue; qDebug() << "pValue is: " << pValue; qDebug() << "tValue_expected is " << tValue_expected; qDebug() << "pValue_expected is: " << pValue_expected; - FuzzyCompare(tValue, tValue_expected, 1.e-5); - FuzzyCompare(pValue, pValue_expected, 1.e-5); + FuzzyCompare(tValue, tValue_expected, 1.e-5); + FuzzyCompare(pValue, pValue_expected, 1.e-5); } void TTestTest::oneSample_data() { QTest::addColumn>("col1Data"); QTest::addColumn("populationMean"); QTest::addColumn("tValue_expected"); QTest::addColumn("pValue_expected"); // First Sample // This data set is taken from "JASP" // DATA SET:: Weight Gain; QVector col1Data = {13.2, 8.58, 14.08, 8.58, 10.56, 14.74, 7.92, 13.2, 12.76, 5.72, 11.66, 7.04, 3.08, 15.62, 14.3, 5.5}; double populationMean = 16; - double tValue_expected = -5.823250303; - double pValue_expected = 3.35479e-05; + double tValue_expected = -5.823250303; + double pValue_expected = 3.35479e-05; QTest::newRow("weight gain") << col1Data << populationMean << tValue_expected << pValue_expected; } void TTestTest::oneSample() { QFETCH(QVector, col1Data); QFETCH(double, populationMean); QFETCH(double, tValue_expected); QFETCH(double, pValue_expected); Column* col1 = new Column("col1", AbstractColumn::Numeric); col1->replaceValues(0, col1Data); QVector cols; cols << col1; HypothesisTest tTest("One Sample"); tTest.setColumns(cols); tTest.setPopulationMean(populationMean); HypothesisTest::Test test; test.type = HypothesisTest::Test::Type::TTest; test.subtype = HypothesisTest::Test::SubType::OneSample; test.tail = HypothesisTest::Test::Tail::Two; tTest.performTest(test); - double tValue = tTest.statisticValue()[0]; - double pValue = tTest.pValue()[0]; + double tValue = tTest.statisticValue()[0]; + double pValue = tTest.pValue()[0]; qDebug() << "tValue is " << tValue; qDebug() << "pValue is: " << pValue; qDebug() << "tValue_expected is " << tValue_expected; qDebug() << "pValue_expected is: " << pValue_expected; - FuzzyCompare(tValue, tValue_expected, 1.e-5); - FuzzyCompare(pValue, pValue_expected, 1.e-5); + FuzzyCompare(tValue, tValue_expected, 1.e-5); + FuzzyCompare(pValue, pValue_expected, 1.e-5); } QTEST_MAIN(TTestTest)