1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195
|
/*
File : NSLStatisticalTestTest.cpp
Project : LabPlot
Description : NSL Tests for statistical functions
--------------------------------------------------------------------
SPDX-FileCopyrightText: 2025 Kuntal Bar <barkuntal6@gmail.com>
SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "NSLStatisticalTestTest.h"
extern "C" {
#include "backend/nsl/nsl_statistical_test.h"
}
void NSLStatisticalTestTest::testMannWhitney() {
const double sample1[] = {1.0, 2.0, 3.0};
const double sample2[] = {4.0, 5.0, 6.0};
const size_t n1 = sizeof(sample1) / sizeof(sample1[0]);
const size_t n2 = sizeof(sample2) / sizeof(sample2[0]);
double U = nsl_stats_mannwhitney_u(sample1, n1, sample2, n2);
printf("Mann-Whitney U: %f\n", U);
double p = nsl_stats_mannwhitney_p(U, n1, n2);
printf("Mann-Whitney p-value: %f\n", p);
double expected_U = 0.0;
double expected_p = 0.0808556;
const double epsilon = 1e-4;
QVERIFY(std::abs(U - expected_U) < epsilon);
QVERIFY(std::abs(p - expected_p) < epsilon);
}
void NSLStatisticalTestTest::testAnovaOneWay() {
const double group1[] = {1.0, 2.0, 3.0};
const double group2[] = {2.0, 3.0, 4.0};
const double group3[] = {5.0, 6.0, 7.0};
size_t sizes[] = {3, 3, 3};
const size_t n_groups = 3;
double* groups[] = {const_cast<double*>(group1), const_cast<double*>(group2), const_cast<double*>(group3)};
double F = nsl_stats_anova_oneway_f(groups, sizes, n_groups);
printf("Computed F-statistic: %f", F);
double p = nsl_stats_anova_oneway_p(groups, sizes, n_groups);
printf("Computed p-value: %f\n", p);
double expected_F = 13.0;
double expected_p = 0.0065;
const double epsilon = 1e-4;
QVERIFY(std::abs(F - expected_F) < epsilon);
QVERIFY(std::abs(p - expected_p) < epsilon);
}
void NSLStatisticalTestTest::testKruskalWallis() {
const double group1[] = {1.0, 2.0, 3.0};
const double group2[] = {2.0, 3.0, 4.0};
const double group3[] = {5.0, 6.0, 7.0};
size_t sizes[] = {3, 3, 3};
const size_t n_groups = 3;
double* groups[] = {const_cast<double*>(group1), const_cast<double*>(group2), const_cast<double*>(group3)};
double H = nsl_stats_kruskal_wallis_h(groups, sizes, n_groups);
double p = nsl_stats_kruskal_wallis_p(groups, sizes, n_groups);
printf("Computed h-statistic: %f\n", H);
printf("Computed p-value: %f\n", p);
double expected_H = 6.0564;
double expected_p = 0.0484;
const double epsilon = 1e-4;
QVERIFY(std::abs(H - expected_H) < epsilon);
QVERIFY(std::abs(p - expected_p) < epsilon);
}
void NSLStatisticalTestTest::testLogRankTest() {
// ----------------------------------------------------------------------------------
// Test Case 1: No Censored Data
// ----------------------------------------------------------------------------------
const double time1_group1[] = {5, 6, 6, 2, 4, 4};
const int status1_group1[] = {1, 1, 1, 1, 1, 1}; // 1 = event occurred
const double time1_group2[] = {1, 3, 3, 8, 9, 9};
const int status1_group2[] = {1, 1, 1, 1, 1, 1}; // 1 = event occurred
size_t group1_indices1[] = {0, 1, 2, 3, 4, 5};
size_t size1_1 = sizeof(group1_indices1) / sizeof(group1_indices1[0]);
size_t group2_indices1[] = {6, 7, 8, 9, 10, 11};
size_t size2_1 = sizeof(group2_indices1) / sizeof(group2_indices1[0]);
double time1_combined[12];
int status1_combined[12];
for (size_t i = 0; i < size1_1; i++) {
time1_combined[i] = time1_group1[i];
status1_combined[i] = status1_group1[i];
}
for (size_t i = 0; i < size2_1; i++) {
time1_combined[size1_1 + i] = time1_group2[i];
status1_combined[size1_1 + i] = status1_group2[i];
}
double H1 = nsl_stats_log_rank_test_statistic(time1_combined, status1_combined, group1_indices1, size1_1, group2_indices1, size2_1);
double p1 = nsl_stats_log_rank_test_p(time1_combined, status1_combined, group1_indices1, size1_1, group2_indices1, size2_1);
printf("Computed H-value: %f\n", H1);
printf("Computed p-value: %f\n", p1);
double expected_H1 = 1.009510;
double expected_p1 = 0.31502028;
double epsilon = 1e-4;
QVERIFY(std::abs(H1 - expected_H1) < epsilon);
QVERIFY(std::abs(p1 - expected_p1) < epsilon);
// ----------------------------------------------------------------------------------
// Test Case 2: Censored Data
// ----------------------------------------------------------------------------------
const double time2_group1[] = {5, 6, 6, 2, 4, 4};
const int status2_group1[] = {1, 1, 0, 1, 1, 0}; // 1 = event occurred, 0 = censored
const double time2_group2[] = {1, 3, 3, 8, 9, 9};
const int status2_group2[] = {1, 0, 1, 1, 0, 1}; // 1 = event occurred, 0 = censored
size_t group1_indices2[] = {0, 1, 2, 3, 4, 5};
size_t size1_2 = sizeof(group1_indices2) / sizeof(group1_indices2[0]);
size_t group2_indices2[] = {6, 7, 8, 9, 10, 11};
size_t size2_2 = sizeof(group2_indices2) / sizeof(group2_indices2[0]);
double time2_combined[12];
int status2_combined[12];
for (size_t i = 0; i < size1_2; i++) {
time2_combined[i] = time2_group1[i];
status2_combined[i] = status2_group1[i];
}
for (size_t i = 0; i < size2_2; i++) {
time2_combined[size1_2 + i] = time2_group2[i];
status2_combined[size1_2 + i] = status2_group2[i];
}
double H2 = nsl_stats_log_rank_test_statistic(time2_combined, status2_combined, group1_indices2, size1_2, group2_indices2, size2_2);
double p2 = nsl_stats_log_rank_test_p(time2_combined, status2_combined, group1_indices2, size1_2, group2_indices2, size2_2);
double expected_H2 = 0.586871;
double expected_p2 = 0.44362;
printf("Computed H-value: %f\n", H2);
printf("Computed p-value: %f\n", p2);
QVERIFY(std::abs(H2 - expected_H2) < epsilon);
QVERIFY(std::abs(p2 - expected_p2) < epsilon);
}
void NSLStatisticalTestTest::testIndependentT() {
const double sample1[] = {12.5, 13.3, 14.2, 12.7, 13.9};
const double sample2[] = {15.1, 14.8, 15.5, 15.2, 14.9};
size_t n1 = 5;
size_t n2 = 5;
double t_stat = nsl_stats_independent_t(sample1, n1, sample2, n2);
double p_value = nsl_stats_independent_t_p(sample1, n1, sample2, n2);
double expected_t = -5.0671;
double expected_p = 0.0010;
const double epsilon = 1e-4;
printf("Computed t-statistic: %f\n", t_stat);
printf("Computed p-value: %f\n", p_value);
QVERIFY(std::abs(t_stat - expected_t) < epsilon);
QVERIFY(std::abs(p_value - expected_p) < epsilon);
}
void NSLStatisticalTestTest::testOneSampleT() {
const double sample[] = {15.2, 14.8, 15.5, 14.9, 15.1};
size_t n = 5;
double hypothesized_mean = 15.0;
double t_stat = nsl_stats_one_sample_t(sample, n, hypothesized_mean);
double p_value = nsl_stats_one_sample_t_p(sample, n, hypothesized_mean, 0);
double expected_t = 0.8165;
double expected_p = 0.4601;
const double epsilon = 1e-4;
printf("Computed t-statistic: %f\n", t_stat);
printf("Computed p-value: %f\n", p_value);
QVERIFY(std::abs(t_stat - expected_t) < epsilon);
QVERIFY(std::abs(p_value - expected_p) < epsilon);
}
QTEST_MAIN(NSLStatisticalTestTest)
|