diff --git a/src/backend/hypothesis_test/HypothesisTest.cpp b/src/backend/hypothesis_test/HypothesisTest.cpp
index ce3b5939b..506464c4f 100644
--- a/src/backend/hypothesis_test/HypothesisTest.cpp
+++ b/src/backend/hypothesis_test/HypothesisTest.cpp
@@ -1,1015 +1,929 @@
/***************************************************************************
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 "HypothesisTestPrivate.h"
#include "kdefrontend/hypothesis_test/HypothesisTestView.h"
#include "backend/spreadsheet/Spreadsheet.h"
#include "backend/core/column/Column.h"
#include "backend/lib/macros.h"
#include "QDebug"
extern "C" {
#include "backend/nsl/nsl_stats.h"
}
#include
#include
#include
#include
#include
#include
#include
#include
HypothesisTest::HypothesisTest(const QString &name) : AbstractPart(name),
d(new HypothesisTestPrivate(this)) {
}
HypothesisTest::~HypothesisTest() {
delete d;
}
-QAbstractItemModel* HypothesisTest::dataModel() {
- return d->dataModel;
-}
-
-QAbstractItemModel* HypothesisTest::horizontalHeaderModel() {
- return d->horizontalHeaderModel;
-}
-
-QAbstractItemModel* HypothesisTest::verticalHeaderModel() {
- return d->verticalHeaderModel;
-}
-
-QAbstractItemModel* HypothesisTest::resultModel() {
- return d->resultModel;
-}
-
-
void HypothesisTest::setDataSourceType(DataSourceType type) {
if (type != d->dataSourceType) {
d->dataSourceType = type;
}
}
void HypothesisTest::setDataSourceSpreadsheet(Spreadsheet *spreadsheet) {
if (spreadsheet != d->dataSourceSpreadsheet)
d->setDataSourceSpreadsheet(spreadsheet);
}
QStringList HypothesisTest::allColumns() {
return d->all_columns;
}
HypothesisTest::TailType HypothesisTest::tailType() {
return d->tail_type;
}
void HypothesisTest::setPopulationMean(QVariant populationMean) {
d->m_population_mean = populationMean.toDouble();
}
void HypothesisTest::setSignificanceLevel(QVariant alpha) {
d->m_significance_level = alpha.toDouble();
}
void HypothesisTest::setTailType(HypothesisTest::TailType tailType) {
d->tail_type = tailType;
}
void HypothesisTest::setColumns(QVector cols) {
d->m_columns = cols;
}
void HypothesisTest::setColumns(QStringList cols) {
return d->setColumns(cols);
}
HypothesisTest::DataSourceType HypothesisTest::dataSourceType() const {
return d->dataSourceType;
}
void HypothesisTest::performTwoSampleTTest() {
}
void HypothesisTest::performTwoSampleIndependentTTest(bool equal_variance) {
d->performTwoSampleIndependentTest(HypothesisTestPrivate::TestT, equal_variance);
}
void HypothesisTest::performTwoSamplePairedTTest() {
d->performTwoSamplePairedTest(HypothesisTestPrivate::TestT);
}
void HypothesisTest::PerformOneSampleTTest() {
d->PerformOneSampleTest(HypothesisTestPrivate::TestT);
}
void HypothesisTest::performTwoSampleIndependentZTest() {
d->performTwoSampleIndependentTest(HypothesisTestPrivate::TestZ);
}
void HypothesisTest::performTwoSamplePairedZTest() {
d->performTwoSamplePairedTest(HypothesisTestPrivate::TestZ);
}
void HypothesisTest::PerformOneSampleZTest() {
d->PerformOneSampleTest(HypothesisTestPrivate::TestZ);
}
QString HypothesisTest::testName() {
return d->m_currTestName;
}
QString HypothesisTest::statsTable() {
return d->m_stats_table;
}
+QString HypothesisTest::summaryResultText() {
+ return d->m_summary_results;
+}
+
/******************************************************************************
* Private Implementations
* ****************************************************************************/
HypothesisTestPrivate::HypothesisTestPrivate(HypothesisTest* owner) : q(owner) ,
dataModel(new QStandardItemModel) ,
horizontalHeaderModel(new QStandardItemModel) ,
verticalHeaderModel(new QStandardItemModel) ,
resultModel(new QStandardItemModel()){
}
HypothesisTestPrivate::~HypothesisTestPrivate() {
}
void HypothesisTestPrivate::setDataSourceSpreadsheet(Spreadsheet *spreadsheet) {
dataSourceSpreadsheet = spreadsheet;
//setting rows and columns count;
m_rowCount = dataSourceSpreadsheet->rowCount();
m_columnCount = dataSourceSpreadsheet->columnCount();
for (auto* col : dataSourceSpreadsheet->children()) {
all_columns << col->name();
}
}
void HypothesisTestPrivate::setColumns(QStringList cols) {
m_columns.clear();
Column* column = new Column("column");
for (QString col : cols) {
- if (col != "") {
+ if (!cols.isEmpty()) {
column = dataSourceSpreadsheet->column(col);
m_columns.append(column);
}
}
}
/**************************Two Sample Independent *************************************/
void HypothesisTestPrivate::performTwoSampleIndependentTest(TestType test, bool equal_variance) {
dataModel->clear();
horizontalHeaderModel->clear();
verticalHeaderModel->clear();
resultModel->clear();
QMessageBox* msg_box = new QMessageBox();
// checking for cols;
if (m_columns.size() != 2) {
msg_box->setText(i18n("Inappropriate number of columns selected"));
msg_box->exec();
return;
}
int n[2];
double sum[2], mean[2], std[2];
QString col1_name = m_columns[0]->name();
QString col2_name = m_columns[1]->name();
if (m_columns[0]->columnMode() == AbstractColumn::Integer || m_columns[0]->columnMode() == AbstractColumn::Numeric) {
for (int i = 0; i < 2; i++) {
findStats(m_columns[i], n[i], sum[i], mean[i], std[i]);
if (n[i] < 1) {
- msg_box->setText(i18n("atleast one of selected column is empty"));
+ msg_box->setText(i18n("At least one of selected column is empty"));
msg_box->exec();
return;
}
}
}
else {
findStatsCategorical(n, sum, mean, std, col1_name, col2_name);
if (n[0] == -1) {
msg_box->setText(i18n("Unequal size between %1 and %2", m_columns[0]->name(), m_columns[1]->name()));
msg_box->exec();
return;
} else if(n[0] == -2) {
msg_box->setText(i18n("There are more than two categorical variables in %1", m_columns[0]->name()));
msg_box->exec();
return;
} else if (n[0] == 0) {
msg_box->setText(i18n("atleast one of selected column is empty"));
msg_box->exec();
return;
}
}
QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", col1_name, n[0], sum[0], mean[0], std[0], col2_name, n[1], sum[1], mean[1], std[1]};
m_stats_table = getHtmlTable(3, 5, row_major);
switch (test) {
case TestT: {
m_currTestName = i18n("Two Sample Independent T Test for %1 vs %2", col1_name, col2_name);
- double t;
+ double t_value;
int df;
QString temp_msg = "";
double p_value = 0;
-
- resultModel->setRowCount(9);
- resultModel->setColumnCount(1);
+ m_summary_results = "";
if (equal_variance) {
df = n[0] + n[1] - 2;
-
- //Assuming equal variance
double sp = qSqrt( ((n[0]-1)*qPow(std[0],2) + (n[1]-1)*qPow(std[1],2))/df);
- t = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1]));
-
- resultModel->setData(resultModel->index(8, 0), i18n("Assumption: Equal Variance between both populations"), Qt::DisplayRole);
+ t_value = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1]));
} else {
double temp_val;
temp_val = qPow( qPow(std[0], 2)/n[0] + qPow(std[1], 2)/n[1], 2);
temp_val = temp_val / ( (qPow( (qPow(std[0], 2)/n[0]), 2)/(n[0]-1)) + (qPow( (qPow(std[1], 2)/n[1]), 2)/(n[1]-1)));
df = qRound(temp_val);
- t = (mean[0] - mean[1]) / (qSqrt( (qPow(std[0], 2)/n[0]) + (qPow(std[1], 2)/n[1])));
-
- resultModel->setData(resultModel->index(8, 0), i18n("Assumption: Non-Equal Variance between both populations"), Qt::DisplayRole);
+ t_value = (mean[0] - mean[1]) / (qSqrt( (qPow(std[0], 2)/n[0]) + (qPow(std[1], 2)/n[1])));
}
switch (tail_type) {
case HypothesisTest::TailNegative:
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x2265), col2_name);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x3C), col2_name);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(t_value, df);
+ m_summary_results += i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("≥"), col2_name);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("⋖"), col2_name);
break;
case HypothesisTest::TailPositive:
- t *= -1;
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x2264), col2_name);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x3E), col2_name);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ t_value *= -1;
+ p_value = nsl_stats_tdist_p(t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("≤"), col2_name);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING(">"), col2_name);
break;
case HypothesisTest::TailTwo:
- p_value = nsl_stats_tdist_p(t, df) + nsl_stats_tdist_p(-1*t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x3D), col2_name);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(t_value, df) + nsl_stats_tdist_p(-1*t_value, df);
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x2260), col2_name);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("="), col2_name);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("≠"), col2_name);
break;
}
- resultModel->setData(resultModel->index(3, 0), i18n("T value is %1", t), Qt::DisplayRole);
- resultModel->setData(resultModel->index(4, 0), i18n("P value is %1", p_value), Qt::DisplayRole);
- resultModel->setData(resultModel->index(5, 0), i18n("DoF is %1", df), Qt::DisplayRole);
- resultModel->setData(resultModel->index(6, 0), i18n("Significance level is %1", m_significance_level), Qt::DisplayRole);
+
+ m_summary_results += i18n("Significance level is %1
", m_significance_level);
+ m_summary_results += i18n("T Value is %1
", t_value);
if (p_value <= m_significance_level)
temp_msg = i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level);
else
temp_msg = i18n("There is a plausibility for Null Hypothesis to be true");
- resultModel->setData(resultModel->index(4, 0), temp_msg, Qt::ToolTipRole);
- break;
+ m_summary_results += i18n(""
+ " Hover over me %1"
+ "", temp_msg);
+
+// m_summary_results += i18n("
P Value is %1"
+// " %2"
+// "
", p_value, temp_msg);
+
+ m_summary_results += i18n("Degree of Freedom is %1
setRowCount(8);
resultModel->setColumnCount(1);
df = n[0] + n[1] - 2;
//Assuming equal variance
double sp = qSqrt( ((n[0]-1)*qPow(std[0],2) + (n[1]-1)*qPow(std[1],2))/df);
- t = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1]));
-
+ z_value = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1]));
switch (tail_type) {
case HypothesisTest::TailNegative:
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x2265), col2_name);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x3C), col2_name);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(z_value, df);
+ m_summary_results += i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("≥"), col2_name);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("⋖"), col2_name);
break;
case HypothesisTest::TailPositive:
- t *= -1;
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x2264), col2_name);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x3E), col2_name);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ z_value *= -1;
+ p_value = nsl_stats_tdist_p(z_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("≤"), col2_name);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING(">"), col2_name);
break;
case HypothesisTest::TailTwo:
- p_value = nsl_stats_tdist_p(t, df) + nsl_stats_tdist_p(-1*t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x3D), col2_name);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", col1_name, QChar(0x2260), col2_name);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(z_value, df) + nsl_stats_tdist_p(-1*z_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("="), col2_name);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", col1_name, UTF8_QSTRING("≠"), col2_name);
break;
}
- resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", t), Qt::DisplayRole);
+ resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", z_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(4, 0), i18n("P value is %1", p_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(5, 0), i18n("Significance level is %1", m_significance_level), Qt::DisplayRole);
resultModel->setData(resultModel->index(7, 0), i18n("Assumption: Central Limit Theorem is Valid"), Qt::DisplayRole);
if (p_value <= m_significance_level)
temp_msg = i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level);
else
temp_msg = i18n("There is a plausibility for Null Hypothesis to be true");
// tool tips
resultModel->setData(resultModel->index(4, 0), temp_msg, Qt::ToolTipRole);
// resultModel->setData(resultModel->index(0, 0), QIcon("open.xpm"), Qt::DecorationRole);
break;
}
}
emit q->changed();
return;
}
/********************************Two Sample Paired ***************************************/
void HypothesisTestPrivate::performTwoSamplePairedTest(TestType test) {
dataModel->clear();
horizontalHeaderModel->clear();
verticalHeaderModel->clear();
resultModel->clear();
QMessageBox* msg_box = new QMessageBox();
// checking for cols;
if (m_columns.size() != 2) {
msg_box->setText(i18n("Inappropriate number of columns selected"));
msg_box->exec();
return;
}
bool modeOk = true;
for (int i = 0; i < 2; i++) {
if(m_columns[i]->columnMode() == AbstractColumn::Numeric || m_columns[i]->columnMode() == AbstractColumn::Integer)
continue;
modeOk = false;
}
if (!modeOk) {
msg_box->setText(i18n("select only columns with numbers"));
msg_box->exec();
return;
}
int n;
double sum, mean, std;
findStatsPaired(m_columns[0], m_columns[1], n, sum, mean, std);
if (n == -1) {
msg_box->setText(i18n("both columns are having different sizes"));
msg_box->exec();
return;
}
if (n < 1) {
msg_box->setText(i18n("columns are empty"));
msg_box->exec();
return;
}
QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", "difference", n, sum, mean, std};
m_stats_table = getHtmlTable(2, 5, row_major);
if (test == TestT) {
m_currTestName = i18n("Two Sample Paired T Test for %1 vs %2", m_columns[0]->name(), m_columns[1]->name());
- double t;
+ double t_value;
int df;
QString temp_msg = "";
double p_value = 0;
+ m_summary_results = "";
resultModel->setRowCount(7);
resultModel->setColumnCount(1);
- t = mean / (std/qSqrt(n));
- df = n - 1;
-
-
+ t_value = mean / (std/qSqrt(n));
+ df = n - 1;
switch (tail_type) {
case HypothesisTest::TailNegative:
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x2265), m_columns[1]->name());
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x3C), m_columns[1]->name());
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≥"), m_columns[1]->name());
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("⋖"), m_columns[1]->name());
break;
case HypothesisTest::TailPositive:
- t *= -1;
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x2264), m_columns[1]->name());
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x3E), m_columns[1]->name());
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ t_value *= -1;
+ p_value = nsl_stats_tdist_p(t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≤"), m_columns[1]->name());
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING(">"), m_columns[1]->name());
break;
case HypothesisTest::TailTwo:
- p_value = nsl_stats_tdist_p(t, df) + nsl_stats_tdist_p(-1*t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x3D), m_columns[1]->name());
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x2260), m_columns[1]->name());
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(t_value, df) + nsl_stats_tdist_p(-1*t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("="), m_columns[1]->name());
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≠"), m_columns[1]->name());
break;
}
- resultModel->setData(resultModel->index(3, 0), i18n("T value is %1", t), Qt::DisplayRole);
+ resultModel->setData(resultModel->index(3, 0), i18n("T value is %1", t_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(4, 0), i18n("P value is %1", p_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(5, 0), i18n("DoF is %1", df), Qt::DisplayRole);
resultModel->setData(resultModel->index(6, 0), i18n("Significance level is %1", m_significance_level), Qt::DisplayRole);
if (p_value <= m_significance_level)
temp_msg = i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level);
else
temp_msg = i18n("There is a plausibility for Null Hypothesis to be true");
// tool tips
resultModel->setData(resultModel->index(4, 0), temp_msg, Qt::ToolTipRole);
// resultModel->setData(resultModel->index(0, 0), QIcon("open.xpm"), Qt::DecorationRole);
emit q->changed();
return;
}
else if (test == TestZ) {
m_currTestName = i18n("Two Sample Paired Z Test for %1 vs %2", m_columns[0]->name(), m_columns[1]->name());
- double z;
+ double z_value;
int df;
QString temp_msg = "";
double p_value = 0;
+ m_summary_results = "";
resultModel->setRowCount(8);
resultModel->setColumnCount(1);
- z = mean / (std/qSqrt(n));
+ z_value = mean / (std/qSqrt(n));
df = n - 1;
-
switch (tail_type) {
case HypothesisTest::TailNegative:
- p_value = nsl_stats_tdist_p(z, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x2265), m_columns[1]->name());
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x3C), m_columns[1]->name());
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(z_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≥"), m_columns[1]->name());
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("⋖"), m_columns[1]->name());
break;
case HypothesisTest::TailPositive:
- z *= -1;
- p_value = nsl_stats_tdist_p(z, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x2264), m_columns[1]->name());
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x3E), m_columns[1]->name());
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ z_value *= -1;
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≤"), m_columns[1]->name());
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING(">"), m_columns[1]->name());
break;
case HypothesisTest::TailTwo:
- p_value = nsl_stats_tdist_p(z, df) + nsl_stats_tdist_p(-1*z, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x3D), m_columns[1]->name());
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 Population mean of %3", m_columns[0]->name(), QChar(0x2260), m_columns[1]->name());
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(z_value, df) + nsl_stats_tdist_p(-1*z_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("="), m_columns[1]->name());
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≠"), m_columns[1]->name());
break;
}
-
- resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", z), Qt::DisplayRole);
+ resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", z_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(4, 0), i18n("P value is %1", p_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(5, 0), i18n("Significance level is %1", m_significance_level), Qt::DisplayRole);
resultModel->setData(resultModel->index(7, 0), i18n("Assumption: Central Limit Theorem is Valid"), Qt::DisplayRole);
if (p_value <= m_significance_level)
temp_msg = i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level);
else
temp_msg = i18n("There is a plausibility for Null Hypothesis to be true");
// tool tips
resultModel->setData(resultModel->index(4, 0), temp_msg, Qt::ToolTipRole);
// resultModel->setData(resultModel->index(0, 0), QIcon("open.xpm"), Qt::DecorationRole);
emit q->changed();
return;
}
}
/******************************** One Sample ***************************************/
void HypothesisTestPrivate::PerformOneSampleTest(TestType test) {
dataModel->clear();
horizontalHeaderModel->clear();
verticalHeaderModel->clear();
resultModel->clear();
QMessageBox* msg_box = new QMessageBox();
// checking for cols;
if (m_columns.size() != 1) {
msg_box->setText(i18n("Inappropriate number of columns selected"));
msg_box->exec();
return;
}
if ( !(m_columns[0]->columnMode() == AbstractColumn::Numeric || m_columns[0]->columnMode() == AbstractColumn::Integer)) {
msg_box->setText(i18n("select only columns with numbers"));
msg_box->exec();
return;
}
int n;
double sum, mean, std;
findStats(m_columns[0], n, sum, mean, std);
if (n < 1) {
msg_box->setText(i18n("column is empty"));
msg_box->exec();
return;
}
QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", m_columns[0]->name(), n, sum, mean, std};
m_stats_table = getHtmlTable(2, 5, row_major);
if (test == TestT) {
m_currTestName = i18n("One Sample T Test for %1", m_columns[0]->name());
- double t;
+ double t_value;
int df;
QString temp_msg = "";
double p_value = 0;
+ m_summary_results = "";
resultModel->setRowCount(7);
resultModel->setColumnCount(1);
- t = (mean - m_population_mean) / (std/qSqrt(n));
+ t_value = (mean - m_population_mean) / (std/qSqrt(n));
df = n - 1;
switch (tail_type) {
case HypothesisTest::TailNegative:
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x2265), m_population_mean);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x3C), m_population_mean);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≥"), m_population_mean);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("⋖"), m_population_mean);
break;
case HypothesisTest::TailPositive:
- t *= -1;
- p_value = nsl_stats_tdist_p(t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x2264), m_population_mean);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x3E), m_population_mean);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ t_value *= -1;
+ p_value = nsl_stats_tdist_p(t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≤"), m_population_mean);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING(">"), m_population_mean);
break;
case HypothesisTest::TailTwo:
- p_value = nsl_stats_tdist_p(t, df) + nsl_stats_tdist_p(-1*t, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x3D), m_population_mean);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x2260), m_population_mean);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(t_value, df) + nsl_stats_tdist_p(-1*t_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("="), m_population_mean);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≠"), m_population_mean);
break;
}
- resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", t), Qt::DisplayRole);
+ resultModel->setData(resultModel->index(3, 0), i18n("T value is %1", t_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(4, 0), i18n("P value is %1", p_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(5, 0), i18n("DoF is %1", df), Qt::DisplayRole);
resultModel->setData(resultModel->index(6, 0), i18n("Significance level is %1", m_significance_level), Qt::DisplayRole);
if (p_value <= m_significance_level)
temp_msg = i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level);
else
temp_msg = i18n("There is a plausibility for Null Hypothesis to be true");
// tool tips
resultModel->setData(resultModel->index(4, 0), temp_msg, Qt::ToolTipRole);
// resultModel->setData(resultModel->index(0, 0), QIcon("open.xpm"), Qt::DecorationRole);
emit q->changed();
return;
}
else if (test == TestZ) {
m_currTestName = i18n("One Sample Z Test for %1", m_columns[0]->name());
- double z;
+ double z_value;
int df;
QString temp_msg = "";
double p_value = 0;
+ m_summary_results = "";
resultModel->setRowCount(8);
resultModel->setColumnCount(1);
- z = (mean - m_population_mean) / (std/qSqrt(n));
+ z_value = (mean - m_population_mean) / (std/qSqrt(n));
df = n - 1;
switch (tail_type) {
case HypothesisTest::TailNegative:
- p_value = nsl_stats_tdist_p(z, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x2265), m_population_mean);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x3C), m_population_mean);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(z_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≥"), m_population_mean);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("⋖"), m_population_mean);
break;
case HypothesisTest::TailPositive:
- z *= -1;
- p_value = nsl_stats_tdist_p(z, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x2264), m_population_mean);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x3E), m_population_mean);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ z_value *= -1;
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≤"), m_population_mean);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING(">"), m_population_mean);
break;
case HypothesisTest::TailTwo:
- p_value = nsl_stats_tdist_p(z, df) + nsl_stats_tdist_p(-1*z, df);
-
- temp_msg = i18n("Null Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x3D), m_population_mean);
- resultModel->setData(resultModel->index(0, 0), temp_msg, Qt::DisplayRole);
-
- temp_msg = i18n("Alternate Hypothesis : Population mean of %1 %2 %3", m_columns[0]->name(), QChar(0x2260), m_population_mean);
- resultModel->setData(resultModel->index(1, 0), temp_msg, Qt::DisplayRole);
+ p_value = nsl_stats_tdist_p(z_value, df) + nsl_stats_tdist_p(-1*z_value, df);
+ m_summary_results += i18n("
Null Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("="), m_population_mean);
+ m_summary_results += i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3
", m_columns[0]->name(), UTF8_QSTRING("≠"), m_population_mean);
break;
}
- resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", z), Qt::DisplayRole);
+ resultModel->setData(resultModel->index(3, 0), i18n("Z value is %1", z_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(4, 0), i18n("P value is %1", p_value), Qt::DisplayRole);
resultModel->setData(resultModel->index(5, 0), i18n("Significance level is %1", m_significance_level), Qt::DisplayRole);
resultModel->setData(resultModel->index(7, 0), i18n("Assumption: Central Limit Theorem is Valid"), Qt::DisplayRole);
if (p_value <= m_significance_level)
temp_msg = i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level);
else
temp_msg = i18n("There is a plausibility for Null Hypothesis to be true");
// tool tips
resultModel->setData(resultModel->index(4, 0), temp_msg, Qt::ToolTipRole);
// resultModel->setData(resultModel->index(0, 0), QIcon("open.xpm"), Qt::DecorationRole);
emit q->changed();
return;
}
}
void HypothesisTestPrivate::findStatsPaired(Column* column1, Column* column2, int &count, double &sum, double &mean, double &std) {
sum = 0;
mean = 0;
std = 0;
int count1 = column1->rowCount();
int count2 = column2->rowCount();
count = qMin(count1, count2);
double row1, row2;
for (int i = 0; i < count; i++) {
row1 = column1->valueAt(i);
row2 = column2->valueAt(i);
if (std::isnan(row1) || std::isnan(row2)) {
if (std::isnan(row1) && std::isnan(row2))
count = i;
else {
count = -1;
return;
}
break;
}
sum += row1 - row2;
}
if (count < 1) return;
mean = sum/count;
double row;
for (int i = 0; i < count; i++) {
row1 = column1->valueAt(i);
row2 = column2->valueAt(i);
row = row1 - row2;
std += qPow( (row - mean), 2);
}
if (count > 1)
std = std / (count-1);
std = qSqrt(std);
return;
}
void HypothesisTestPrivate::findStats(Column* column, int &count, double &sum, double &mean, double &std) {
sum = 0;
mean = 0;
std = 0;
count = column->rowCount();
for (int i = 0; i < count; i++) {
double row = column->valueAt(i);
if ( std::isnan(row)) {
count = i;
break;
}
sum += row;
}
if (count < 1) return;
mean = sum/count;
for (int i = 0; i < count; i++) {
double row = column->valueAt(i);
std += qPow( (row - mean), 2);
}
if (count > 1)
std = std / (count-1);
std = qSqrt(std);
return;
}
void HypothesisTestPrivate::findStatsCategorical(int n[], double sum[], double mean[], double std[], QString &col1_name, QString &col2_name) {
/* Error codes;
n[0] = -1 : unequal rows
n[0] = -2 : #categorical variables != 2;
*/
// clearing the variables;
for (int i = 0; i < 2; i++) {
sum[i] = 0;
mean[i] = 0;
std[i] = 0;
n[i] = 0;
}
int count_temp = m_columns[0]->rowCount();
col1_name = "";
col2_name = "";
for (int i = 0; i < count_temp; i++) {
QString name = m_columns[0]->textAt(i);
double value = m_columns[1]->valueAt(i);
if (name == "" || std::isnan(value)) {
if (name == "" && std::isnan(value)) {
break;
} else {
n[0] = -1;
return;
}
}
if (name == col1_name) {
n[0]++;
sum[0] += value;
} else if (name == col2_name) {
n[1]++;
sum[1] += value;
} else if (col1_name == "") {
n[0]++;
sum[0] += value;
col1_name = name;
} else if (col2_name == "") {
n[1]++;
sum[1] += value;
col2_name = name;
}
else {
// this case occurs when there are more than two categorical variables in column 1
// sending error code of -1;
n[0] = -2;
return;
}
}
if (col1_name == "" || col2_name == "") {
n[0] = -2;
return;
}
mean[0] = sum[0]/n[0];
mean[1] = sum[1]/n[1];
for (int i = 0; i < n[0]+n[1]; i++) {
QString name = m_columns[0]->textAt(i);
double value = m_columns[1]->valueAt(i);
if (name == col1_name) {
std[0] += qPow( (value - mean[0]), 2);
} else {
std[1] += qPow( (value - mean[1]), 2);
}
}
for (int i = 0; i < 2; i++) {
if (n[i] > 1)
std[i] = std[i] / (n[i] - 1);
std[i] = qSqrt(std[i]);
}
return;
}
QString HypothesisTestPrivate::getHtmlTable(int row, int column, QVariant *row_major) {
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 = row_major[j].toString();
table += i18n(" %2 | ", bg, element);
}
table += "
";
if (pky)
bg = "tg-0pky";
else
bg = "tg-btxf";
pky = !pky;
for (int i = 1; i < row; i++) {
table += " ";
QString element = row_major[i*column].toString();
table += i18n(" %2 | ", bg, element);
for (int j = 1; j < column; j++) {
QString element = row_major[i*column+j].toString();
table += i18n(" %2 | ", bg, element);
}
table += "
";
if (pky)
bg = "tg-0pky";
else
bg = "tg-btxf";
pky = !pky;
}
table += "
";
return table;
}
+
/**********************************************************************************
* virtual functions implementations
* ********************************************************************************/
/*!
Saves as XML.
*/
void HypothesisTest::save(QXmlStreamWriter* writer) const {
writer->writeStartElement("hypothesisTest");
writeBasicAttributes(writer);
writeCommentElement(writer);
//TODO:
writer->writeEndElement();
}
/*!
Loads from XML.
*/
bool HypothesisTest::load(XmlStreamReader* reader, bool preview) {
Q_UNUSED(preview);
if (!readBasicAttributes(reader))
return false;
//TODO:
return !reader->hasError();
}
Spreadsheet *HypothesisTest::dataSourceSpreadsheet() const {
return d->dataSourceSpreadsheet;
}
bool HypothesisTest::exportView() const {
return true;
}
bool HypothesisTest::printView() {
return true;
}
bool HypothesisTest::printPreview() const {
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* HypothesisTest::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* HypothesisTest::createContextMenu() {
QMenu* menu = AbstractPart::createContextMenu();
// Q_ASSERT(menu);
// emit requestProjectContextMenu(menu);
return menu;
}
diff --git a/src/backend/hypothesis_test/HypothesisTest.h b/src/backend/hypothesis_test/HypothesisTest.h
index 038fad4db..4a5cbb48a 100644
--- a/src/backend/hypothesis_test/HypothesisTest.h
+++ b/src/backend/hypothesis_test/HypothesisTest.h
@@ -1,107 +1,103 @@
/***************************************************************************
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
#include "backend/core/AbstractPart.h"
#include "backend/lib/macros.h"
class HypothesisTestPrivate;
class HypothesisTestView;
class Spreadsheet;
-class QAbstractItemModel;
class QString;
class Column;
class QLayout;
class HypothesisTest : public AbstractPart {
Q_OBJECT
public:
explicit HypothesisTest(const QString& name);
~HypothesisTest() override;
enum DataSourceType {DataSourceSpreadsheet, DataSourceDatabase};
enum TailType {TailPositive, TailNegative, TailTwo};
- QAbstractItemModel* dataModel();
- QAbstractItemModel* horizontalHeaderModel();
- QAbstractItemModel* verticalHeaderModel();
- QAbstractItemModel* resultModel();
-
QString testName();
QString statsTable();
+ QString summaryResultText();
+
void setDataSourceSpreadsheet(Spreadsheet* spreadsheet);
void setColumns(QVector cols);
void setColumns(QStringList cols);
void performTwoSampleTTest();
void performTwoSampleIndependentTTest(bool equal_variance);
void performTwoSamplePairedTTest();
void PerformOneSampleTTest();
void performTwoSampleIndependentZTest();
void performTwoSamplePairedZTest();
void PerformOneSampleZTest();
DataSourceType dataSourceType() const;
//virtual methods
// QIcon icon() const override;
QMenu* createContextMenu() override;
QWidget* view() const override;
bool exportView() const override;
bool printView() override;
bool printPreview() const override;
void save(QXmlStreamWriter*) const override;
bool load(XmlStreamReader*, bool preview) override;
Spreadsheet* dataSourceSpreadsheet() const;
void setDataSourceType(DataSourceType type);
QStringList allColumns();
void setTailType(TailType tailType);
TailType tailType();
void setPopulationMean(QVariant populationMean);
void setSignificanceLevel(QVariant alpha);
private:
HypothesisTestPrivate* const d;
mutable HypothesisTestView* m_view{nullptr};
friend class HypothesisTestPrivate;
signals:
void changed();
void requestProjectContextMenu(QMenu*);
void dataSourceTypeChanged(HypothesisTest::DataSourceType);
void dataSourceSpreadsheetChanged(Spreadsheet*);
};
#endif // HypothesisTest_H
diff --git a/src/backend/hypothesis_test/HypothesisTestPrivate.h b/src/backend/hypothesis_test/HypothesisTestPrivate.h
index 85e19ed05..9ff3ed6ad 100644
--- a/src/backend/hypothesis_test/HypothesisTestPrivate.h
+++ b/src/backend/hypothesis_test/HypothesisTestPrivate.h
@@ -1,87 +1,88 @@
/***************************************************************************
File : HypothesisTestPrivate.h
Project : LabPlot
Description : Private members of Hypothesis Test
--------------------------------------------------------------------
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 HYPOTHESISTESTPRIVATE_H
#define HYPOTHESISTESTPRIVATE_H
#include
class QStandardItemModel;
class HypothesisTestPrivate {
public:
explicit HypothesisTestPrivate(HypothesisTest*);
virtual ~HypothesisTestPrivate();
enum TestType {TestT, TestZ};
QString name() const;
HypothesisTest* const q;
HypothesisTest::DataSourceType dataSourceType{HypothesisTest::DataSourceSpreadsheet};
Spreadsheet* dataSourceSpreadsheet{nullptr};
void setDataSourceSpreadsheet(Spreadsheet* spreadsheet);
void setColumns(QStringList cols);
QVector m_columns;
QStringList all_columns;
QStandardItemModel* dataModel{nullptr};
QStandardItemModel* horizontalHeaderModel{nullptr};
QStandardItemModel* verticalHeaderModel{nullptr};
bool m_dbCreated{false};
int m_rowCount{0};
int m_columnCount{0};
QString m_currTestName{"Result Table"};
double m_population_mean;
double m_significance_level;
QString m_stats_table;
+ QString m_summary_results;
void performTwoSampleIndependentTest(TestType test, bool equal_variance = true);
void performTwoSamplePairedTest(TestType test);
void PerformOneSampleTest(TestType test);
HypothesisTest::TailType tail_type;
QStandardItemModel* resultModel{nullptr};
private:
void findStats(Column* column, int &count, double &sum, double &mean, double &std);
void findStatsPaired(Column *column1, Column *column2, int &count, double &sum, double &mean, double &std);
void findStatsCategorical(int n[2], double sum[2], double mean[2], double std[2], QString &col1_name, QString &col2_name);
QString getHtmlTable(int row, int column, QVariant *row_major);
// QMap m_members;
};
#endif
diff --git a/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp b/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp
index 461ea8ff4..af847af9c 100644
--- a/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp
+++ b/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp
@@ -1,684 +1,682 @@
/***************************************************************************
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/pivot/hypothesisTestView.h"
#include "kdefrontend/TemplateHandler.h"
#include
#include
#include
#include
#include
#include
/*!
\class HypothesisTestDock
\brief Provides a dock (widget) for hypothesis testing:
\ingroup kdefrontend
*/
HypothesisTestDock::HypothesisTestDock(QWidget* parent) : QWidget(parent) {
ui.setupUi(this);
ui.cbDataSourceType->addItem(i18n("Spreadsheet"));
ui.cbDataSourceType->addItem(i18n("Database"));
cbSpreadsheet = new TreeViewComboBox;
ui.gridLayout->addWidget(cbSpreadsheet, 1, 1);
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"));
ui.cbTest->addItem(i18n("Z Test"));
ui.cbTestType->addItem(i18n("Two Sample Independent"));
ui.cbTestType->addItem(i18n("Two Sample Paired"));
ui.cbTestType->addItem(i18n("One Sample"));
// making all test blocks invisible at starting.
ui.lCol1Categorical->setVisible(false);
ui.cbCol1Categorical->setVisible(false);
ui.lCol1->setVisible(false);
ui.cbCol1->setVisible(false);
ui.lCol2->setVisible(false);
ui.cbCol2->setVisible(false);
ui.chbEqualVariance->setVisible(false);
ui.chbEqualVariance->setChecked(true);
ui.pbPerformTest->setEnabled(false);
ui.rb_h1_one_tail_2->setVisible(false);
ui.rb_h1_one_tail_1->setVisible(false);
ui.rb_h1_two_tail->setVisible(false);
ui.rb_h0_one_tail_1->setVisible(false);
ui.rb_h0_one_tail_2->setVisible(false);
ui.rb_h0_two_tail->setVisible(false);
ui.l_h0->setVisible(false);
ui.l_h1->setVisible(false);
- QString mu = QChar(0x3BC);
- QString mu0 = mu+QChar(0x2092);
+ QString mu = UTF8_QSTRING("μ");
+ QString mu0 = UTF8_QSTRING("μₒ");
// radio button for null and alternate hypothesis
- // for alternative hypothesis
+ // for alternative hypothesis (h1)
// one_tail_1 is mu > mu0; one_tail_2 is mu < mu0; two_tail = mu != mu0;
+ ui.rb_h1_one_tail_1->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING(">"), mu0));
+ ui.rb_h1_one_tail_2->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("<"), mu0));
+ ui.rb_h1_two_tail->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("≠"), mu0));
- ui.rb_h1_one_tail_1->setText( i18n("%1 %2 %3", mu, QChar(0x3E), mu0));
- ui.rb_h1_one_tail_2->setText( i18n("%1 %2 %3", mu, QChar(0x3C), mu0));
- ui.rb_h1_two_tail->setText( i18n("%1 %2 %3", mu, QChar(0x2260), mu0));
-
- ui.rb_h0_one_tail_1->setText( i18n("%1 %2 %3", mu, QChar(0x2264), mu0));
- ui.rb_h0_one_tail_2->setText( i18n("%1 %2 %3",mu, QChar(0x2265), mu0));
- ui.rb_h0_two_tail->setText( i18n("%1 %2 %3", mu, QChar(0x3D), mu0));
+ ui.rb_h0_one_tail_1->setText( i18n("%1 %2 %3",mu, UTF8_QSTRING("≤"), mu0));
+ ui.rb_h0_one_tail_2->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("≥"), mu0));
+ ui.rb_h0_two_tail->setText( i18n("%1 %2 %3", mu, UTF8_QSTRING("="), mu0));
ui.rb_h0_two_tail->setEnabled(false);
ui.rb_h0_one_tail_1->setEnabled(false);
ui.rb_h0_one_tail_2->setEnabled(false);
// setting muo and alpha buttons
ui.l_muo->setText( i18n("%1", mu0));
- ui.l_alpha->setText( i18n("%1", QChar(0x3B1)));
+ ui.l_alpha->setText( i18n("%1", UTF8_QSTRING("α")));
ui.le_muo->setText( i18n("%1", population_mean));
ui.le_alpha->setText( i18n("%1", significance_level));
ui.l_muo->setVisible(false);
ui.l_alpha->setVisible(false);
ui.le_muo->setVisible(false);
ui.le_alpha->setVisible(false);
// 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::activated), this, &HypothesisTestDock::showHypothesisTest);
connect(ui.cbTestType, static_cast(&QComboBox::activated), 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);
//connecting null hypothesis and alternate hypothesis radio button
connect(ui.rb_h1_one_tail_1, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail1Toggled);
connect(ui.rb_h1_one_tail_2, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail2Toggled);
connect(ui.rb_h1_two_tail, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1TwoTailToggled);
connect(ui.cbCol1Categorical, QOverload::of(&QComboBox::currentIndexChanged), this, &HypothesisTestDock::col1CatIndexChanged);
}
void HypothesisTestDock::setHypothesisTest(HypothesisTest* HypothesisTest) {
// m_initializing = true;
m_hypothesisTest = HypothesisTest;
//// m_aspectTreeModel = new AspectTreeModel(m_hypothesisTest->project());
// QList list;
// list << "Folder" << "Workbook" << "Spreadsheet" << "LiveDataSource";
// cbSpreadsheet->setTopLevelClasses(list);
// list.clear();
// list << "Spreadsheet" << "LiveDataSource";
//// m_aspectTreeModel->setSelectableAspects(list);
//// 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::DataSourceSpreadsheet)
// setModelIndexFromAspect(cbSpreadsheet, m_hypothesisTest->dataSourceSpreadsheet());
// else
// ui.cbConnection->setCurrentIndex(ui.cbConnection->findText(m_hypothesisTest->dataSourceConnection()));
-
//clearing all cbCol*
ui.cbCol1->clear();
ui.cbCol2->clear();
ui.cbCol1Categorical->clear();
for (auto* col : m_hypothesisTest->dataSourceSpreadsheet()->children()) {
ui.cbCol1Categorical->addItem(col->name());
if (col->columnMode() == AbstractColumn::Integer || col->columnMode() == AbstractColumn::Numeric) {
ui.cbCol2->addItem(col->name());
ui.cbCol1->addItem(col->name());
}
}
this->dataSourceTypeChanged(ui.cbDataSourceType->currentIndex());
// setting rows and columns in combo box;
// //available dimensions and measures
// ui.lwFields->clear();
// for (auto dimension : m_hypothesisTest->dimensions())
// ui.lwFields->addItem(new QListWidgetItem(QIcon::fromTheme("draw-text"), dimension));
// for (auto measure : m_hypothesisTest->measures())
// ui.lwFields->addItem(new QListWidgetItem(measure));
// //undo functions
// connect(m_hypothesisTest, SIGNAL(aspectDescriptionChanged(const AbstractAspect*)), this, SLOT(hypothesisTestDescriptionChanged(const AbstractAspect*)));
// //TODO:
// m_initializing = false;
}
void HypothesisTestDock::showHypothesisTest() {
ttest = ui.cbTest->currentText() == "T Test";
ztest = ui.cbTest->currentText() == "Z Test";
two_sample_independent = ui.cbTestType->currentText() == "Two Sample Independent";
two_sample_paired = ui.cbTestType->currentText() == "Two Sample Paired";
one_sample = ui.cbTestType->currentText() == "One Sample";
ui.lCol1Categorical->setVisible(two_sample_independent);
ui.cbCol1Categorical->setVisible(two_sample_independent);
ui.lCol1->setVisible(two_sample_paired);
ui.cbCol1->setVisible(two_sample_paired);
ui.lCol2->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.cbCol2->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.chbEqualVariance->setVisible(ttest && two_sample_independent);
ui.chbEqualVariance->setChecked(true);
ui.pbPerformTest->setEnabled(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h1_one_tail_2->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h1_one_tail_1->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h1_two_tail->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h0_one_tail_1->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h0_one_tail_2->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h0_two_tail->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.l_h0->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.l_h1->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.rb_h1_two_tail->setChecked(true);
ui.l_muo->setVisible(one_sample);
ui.le_muo->setVisible(one_sample);
ui.l_alpha->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.le_alpha->setVisible(two_sample_independent || two_sample_paired || one_sample);
ui.le_muo->setText( i18n("%1", population_mean));
ui.le_alpha->setText( i18n("%1", significance_level));
if (two_sample_independent)
ui.lCol2->setText("Independent Variable");
}
void HypothesisTestDock::doHypothesisTest() {
m_hypothesisTest->setPopulationMean(ui.le_muo->text());
m_hypothesisTest->setSignificanceLevel(ui.le_alpha->text());
QStringList cols;
if(ttest) {
if(two_sample_independent) {
cols << ui.cbCol1Categorical->currentText() << ui.cbCol2->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->performTwoSampleIndependentTTest( ui.chbEqualVariance->isChecked());
}
else if(two_sample_paired) {
cols << ui.cbCol1->currentText();
cols << ui.cbCol2->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->performTwoSamplePairedTTest();
}
else if(one_sample){
cols << ui.cbCol1->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->PerformOneSampleTTest();
}
}
else if(ztest) {
if(two_sample_independent) {
cols << ui.cbCol1Categorical->currentText();
cols << ui.cbCol2->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->performTwoSampleIndependentZTest();
}
else if(two_sample_paired) {
cols << ui.cbCol1->currentText();
cols << ui.cbCol2->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->performTwoSamplePairedZTest();
}
else if(one_sample){
cols << ui.cbCol1->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->PerformOneSampleZTest();
}
}
cols << ui.cbCol1->currentText();
cols << ui.cbCol2->currentText();
m_hypothesisTest->setColumns(cols);
m_hypothesisTest->performTwoSampleTTest();
}
//void HypothesisTestDock::setModelIndexFromAspect(TreeViewComboBox* cb, const AbstractAspect* aspect) {
// 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) {
HypothesisTest::DataSourceType type = (HypothesisTest::DataSourceType)index;
bool showDatabase = (type == HypothesisTest::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) {
auto* aspect = static_cast(index.internalPointer());
Spreadsheet* spreadsheet = dynamic_cast(aspect);
//clear the previous definitions of combo-box columns
//clearing all cbCol*
ui.cbCol1->clear();
ui.cbCol2->clear();
ui.cbCol1Categorical->clear();
for (auto* col : m_hypothesisTest->dataSourceSpreadsheet()->children()) {
ui.cbCol1Categorical->addItem(col->name());
if (col->columnMode() == AbstractColumn::Integer || col->columnMode() == AbstractColumn::Numeric) {
ui.cbCol2->addItem(col->name());
ui.cbCol1->addItem(col->name());
}
}
m_hypothesisTest->setDataSourceSpreadsheet(spreadsheet);
}
// currently no need of this slot
void HypothesisTestDock::col1CatIndexChanged(int index) {
if (index < 0) return;
if (two_sample_paired) {
ui.lCol2->setText("Independent Variable");
return;
}
QString selected_text = ui.cbCol1Categorical->currentText();
Column* col1 = m_hypothesisTest->dataSourceSpreadsheet()->column(selected_text);
if (col1->columnMode() == AbstractColumn::Integer || col1->columnMode() == AbstractColumn::Numeric) {
ui.lCol2->setText("Independent Variable");
}
else {
ui.lCol2->setText("Dependent Variable");
}
}
//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),
// 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 Matrix *********
////*************************************************************
//void HypothesisTestDock::hypothesisTestDescriptionChanged(const AbstractAspect* aspect) {
// 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 = 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.rb_h0_one_tail_1->setChecked(true);
m_hypothesisTest->setTailType(HypothesisTest::TailPositive);
}
void HypothesisTestDock::onRbH1OneTail2Toggled(bool checked) {
if (!checked) return;
ui.rb_h0_one_tail_2->setChecked(true);
m_hypothesisTest->setTailType(HypothesisTest::TailNegative);
}
void HypothesisTestDock::onRbH1TwoTailToggled(bool checked) {
if (!checked) return;
ui.rb_h0_two_tail->setChecked(true);
m_hypothesisTest->setTailType(HypothesisTest::TailTwo);
}
diff --git a/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp b/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp
index c06c27edc..29f630180 100644
--- a/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp
+++ b/src/kdefrontend/hypothesis_test/HypothesisTestView.cpp
@@ -1,202 +1,178 @@
/***************************************************************************
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/hypothesis_test/HypothesisTest.h"
#include "backend/lib/macros.h"
#include "backend/lib/trace.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
/*!
\class HypothesisTestView
\brief View class for Hypothesis Test
\ingroup kdefrontend
*/
HypothesisTestView::HypothesisTestView(HypothesisTest* hypothesisTest) : QWidget(),
m_hypothesisTest(hypothesisTest),
m_testName(new QLabel()),
m_statsTable(new QLabel()),
- m_resultView(new QListView(this)) {
+ m_summaryResults(new QLabel()){
//setting alignments and fonts of testname label;
m_testName->setText(m_hypothesisTest->testName());
- QFont font = m_testName->font();
- font.setPointSize(15);
- m_testName->setFont(font);
-
- //setting properties for table view
- m_resultView->setEditTriggers(QAbstractItemView::NoEditTriggers);
-// m_tableView->setSizePolicy(QSizePolicy::Maximum, QSizePolicy::Maximum);
-
-// QHBoxLayout* tableLayout = new QHBoxLayout(m_tableView);
-// m_tableView->setLayout(tableLayout);
-// m_tableView->setLayout(Qt::ho)
-
-
+// QFont font = m_testName->font();
+// font.setPointSize(15);
+// m_testName->setFont(font);
auto* layout = new QVBoxLayout(this);
- layout->setContentsMargins(0,0,0,0);
layout->addWidget(m_testName);
- layout->addSpacing(5);
layout->addWidget(m_statsTable);
-// layout->addWidget(m_tableView);
- layout->addSpacing(20);
- layout->addWidget(m_resultView);
-// layout->addLayout(m_hypothesisTest->resultLayout());
-// layout->setAlignment(m_testName, Qt::AlignHCenter);
-// layout->setAlignment(m_tableView, Qt::AlignJustify);
+ layout->addWidget(m_summaryResults);
init();
}
HypothesisTestView::~HypothesisTestView() = default;
void HypothesisTestView::init() {
initActions();
initMenus();
-
- m_resultView->setModel(m_hypothesisTest->resultModel());
-
- // user cant select the text. so that he/she doesn't get the feel of list view
- // and get the feel of text;
- m_resultView->setSelectionMode(QAbstractItemView::NoSelection);
- m_resultView->setFocusPolicy(Qt::NoFocus);
-
connect(m_hypothesisTest, &HypothesisTest::changed, this, &HypothesisTestView::changed);
}
void HypothesisTestView::initActions() {
}
void HypothesisTestView::initMenus() {
}
void HypothesisTestView::connectActions() {
}
void HypothesisTestView::fillToolBar(QToolBar* 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 HypothesisTestView::createContextMenu(QMenu* menu) {
Q_ASSERT(menu);
}
bool HypothesisTestView::exportView() {
return true;
}
bool HypothesisTestView::printView() {
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 HypothesisTestView::printPreview() {
QPrintPreviewDialog* dlg = new QPrintPreviewDialog(this);
connect(dlg, &QPrintPreviewDialog::paintRequested, this, &HypothesisTestView::print);
return dlg->exec();
}
/*!
prints the complete spreadsheet to \c printer.
*/
void HypothesisTestView::print(QPrinter* printer) const {
WAIT_CURSOR;
QPainter painter (printer);
RESET_CURSOR;
}
void HypothesisTestView::changed() {
m_testName->setText(m_hypothesisTest->testName());
m_statsTable->setText(m_hypothesisTest->statsTable());
+ m_summaryResults->setText(m_hypothesisTest->summaryResultText());
}
void HypothesisTestView::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;
PERFTRACE("export pivot table to file");
}
void HypothesisTestView::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");
}
diff --git a/src/kdefrontend/hypothesis_test/HypothesisTestView.h b/src/kdefrontend/hypothesis_test/HypothesisTestView.h
index a71c57683..1f6ff7ae6 100644
--- a/src/kdefrontend/hypothesis_test/HypothesisTestView.h
+++ b/src/kdefrontend/hypothesis_test/HypothesisTestView.h
@@ -1,88 +1,88 @@
/***************************************************************************
File : PivotTableView.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
#include "backend/core/AbstractColumn.h"
#include "backend/lib/IntervalAttribute.h"
class Column;
class HypothesisTest;
class HypothesisTestModel;
class AbstractAspect;
class QTableView;
class QHeaderView;
class QListView;
class QPrinter;
class QMenu;
class QToolBar;
class QModelIndex;
class QItemSelection;
class QLabel;
class HypothesisTestView : public QWidget {
Q_OBJECT
public:
explicit HypothesisTestView(HypothesisTest*);
~HypothesisTestView() override;
bool exportView();
bool printView();
bool printPreview();
private:
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;
HypothesisTest* m_hypothesisTest;
QLabel* m_testName;
QLabel* m_statsTable;
- QListView* m_resultView;
+ QLabel* m_summaryResults;
public slots:
void createContextMenu(QMenu*);
void fillToolBar(QToolBar*);
void print(QPrinter*) const;
void changed();
private slots:
};
#endif
diff --git a/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui b/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui
index cbbf19948..4d47b9f5e 100644
--- a/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui
+++ b/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui
@@ -1,397 +1,397 @@
HypothesisTestDock
0
0
588
996
Form
9
255
73
17
75
true
Structure:
- 490
- 500
+ 280
+ 630
77
23
Do Test
10
480
341
106
Qt::Horizontal
-
Alternate Hypothesis
-
mu > muo
-
mu < muo
-
mu != muo
-
Null Hypothesis
-
mu <= muo
-
mu >= muo
-
mu == muo
10
610
217
81
-
muo
-
-
alpha
-
15
12
90
25
0
0
Name:
15
43
90
25
Comment:
130
43
401
25
130
12
401
25
15
93
42
17
75
true
Data
15
116
561
112
-
Source:
-
0
0
-
Spreadsheet:
-
Connection:
-
0
0
-
0
0
-
Table:
-
12
433
125
23
Equal Variance
13
288
341
50
-
-
Test
-
Test type
-
-
+
16
373
394
50
-
Independent Variable
Qt::AlignCenter
-
Independent Variable
-
Variable
-
-
-