diff --git a/CMakeLists.txt.user.4.8-pre1 b/CMakeLists.txt.user.4.8-pre1 deleted file mode 100644 index 1d263cec5..000000000 --- a/CMakeLists.txt.user.4.8-pre1 +++ /dev/null @@ -1,1756 +0,0 @@ - - - - - - EnvironmentId - {8aab856c-4268-430e-935d-1fc6c3939b19} - - - ProjectExplorer.Project.ActiveTarget - 0 - - - ProjectExplorer.Project.EditorSettings - - true - false - true - - Cpp - - CppGlobal - - - - QmlJS - - QmlJSGlobal - - - 2 - UTF-8 - false - 4 - false - 80 - true - true - 1 - true - false - 0 - true - true - 0 - 8 - true - 1 - true - true - true - false - - - - ProjectExplorer.Project.PluginSettings - - - - ProjectExplorer.Project.Target.0 - - Desktop - Desktop - {a4fe69e5-b48a-40e0-b2f6-ff46a3365815} - 0 - 0 - 0 - - - /home/deva/build-labplot-Desktop-Default - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Default - Default - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=Debug - - /home/deva/build-labplot-Desktop-Debug - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Debug - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=Release - - /home/deva/build-labplot-Desktop-Release - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Release - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=RelWithDebInfo - - /home/deva/build-labplot-Desktop-Release with Debug Information - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release with Debug Information - Release with Debug Information - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=MinSizeRel - - /home/deva/build-labplot-Desktop-Minimum Size Release - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Minimum Size Release - Minimum Size Release - CMakeProjectManager.CMakeBuildConfiguration - - 5 - - - 0 - Deploy - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deploy locally - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - labplot2 - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/src - 2 - - labplot2 - - CMakeProjectManager.CMakeRunConfiguration.labplot2 - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - differentiationtest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/analysis/differentiation - -1 - - differentiationtest - - CMakeProjectManager.CMakeRunConfiguration.differentiationtest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - nsldifftest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/nsl/diff - -1 - - nsldifftest - - CMakeProjectManager.CMakeRunConfiguration.nsldifftest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - nslinttest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/nsl/int - -1 - - nslinttest - - CMakeProjectManager.CMakeRunConfiguration.nslinttest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - nslsfwindowtest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/nsl/sf - -1 - - nslsfwindowtest - - CMakeProjectManager.CMakeRunConfiguration.nslsfwindowtest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - nslsfbasictest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/nsl/sf - -1 - - nslsfbasictest - - CMakeProjectManager.CMakeRunConfiguration.nslsfbasictest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - nslsmoothtest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/nsl/smooth - -1 - - nslsmoothtest - - CMakeProjectManager.CMakeRunConfiguration.nslsmoothtest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - integrationtest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/analysis/integration - -1 - - integrationtest - - CMakeProjectManager.CMakeRunConfiguration.integrationtest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - fittest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/analysis/fit - -1 - - fittest - - CMakeProjectManager.CMakeRunConfiguration.fittest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - convolutiontest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/analysis/convolution - -1 - - convolutiontest - - CMakeProjectManager.CMakeRunConfiguration.convolutiontest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - correlationtest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/analysis/correlation - -1 - - correlationtest - - CMakeProjectManager.CMakeRunConfiguration.correlationtest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - asciifiltertest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/import_export/ASCII - -1 - - asciifiltertest - - CMakeProjectManager.CMakeRunConfiguration.asciifiltertest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - jsonfiltertest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/import_export/JSON - -1 - - jsonfiltertest - - CMakeProjectManager.CMakeRunConfiguration.jsonfiltertest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - projectimporttest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/import_export/project - -1 - - projectimporttest - - CMakeProjectManager.CMakeRunConfiguration.projectimporttest - 3768 - false - true - false - false - true - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - nsldfttest - - - /tmp/QtCreator-zKyLSD/qtc-cmake-XXH4cuqI/tests/nsl/dft - -1 - - nsldfttest - - CMakeProjectManager.CMakeRunConfiguration.nsldfttest - 3768 - false - true - false - false - true - - 15 - - - - ProjectExplorer.Project.Target.1 - - Imported Kit - Imported Kit - {5dc9fd71-2911-42ea-ae59-b3f509566709} - 0 - 0 - 0 - - - /home/deva/build-labplot-Imported_Kit_5dc9fd-Default - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Default - Default - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=Debug - - /home/deva/build-labplot-Imported_Kit_5dc9fd-Debug - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Debug - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=Release - - /home/deva/build-labplot-Imported_Kit_5dc9fd-Release - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Release - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=RelWithDebInfo - - /home/deva/build-labplot-Imported_Kit_5dc9fd-Release with Debug Information - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release with Debug Information - Release with Debug Information - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=MinSizeRel - - /home/deva/build-labplot-Imported_Kit_5dc9fd-Minimum Size Release - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Minimum Size Release - Minimum Size Release - CMakeProjectManager.CMakeBuildConfiguration - - 5 - - - 0 - Deploy - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deploy locally - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - -1 - - - - %{buildDir} - Custom Executable - - ProjectExplorer.CustomExecutableRunConfiguration - 3768 - false - true - false - false - true - - 1 - - - - ProjectExplorer.Project.Target.2 - - Imported Kit - Imported Kit - {8e99deae-104f-42a6-b97e-de9375803f55} - 0 - 0 - 0 - - - /home/deva/build-labplot-Imported_Kit_8e99de-Default - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Default - Default - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=Debug - - /home/deva/build-labplot-Imported_Kit_8e99de-Debug - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Debug - Debug - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=Release - - /home/deva/build-labplot-Imported_Kit_8e99de-Release - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release - Release - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=RelWithDebInfo - - /home/deva/build-labplot-Imported_Kit_8e99de-Release with Debug Information - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Release with Debug Information - Release with Debug Information - CMakeProjectManager.CMakeBuildConfiguration - - - - CMAKE_BUILD_TYPE:STRING=MinSizeRel - - /home/deva/build-labplot-Imported_Kit_8e99de-Minimum Size Release - - - - - all - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Build - - ProjectExplorer.BuildSteps.Build - - - - - - clean - - true - CMake Build - - CMakeProjectManager.MakeStep - - 1 - Clean - - ProjectExplorer.BuildSteps.Clean - - 2 - false - - Minimum Size Release - Minimum Size Release - CMakeProjectManager.CMakeBuildConfiguration - - 5 - - - 0 - Deploy - - ProjectExplorer.BuildSteps.Deploy - - 1 - Deploy locally - - ProjectExplorer.DefaultDeployConfiguration - - 1 - - - false - false - 1000 - - true - - false - false - false - false - true - 0.01 - 10 - true - 1 - 25 - - 1 - true - false - true - valgrind - - 0 - 1 - 2 - 3 - 4 - 5 - 6 - 7 - 8 - 9 - 10 - 11 - 12 - 13 - 14 - - -1 - - - - %{buildDir} - Custom Executable - - ProjectExplorer.CustomExecutableRunConfiguration - 3768 - false - true - false - false - true - - 1 - - - - ProjectExplorer.Project.TargetCount - 3 - - - ProjectExplorer.Project.Updater.FileVersion - 18 - - - Version - 18 - - diff --git a/src/backend/hypothesis_test/HypothesisTest.cpp b/src/backend/hypothesis_test/HypothesisTest.cpp index 1dcdd74da..a072050c2 100644 --- a/src/backend/hypothesis_test/HypothesisTest.cpp +++ b/src/backend/hypothesis_test/HypothesisTest.cpp @@ -1,766 +1,787 @@ /*************************************************************************** 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; } void HypothesisTest::setDataSourceType(DataSourceType type) { if (type != d->dataSourceType) { d->dataSourceType = type; } } +HypothesisTest::DataSourceType HypothesisTest::dataSourceType() const { + return d->dataSourceType; +} + void HypothesisTest::setDataSourceSpreadsheet(Spreadsheet *spreadsheet) { if (spreadsheet != d->dataSourceSpreadsheet) d->setDataSourceSpreadsheet(spreadsheet); } +void HypothesisTest::setColumns(QVector cols) { + d->m_columns = cols; +} + +void HypothesisTest::setColumns(QStringList cols) { + return d->setColumns(cols); +} + QStringList HypothesisTest::allColumns() { return d->all_columns; } +void HypothesisTest::setTailType(HypothesisTest::TailType tailType) { + d->tail_type = tailType; +} + 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; +QString HypothesisTest::testName() { + return d->m_currTestName; } -void HypothesisTest::performTwoSampleTTest() { - +QString HypothesisTest::statsTable() { + return d->m_stats_table; } void HypothesisTest::performTwoSampleIndependentTTest(bool equal_variance) { + d->m_currTestName = "

Two Sample Independent T Test

"; d->performTwoSampleIndependentTest(HypothesisTestPrivate::TestT, equal_variance); - d->m_currTestName = "

Two Sample Independent T Test

"; } void HypothesisTest::performTwoSamplePairedTTest() { + d->m_currTestName = "

Two Sample Paried T Test

"; d->performTwoSamplePairedTest(HypothesisTestPrivate::TestT); - d->m_currTestName = "

Two Sample Paried T Test

"; } void HypothesisTest::PerformOneSampleTTest() { + d->m_currTestName = "

One Sample T Test

"; d->PerformOneSampleTest(HypothesisTestPrivate::TestT); - d->m_currTestName = "

One Sample T Test

"; } void HypothesisTest::performTwoSampleIndependentZTest() { + d->m_currTestName = "

Two Sample Independent Z Test

"; d->performTwoSampleIndependentTest(HypothesisTestPrivate::TestZ); - d->m_currTestName = "

Two Sample Independent Z Test

"; } void HypothesisTest::performTwoSamplePairedZTest() { + d->m_currTestName = "

Two Sample Paired Z Test

"; d->performTwoSamplePairedTest(HypothesisTestPrivate::TestZ); - d->m_currTestName = "

Two Sample Paired Z Test

"; } void HypothesisTest::PerformOneSampleZTest() { + d->m_currTestName = "

One Sample Z Test

"; d->PerformOneSampleTest(HypothesisTestPrivate::TestZ); - d->m_currTestName = "

One Sample Z Test

"; } -QString HypothesisTest::testName() { - return d->m_currTestName; -} -QString HypothesisTest::statsTable() { - return d->m_stats_table; -} /****************************************************************************** * Private Implementations * ****************************************************************************/ -HypothesisTestPrivate::HypothesisTestPrivate(HypothesisTest* owner) : q(owner) , - dataModel(new QStandardItemModel) , - horizontalHeaderModel(new QStandardItemModel) , - verticalHeaderModel(new QStandardItemModel) , - resultModel(new QStandardItemModel()){ +HypothesisTestPrivate::HypothesisTestPrivate(HypothesisTest* owner) : q(owner) { } 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 (!cols.isEmpty()) { column = dataSourceSpreadsheet->column(col); m_columns.append(column); } } } /**************************Two Sample Independent *************************************/ void HypothesisTestPrivate::performTwoSampleIndependentTest(TestType test, bool equal_variance) { QString test_name; double value; - int df; + int df = 0; double p_value = 0; clearGlobalVariables(); if (m_columns.size() != 2) { printError("Inappropriate number of columns selected"); emit q->changed(); 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) { printError("At least one of selected column is empty"); emit q->changed(); return; } } } else { - findStatsCategorical(n, sum, mean, std, col1_name, col2_name); - if (n[0] == -1) { - printError( i18n("Unequal size between %1 and %2", m_columns[0]->name(), m_columns[1]->name())); - emit q->changed(); - return; - } else if(n[0] == -2) { - printError( i18n("There are more than two categorical variables in %1", m_columns[0]->name())); - emit q->changed(); - return; - } else if (n[0] == 0) { - printError("atleast one of selected column is empty"); - emit q->changed(); - return; + ErrorType error_code = findStatsCategorical(m_columns[0], m_columns[1], n, sum, mean, std, col1_name, col2_name); + switch (error_code) { + case ErrorUnqualSize: { + printError( i18n("Unequal size between Column %1 and Column %2", m_columns[0]->name(), m_columns[1]->name())); + emit q->changed(); + return; + } case ErrorNotTwoCategoricalVariables: { + printError( i18n("Number of Categorical Variable in Column %1 is not equal to 2", m_columns[0]->name())); + emit q->changed(); + return; + } case ErrorEmptyColumn: { + printError("At least one of selected column is empty"); + emit q->changed(); + return; + } case NoError: + break; } } - 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]}; + 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: { test_name = "T"; if (equal_variance) { df = n[0] + n[1] - 2; double sp = qSqrt( ((n[0]-1)*qPow(std[0],2) + (n[1]-1)*qPow(std[1],2))/df); value = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1])); + printLine(9, "Assumption: Equal Variance b/w both population means"); } 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); value = (mean[0] - mean[1]) / (qSqrt( (qPow(std[0], 2)/n[0]) + (qPow(std[1], 2)/n[1]))); + printLine(9, "Assumption: UnEqual Variance b/w both population means"); } break; } case TestZ: { test_name = "Z"; df = n[0] + n[1] - 2; double sp = qSqrt( ((n[0]-1)*qPow(std[0],2) + (n[1]-1)*qPow(std[1],2))/df); value = (mean[0] - mean[1])/(sp*qSqrt(1.0/n[0] + 1.0/n[1])); } } - m_currTestName = i18n("

Two Sample Independent %1 Test for %2 vs %3

", test_name, col1_name, col2_name); + m_currTestName = i18n("

Two Sample Independent %1 Test for %2 vs %3

", test_name, col1_name, col2_name); p_value = getPValue(test, value, col1_name, col2_name, df); printLine(2, i18n("Significance level is %1", m_significance_level), "blue"); printLine(4, i18n("%1 Value is %2 ", test_name, value), "green"); printLine(5, i18n("P Value is %1 ", p_value), "green"); printLine(6, i18n("Degree of Freedom is %1", df), "green"); if (p_value <= m_significance_level) q->m_view->setResultLine(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level), Qt::ToolTipRole); else q->m_view->setResultLine(5, i18n("There is a plausibility for Null Hypothesis to be true"), Qt::ToolTipRole); emit q->changed(); return; } /********************************Two Sample Paired ***************************************/ void HypothesisTestPrivate::performTwoSamplePairedTest(TestType test) { QString test_name; int n; double sum, mean, std; double value; - int df; + int df = 0; double p_value = 0; clearGlobalVariables(); if (m_columns.size() != 2) { printError("Inappropriate number of columns selected"); emit q->changed(); return; } for (int i = 0; i < 2; i++) { if (!(m_columns[i]->columnMode() == AbstractColumn::Numeric || m_columns[i]->columnMode() == AbstractColumn::Integer)) { printError("select only columns with numbers"); emit q->changed(); return; } } - findStatsPaired(m_columns[0], m_columns[1], n, sum, mean, std); + ErrorType error_code = findStatsPaired(m_columns[0], m_columns[1], n, sum, mean, std); + + switch (error_code) { + case ErrorUnqualSize: { + printError("both columns are having different sizes"); + emit q->changed(); + return; + } case ErrorEmptyColumn: { + printError("columns are empty"); + emit q->changed(); + return; + } case NoError: + break; + default: + emit q->changed(); + return; + } if (n == -1) { printError("both columns are having different sizes"); emit q->changed(); return; } if (n < 1) { printError("columns are empty"); emit q->changed(); return; } - QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", "difference", n, sum, mean, std}; + QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", + "difference", n, sum, mean, std}; + m_stats_table = getHtmlTable(2, 5, row_major); switch (test) { case TestT: { value = mean / (std/qSqrt(n)); df = n - 1; test_name = "T"; printLine(6, i18n("Degree of Freedom is %1name(), i18n("%1",m_population_mean), df); - m_currTestName = i18n("

One Sample %1 Test for %2 vs %3

", test_name, m_columns[0]->name(), m_columns[1]->name()); + m_currTestName = i18n("

One Sample %1 Test for %2 vs %3

", test_name, m_columns[0]->name(), m_columns[1]->name()); - printLine(2, i18n("Significance level is %1

", m_significance_level), "blue"); - printLine(4, i18n("%1 Value is %2

", test_name, value), "green"); - printLine(5, i18n("P Value is %1

", p_value), "green"); + printLine(2, i18n("Significance level is %1 ", m_significance_level), "blue"); + printLine(4, i18n("%1 Value is %2 ", test_name, value), "green"); + printLine(5, i18n("P Value is %1 ", p_value), "green"); if (p_value <= m_significance_level) q->m_view->setResultLine(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level), Qt::ToolTipRole); else q->m_view->setResultLine(5, i18n("There is a plausibility for Null Hypothesis to be true"), Qt::ToolTipRole); emit q->changed(); return; } /******************************** One Sample ***************************************/ void HypothesisTestPrivate::PerformOneSampleTest(TestType test) { QString test_name; double value; - int df; + int df = 0; double p_value = 0; clearGlobalVariables(); if (m_columns.size() != 1) { printError("Inappropriate number of columns selected"); emit q->changed(); return; } if ( !(m_columns[0]->columnMode() == AbstractColumn::Numeric || m_columns[0]->columnMode() == AbstractColumn::Integer)) { printError("select only columns with numbers"); emit q->changed(); return; } int n; double sum, mean, std; - findStats(m_columns[0], n, sum, mean, std); + ErrorType error_code = findStats(m_columns[0], n, sum, mean, std); - if (n < 1) { - printError("column is empty"); - emit q->changed(); - return; + switch (error_code) { + case ErrorUnqualSize: { + printError("column is empty"); + emit q->changed(); + return; + } case NoError: + break; + default: { + emit q->changed(); + return; + } } - QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", m_columns[0]->name(), n, sum, mean, std}; + QVariant row_major[] = {"", "N", "Sum", "Mean", "Std", + m_columns[0]->name(), n, sum, mean, std}; + m_stats_table = getHtmlTable(2, 5, row_major); switch (test) { case TestT: { test_name = "T"; value = (mean - m_population_mean) / (std/qSqrt(n)); df = n - 1; printLine(6, i18n("Degree of Freedom is %1", df), "blue"); break; } case TestZ: { test_name = "Z"; df = 0; value = (mean - m_population_mean) / (std/qSqrt(n)); }} p_value = getPValue(test, value, m_columns[0]->name(), i18n("%1",m_population_mean), df); - m_currTestName = i18n("

One Sample %1 Test for %2

", test_name, m_columns[0]->name()); + m_currTestName = i18n("

One Sample %1 Test for %2

", test_name, m_columns[0]->name()); printLine(2, i18n("Significance level is %1", m_significance_level), "blue"); printLine(4, i18n("%1 Value is %2", test_name, value), "green"); printLine(5, i18n("P Value is %1", p_value), "green"); if (p_value <= m_significance_level) q->m_view->setResultLine(5, i18n("We can safely reject Null Hypothesis for significance level %1", m_significance_level), Qt::ToolTipRole); else q->m_view->setResultLine(5, i18n("There is a plausibility for Null Hypothesis to be true"), Qt::ToolTipRole); emit q->changed(); return; } /***************************************Helper Functions*************************************/ -void HypothesisTestPrivate::findStatsPaired(Column* column1, Column* column2, int &count, double &sum, double &mean, double &std) { +HypothesisTestPrivate::ErrorType HypothesisTestPrivate::findStats(const Column* column, 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 cell1, cell2; + count = column->rowCount(); 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 { - count = -1; - return; - } + double row = column->valueAt(i); + if ( std::isnan(row)) { + count = i; break; } - - sum += cell1 - cell2; + sum += row; } - if (count < 1) return; + if (count < 1) return HypothesisTestPrivate::ErrorEmptyColumn; mean = sum/count; - double row; for (int i = 0; i < count; i++) { - cell1 = column1->valueAt(i); - cell2 = column2->valueAt(i); - row = cell1 - cell2; + double row = column->valueAt(i); std += qPow( (row - mean), 2); } if (count > 1) std = std / (count-1); - std = qSqrt(std); - return; + + return HypothesisTestPrivate::NoError; } -void HypothesisTestPrivate::findStats(Column* column, int &count, double &sum, double &mean, double &std) { +HypothesisTestPrivate::ErrorType HypothesisTestPrivate::findStatsPaired(const Column* column1, const Column* column2, int &count, double &sum, double &mean, double &std) { sum = 0; mean = 0; std = 0; - count = column->rowCount(); + int count1 = column1->rowCount(); + int count2 = column2->rowCount(); + + count = qMin(count1, count2); + double cell1, cell2; for (int i = 0; i < count; i++) { - double row = column->valueAt(i); - if ( std::isnan(row)) { - 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 HypothesisTestPrivate::ErrorUnqualSize; break; } - sum += row; + + sum += cell1 - cell2; } - if (count < 1) return; + if (count < 1) + return HypothesisTestPrivate::ErrorEmptyColumn; + mean = sum/count; + double row; for (int i = 0; i < count; i++) { - double row = column->valueAt(i); + cell1 = column1->valueAt(i); + cell2 = column2->valueAt(i); + row = cell1 - cell2; std += qPow( (row - mean), 2); } if (count > 1) std = std / (count-1); + std = qSqrt(std); - return; + return HypothesisTestPrivate::NoError; } +HypothesisTestPrivate::ErrorType HypothesisTestPrivate::findStatsCategorical(const Column *column1, const Column *column2, int n[], double sum[], double mean[], double std[], QString &col1_name, QString &col2_name) { + // clearing and initialising variables; -void HypothesisTestPrivate::findStatsCategorical(int n[], double sum[], double mean[], double std[], QString &col1_name, QString &col2_name) { + const Column* columns[] = {column1, column2}; - /* 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(); + int count_temp = 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); + QString name = columns[0]->textAt(i); + double value = columns[1]->valueAt(i); - if (name == "" || std::isnan(value)) { - if (name == "" && std::isnan(value)) + if (name.isEmpty() || std::isnan(value)) { + if (name.isEmpty() && std::isnan(value)) break; - else { - n[0] = -1; - return; - } + else + return HypothesisTestPrivate::ErrorUnqualSize; } if (name == col1_name) { n[0]++; sum[0] += value; } else if (name == col2_name) { n[1]++; sum[1] += value; - } else if (col1_name == "") { + } else if (col1_name.isEmpty()) { n[0]++; sum[0] += value; col1_name = name; - } else if (col2_name == "") { + } else if (col2_name.isEmpty()) { 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; - } + else + return HypothesisTestPrivate::ErrorNotTwoCategoricalVariables; } - if (col1_name == "" || col2_name == "") { - n[0] = -2; - return; - } + if (col1_name.isEmpty() || col2_name.isEmpty()) + return HypothesisTestPrivate::ErrorNotTwoCategoricalVariables; 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); + QString name = columns[0]->textAt(i); + double value = columns[1]->valueAt(i); if (name == col1_name) std[0] += qPow( (value - mean[0]), 2); - else { + 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; + return HypothesisTestPrivate::NoError; } double HypothesisTestPrivate::getPValue(const HypothesisTestPrivate::TestType &test, double &value, const QString &col1_name, const QString &col2_name, const int df) { double p_value = 0; + + //TODO change ("⋖") symbol to ("<"), currently macro UTF8_QSTRING is not working properly if used "<" symbol; switch (test) { case TestT: { switch (tail_type) { case HypothesisTest::TailNegative: p_value = nsl_stats_tdist_p(value, df); - q->m_view->setResultLine(0, i18n("

Null Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("≥"), col2_name)); - q->m_view->setResultLine(1, i18n("

Alternate Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("⋖"), col2_name)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1_name, UTF8_QSTRING("≥"), col2_name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1_name, UTF8_QSTRING("⋖"), col2_name), "blue"); break; case HypothesisTest::TailPositive: value *= -1; p_value = nsl_stats_tdist_p(value, df); - q->m_view->setResultLine(0, i18n("

Null Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("≤"), col2_name)); - q->m_view->setResultLine(1, i18n("

Alternate Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING(">"), col2_name)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1_name, UTF8_QSTRING("≤"), col2_name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1_name, UTF8_QSTRING(">"), col2_name), "blue"); break; case HypothesisTest::TailTwo: p_value = nsl_stats_tdist_p(value, df) + nsl_stats_tdist_p(-1*value, df); - q->m_view->setResultLine(0, i18n("

Null Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("="), col2_name)); - q->m_view->setResultLine(1, i18n("

Alternate Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("≠"), col2_name)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3", col1_name, UTF8_QSTRING("="), col2_name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3", col1_name, UTF8_QSTRING("≠"), col2_name), "blue"); break; } break; } case TestZ: { switch (tail_type) { case HypothesisTest::TailNegative: p_value = nsl_stats_tdist_p(value, df); - q->m_view->setResultLine(0, i18n("

Null Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("≥"), col2_name)); - q->m_view->setResultLine(1, i18n("

Alternate Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("⋖"), col2_name)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1_name, UTF8_QSTRING("≥"), col2_name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1_name, UTF8_QSTRING("⋖"), col2_name), "blue"); break; case HypothesisTest::TailPositive: value *= -1; p_value = nsl_stats_tdist_p(value, df); - q->m_view->setResultLine(0, i18n("

Null Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("≤"), col2_name)); - q->m_view->setResultLine(1, i18n("

Alternate Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING(">"), col2_name)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1_name, UTF8_QSTRING("≤"), col2_name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1_name, UTF8_QSTRING(">"), col2_name), "blue"); break; case HypothesisTest::TailTwo: p_value = nsl_stats_tdist_p(value, df) + nsl_stats_tdist_p(-1*value, df); - q->m_view->setResultLine(0, i18n("

Null Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("="), col2_name)); - q->m_view->setResultLine(1, i18n("

Alternate Hypothesis: Population mean of %1 %2 Population mean of %3

", col1_name, UTF8_QSTRING("≠"), col2_name)); + printLine(0, i18n("Null Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1_name, UTF8_QSTRING("="), col2_name), "blue"); + printLine(1, i18n("Alternate Hypothesis: Population mean of %1 %2 Population mean of %3 ", col1_name, UTF8_QSTRING("≠"), col2_name), "blue"); break; } break; } } + if (p_value > 1) return 1; return p_value; } 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(" ", 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(" ", bg, element); for (int j = 1; j < column; j++) { QString element = row_major[i*column+j].toString(); table += i18n(" ", bg, element); } table += " "; if (pky) bg = "tg-0pky"; else bg = "tg-btxf"; pky = !pky; } table += "
%2
%2%2
"; return table; } void HypothesisTestPrivate::printLine(const int &index, const QString &msg, const QString &color) { q->m_view->setResultLine(index, i18n("

%2

", color, msg)); return; } void HypothesisTestPrivate::printError(const QString &error_msg) { printLine(0, error_msg, "red"); emit q->changed(); } void HypothesisTestPrivate::clearGlobalVariables() { m_stats_table = ""; q->m_view->clearResult(); } /********************************************************************************** * 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 7fc11fb19..432563aaf 100644 --- a/src/backend/hypothesis_test/HypothesisTest.h +++ b/src/backend/hypothesis_test/HypothesisTest.h @@ -1,104 +1,99 @@ /*************************************************************************** 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 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}; - QString testName(); - QString statsTable(); - + void setDataSourceType(DataSourceType type); + DataSourceType dataSourceType() const; void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); + void setColumns(QVector cols); void setColumns(QStringList cols); + QStringList allColumns(); + void setTailType(TailType tailType); + TailType tailType(); + void setPopulationMean(QVariant populationMean); + void setSignificanceLevel(QVariant alpha); + QString testName(); + QString statsTable(); + 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); -// void setResultLine(int index, QVariant data, Qt::ItemDataRole role = Qt::DisplayRole); -// void clearResult(); 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 024df28d8..9897f438a 100644 --- a/src/backend/hypothesis_test/HypothesisTestPrivate.h +++ b/src/backend/hypothesis_test/HypothesisTestPrivate.h @@ -1,90 +1,81 @@ /*************************************************************************** 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}; + enum ErrorType {ErrorUnqualSize, ErrorNotTwoCategoricalVariables, ErrorEmptyColumn, NoError}; + QString name() const; + void setDataSourceSpreadsheet(Spreadsheet* spreadsheet); + void setColumns(QStringList cols); + void performTwoSampleIndependentTest(TestType test, bool equal_variance = true); + void performTwoSamplePairedTest(TestType test); + void PerformOneSampleTest(TestType test); - HypothesisTest* const q; + 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; - - 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); - double getPValue(const TestType &test, double &value, const QString &col1_name, const QString &col2_name, const int df = 0); + 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(const Column *column1, const Column *column2, int n[2], double sum[2], double mean[2], double std[2], QString &col1_name, QString &col2_name); + + double getPValue(const TestType &test, double &value, const QString &col1_name, const QString &col2_name, const int df); QString getHtmlTable(int row, int column, QVariant *row_major); + + void printLine(const int &index, const QString &msg, const QString &color = "black"); void printError(const QString &error_msg); void clearGlobalVariables(); - - // QMap m_members; - void printLine(const int &index, const QString &msg, const QString &color = "blue"); }; #endif diff --git a/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp b/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp index af847af9c..19fca6a21 100644 --- a/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp +++ b/src/kdefrontend/dockwidgets/HypothesisTestDock.cpp @@ -1,682 +1,680 @@ /*************************************************************************** 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 #include /*! \class HypothesisTestDock \brief Provides a dock (widget) for hypothesis testing: \ingroup kdefrontend */ +//TOOD: Make this dock widget scrollable and automatic resizeable for different screens. + 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); + ui.rbH1OneTail2->setVisible(false); + ui.rbH1OneTail1->setVisible(false); + ui.rbH1TwoTail->setVisible(false); + ui.rbH0OneTail1->setVisible(false); + ui.rbH0OneTail2->setVisible(false); + ui.rbH0TwoTail->setVisible(false); + ui.lH0->setVisible(false); + ui.lH1->setVisible(false); 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.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.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.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.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.rb_h0_two_tail->setEnabled(false); - ui.rb_h0_one_tail_1->setEnabled(false); - ui.rb_h0_one_tail_2->setEnabled(false); + ui.rbH0TwoTail->setEnabled(false); + ui.rbH0OneTail1->setEnabled(false); + ui.rbH0OneTail2->setEnabled(false); // setting muo and alpha buttons - ui.l_muo->setText( i18n("%1", mu0)); - 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.lMuo->setText( i18n("%1", mu0)); + ui.lAlpha->setText( i18n("%1", UTF8_QSTRING("α"))); + ui.leMuo->setText( i18n("%1", population_mean)); + ui.leAlpha->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); + ui.lMuo->setVisible(false); + ui.lAlpha->setVisible(false); + ui.leMuo->setVisible(false); + ui.leAlpha->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.rbH1OneTail1, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail1Toggled); + connect(ui.rbH1OneTail2, &QRadioButton::toggled, this, &HypothesisTestDock::onRbH1OneTail2Toggled); + connect(ui.rbH1TwoTail, &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.rbH1OneTail2->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.rbH1OneTail1->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.rbH1TwoTail->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.rbH0OneTail1->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.rbH0OneTail2->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.rbH0TwoTail->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.lH0->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.lH1->setVisible(two_sample_independent || two_sample_paired || one_sample); - ui.rb_h1_two_tail->setChecked(true); + ui.rbH1TwoTail->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.lMuo->setVisible(one_sample); + ui.leMuo->setVisible(one_sample); + ui.lAlpha->setVisible(two_sample_independent || two_sample_paired || one_sample); + ui.leAlpha->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)); + ui.leMuo->setText( i18n("%1", population_mean)); + ui.leAlpha->setText( i18n("%1", significance_level)); if (two_sample_independent) - ui.lCol2->setText("Independent Variable"); + ui.lCol2->setText( i18n("Independent Variable")); } void HypothesisTestDock::doHypothesisTest() { - m_hypothesisTest->setPopulationMean(ui.le_muo->text()); - m_hypothesisTest->setSignificanceLevel(ui.le_alpha->text()); + m_hypothesisTest->setPopulationMean(ui.leMuo->text()); + m_hypothesisTest->setSignificanceLevel(ui.leAlpha->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"); + ui.lCol2->setText( i18n("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"); + ui.lCol2->setText( i18n("Independent Variable")); } else { - ui.lCol2->setText("Dependent Variable"); + ui.lCol2->setText( i18n("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); + ui.rbH0OneTail1->setChecked(true); m_hypothesisTest->setTailType(HypothesisTest::TailPositive); } void HypothesisTestDock::onRbH1OneTail2Toggled(bool checked) { if (!checked) return; - ui.rb_h0_one_tail_2->setChecked(true); + ui.rbH0OneTail2->setChecked(true); m_hypothesisTest->setTailType(HypothesisTest::TailNegative); } void HypothesisTestDock::onRbH1TwoTailToggled(bool checked) { if (!checked) return; - ui.rb_h0_two_tail->setChecked(true); + ui.rbH0TwoTail->setChecked(true); m_hypothesisTest->setTailType(HypothesisTest::TailTwo); } diff --git a/src/kdefrontend/dockwidgets/HypothesisTestDock.h b/src/kdefrontend/dockwidgets/HypothesisTestDock.h index 17f501f62..68482af74 100644 --- a/src/kdefrontend/dockwidgets/HypothesisTestDock.h +++ b/src/kdefrontend/dockwidgets/HypothesisTestDock.h @@ -1,108 +1,110 @@ /*************************************************************************** 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/hypothesis_test/HypothesisTest.h" #include "ui_hypothesistestdock.h" #include class AbstractAspect; class AspectTreeModel; class HypothesisTest; class TreeViewComboBox; class KConfig; +class QScrollArea; class HypothesisTestDock : public QWidget { Q_OBJECT public: explicit HypothesisTestDock(QWidget*); void setHypothesisTest(HypothesisTest*); private slots: void onRbH1OneTail1Toggled(bool checked); void onRbH1OneTail2Toggled(bool checked); void onRbH1TwoTailToggled(bool checked); private slots: 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 population_mean{0}; double significance_level{0.05}; // void load(); // void loadConfig(KConfig&); // void setModelIndexFromAspect(TreeViewComboBox*, const AbstractAspect*); // void readConnections(); // void updateFields(); // bool fieldSelected(const QString&); bool ttest{false}; bool ztest{false}; bool two_sample_independent{false}; bool two_sample_paired{false}; bool one_sample{false}; + QScrollArea* scroll_dock; private slots: //SLOTs for changes triggered in PivotTableDock // void nameChanged(); // void commentChanged(); void dataSourceTypeChanged(int); void doHypothesisTest(); void showHypothesisTest(); void spreadsheetChanged(const QModelIndex&); void col1CatIndexChanged(int index); // void connectionChanged(); // void tableChanged(); // void showDatabaseManager(); // //SLOTs for changes triggered in PivotTable // void pivotTableDescriptionChanged(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/ui/dockwidgets/hypothesistestdock.ui b/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui index 40dad1b60..095b715b2 100644 --- a/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui +++ b/src/kdefrontend/ui/dockwidgets/hypothesistestdock.ui @@ -1,397 +1,410 @@ HypothesisTestDock 0 0 588 996 Form 9 255 73 17 75 true Structure: - 220 - 440 + 280 + 710 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 + 531 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 + + + + 570 + 10 + 16 + 981 + + + + Qt::Vertical + +