v2.0.0
Loading...
Searching...
No Matches
sts_correction.cpp
Go to the documentation of this file.
1//=============================================================================================================
20
21//=============================================================================================================
22// INCLUDES
23//=============================================================================================================
24
25#include "sts_correction.h"
26
27#include <algorithm>
28#include <numeric>
29#include <vector>
30#include <cmath>
31
32//=============================================================================================================
33// USED NAMESPACES
34//=============================================================================================================
35
36using namespace STSLIB;
37using namespace Eigen;
38
39//=============================================================================================================
40// DEFINE METHODS
41//=============================================================================================================
42
43MatrixXd StatsMcCorrection::bonferroni(const MatrixXd& pValues)
44{
45 const int n = static_cast<int>(pValues.size());
46 MatrixXd corrected = pValues * static_cast<double>(n);
47 corrected = corrected.cwiseMin(1.0);
48 return corrected;
49}
50
51//=============================================================================================================
52
53MatrixXd StatsMcCorrection::holmBonferroni(const MatrixXd& pValues)
54{
55 const int n = static_cast<int>(pValues.size());
56
57 // Flatten to a vector with indices
58 std::vector<std::pair<double, int>> indexed(n);
59 for (int i = 0; i < n; ++i) {
60 indexed[i] = {pValues.data()[i], i};
61 }
62
63 // Sort ascending by p-value
64 std::sort(indexed.begin(), indexed.end());
65
66 // Compute adjusted p-values: adjusted_p[i] = p * (n - rank_i + 1), rank is 1-based
67 std::vector<double> adjusted(n);
68 for (int i = 0; i < n; ++i) {
69 adjusted[i] = indexed[i].first * static_cast<double>(n - i);
70 }
71
72 // Enforce monotonicity: from first to last, corrected[i] = max(corrected[i], corrected[i-1])
73 for (int i = 1; i < n; ++i) {
74 adjusted[i] = std::max(adjusted[i], adjusted[i - 1]);
75 }
76
77 // Cap at 1.0 and place back in original order
78 MatrixXd corrected(pValues.rows(), pValues.cols());
79 for (int i = 0; i < n; ++i) {
80 corrected.data()[indexed[i].second] = std::min(adjusted[i], 1.0);
81 }
82
83 return corrected;
84}
85
86//=============================================================================================================
87
88MatrixXd StatsMcCorrection::fdr(const MatrixXd& pValues, double alpha)
89{
90 Q_UNUSED(alpha);
91
92 const int n = static_cast<int>(pValues.size());
93
94 // Flatten to a vector with indices
95 std::vector<std::pair<double, int>> indexed(n);
96 for (int i = 0; i < n; ++i) {
97 indexed[i] = {pValues.data()[i], i};
98 }
99
100 // Sort ascending by p-value
101 std::sort(indexed.begin(), indexed.end());
102
103 // Compute adjusted p-values: adjusted_p = p * n / rank (rank is 1-based)
104 std::vector<double> adjusted(n);
105 for (int i = 0; i < n; ++i) {
106 int rank = i + 1;
107 adjusted[i] = indexed[i].first * static_cast<double>(n) / static_cast<double>(rank);
108 }
109
110 // Enforce monotonicity: from last to first, corrected[i] = min(corrected[i], corrected[i+1])
111 for (int i = n - 2; i >= 0; --i) {
112 adjusted[i] = std::min(adjusted[i], adjusted[i + 1]);
113 }
114
115 // Cap at 1.0 and place back in original order
116 MatrixXd corrected(pValues.rows(), pValues.cols());
117 for (int i = 0; i < n; ++i) {
118 corrected.data()[indexed[i].second] = std::min(adjusted[i], 1.0);
119 }
120
121 return corrected;
122}
Family-wise error and false-discovery-rate corrections for mass-univariate p-value maps.
Statistical testing (t-tests, F-tests, cluster permutation, multiple comparison correction).
static Eigen::MatrixXd holmBonferroni(const Eigen::MatrixXd &pValues)
static Eigen::MatrixXd fdr(const Eigen::MatrixXd &pValues, double alpha=0.05)
static Eigen::MatrixXd bonferroni(const Eigen::MatrixXd &pValues)