Initial data commit
This commit is contained in:
parent
72d218235f
commit
f23f22d71c
199087 changed files with 3378941 additions and 0 deletions
3
Task/P-value-correction/00-META.yaml
Normal file
3
Task/P-value-correction/00-META.yaml
Normal file
|
|
@ -0,0 +1,3 @@
|
|||
---
|
||||
from: http://rosettacode.org/wiki/P-value_correction
|
||||
note: Probability and statistics
|
||||
33
Task/P-value-correction/00-TASK.txt
Normal file
33
Task/P-value-correction/00-TASK.txt
Normal file
|
|
@ -0,0 +1,33 @@
|
|||
Given a list of [[wp:p-value|p-values]], adjust the p-values for multiple comparisons. This is done in order to control the false positive, or Type 1 error rate.
|
||||
|
||||
This is also known as the "[[wp:False discovery rate|false discovery rate]]" (FDR). After adjustment, the p-values will be higher but still inside [0,1].
|
||||
|
||||
The adjusted p-values are sometimes called "q-values".
|
||||
|
||||
|
||||
;Task:
|
||||
Given one list of [[Welch's_t-test|p-values]], return the p-values correcting for multiple comparisons
|
||||
|
||||
p = {4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03}
|
||||
|
||||
|
||||
There are several methods to do this, see:
|
||||
* Yoav Benjamini, Yosef Hochberg "[http://www.math.tau.ac.il/~ybenja/MyPapers/benjamini_hochberg1995.pdf Controlling the False Discovery Rate: A Practical and Powerful Approach to Multiple Testing]", ''Journal of the Royal Statistical Society. Series B'', Vol. 57, No. 1 (1995), pp. 289-300, JSTOR:[http://www.jstor.org/stable/2346101 2346101]
|
||||
* Yoav Benjamini, Daniel Yekutieli, "[http://www.math.tau.ac.il/~ybenja/MyPapers/benjamini_yekutieli_ANNSTAT2001.pdf The control of the false discovery rate in multiple testing under dependency]", ''Ann. Statist.'', Vol. 29, No. 4 (2001), pp. 1165-1188, DOI:[https://doi.org/10.1214/aos/1013699998 10.1214/aos/1013699998] JSTOR:[http://www.jstor.org/stable/2674075 2674075]
|
||||
* Sture Holm, "A Simple Sequentially Rejective Multiple Test Procedure", ''Scandinavian Journal of Statistics'', Vol. 6, No. 2 (1979), pp. 65-70, JSTOR:[https://www.jstor.org/stable/4615733 4615733]
|
||||
* Yosef Hochberg, "A sharper Bonferroni procedure for multiple tests of significance", ''Biometrika'', Vol. 75, No. 4 (1988), pp 800–802, DOI:[https://doi.org/10.1093/biomet/75.4.800 10.1093/biomet/75.4.800] JSTOR:[https://www.jstor.org/stable/2336325 2336325]
|
||||
* Gerhard Hommel, "A stagewise rejective multiple test procedure based on a modified Bonferroni test", ''Biometrika'', Vol. 75, No. 2 (1988), pp 383–386, DOI:[https://doi.org/10.1093/biomet/75.2.383 10.1093/biomet/75.2.383] JSTOR:[https://www.jstor.org/stable/2336190 2336190]
|
||||
|
||||
|
||||
Each method has its own advantages and disadvantages.
|
||||
<br><br>
|
||||
|
||||
322
Task/P-value-correction/C++/p-value-correction.cpp
Normal file
322
Task/P-value-correction/C++/p-value-correction.cpp
Normal file
|
|
@ -0,0 +1,322 @@
|
|||
#include <algorithm>
|
||||
#include <functional>
|
||||
#include <iostream>
|
||||
#include <numeric>
|
||||
#include <vector>
|
||||
|
||||
std::vector<int> seqLen(int start, int end) {
|
||||
std::vector<int> result;
|
||||
|
||||
if (start == end) {
|
||||
result.resize(end + 1);
|
||||
std::iota(result.begin(), result.end(), 1);
|
||||
} else if (start < end) {
|
||||
result.resize(end - start + 1);
|
||||
std::iota(result.begin(), result.end(), start);
|
||||
} else {
|
||||
result.resize(start - end + 1);
|
||||
std::iota(result.rbegin(), result.rend(), end);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
std::vector<int> order(const std::vector<double>& arr, bool decreasing) {
|
||||
std::vector<int> idx(arr.size());
|
||||
std::iota(idx.begin(), idx.end(), 0);
|
||||
|
||||
std::function<bool(int, int)> cmp;
|
||||
if (decreasing) {
|
||||
cmp = [&arr](int a, int b) { return arr[b] < arr[a]; };
|
||||
} else {
|
||||
cmp = [&arr](int a, int b) { return arr[a] < arr[b]; };
|
||||
}
|
||||
|
||||
std::sort(idx.begin(), idx.end(), cmp);
|
||||
return idx;
|
||||
}
|
||||
|
||||
std::vector<double> cummin(const std::vector<double>& arr) {
|
||||
if (arr.empty()) throw std::runtime_error("cummin requries at least one element");
|
||||
std::vector<double> output(arr.size());
|
||||
double cumulativeMin = arr[0];
|
||||
std::transform(arr.cbegin(), arr.cend(), output.begin(), [&cumulativeMin](double a) {
|
||||
if (a < cumulativeMin) cumulativeMin = a;
|
||||
return cumulativeMin;
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
std::vector<double> cummax(const std::vector<double>& arr) {
|
||||
if (arr.empty()) throw std::runtime_error("cummax requries at least one element");
|
||||
std::vector<double> output(arr.size());
|
||||
double cumulativeMax = arr[0];
|
||||
std::transform(arr.cbegin(), arr.cend(), output.begin(), [&cumulativeMax](double a) {
|
||||
if (cumulativeMax < a) cumulativeMax = a;
|
||||
return cumulativeMax;
|
||||
});
|
||||
return output;
|
||||
}
|
||||
|
||||
std::vector<double> pminx(const std::vector<double>& arr, double x) {
|
||||
if (arr.empty()) throw std::runtime_error("pmin requries at least one element");
|
||||
std::vector<double> result(arr.size());
|
||||
std::transform(arr.cbegin(), arr.cend(), result.begin(), [&x](double a) {
|
||||
if (a < x) return a;
|
||||
return x;
|
||||
});
|
||||
return result;
|
||||
}
|
||||
|
||||
void doubleSay(const std::vector<double>& arr) {
|
||||
printf("[ 1] %.10f", arr[0]);
|
||||
for (size_t i = 1; i < arr.size(); ++i) {
|
||||
printf(" %.10f", arr[i]);
|
||||
if ((i + 1) % 5 == 0) printf("\n[%2d]", i + 1);
|
||||
}
|
||||
}
|
||||
|
||||
std::vector<double> pAdjust(const std::vector<double>& pvalues, const std::string& str) {
|
||||
if (pvalues.empty()) throw std::runtime_error("pAdjust requires at least one element");
|
||||
size_t size = pvalues.size();
|
||||
|
||||
int type;
|
||||
if ("bh" == str || "fdr" == str) {
|
||||
type = 0;
|
||||
} else if ("by" == str) {
|
||||
type = 1;
|
||||
} else if ("bonferroni" == str) {
|
||||
type = 2;
|
||||
} else if ("hochberg" == str) {
|
||||
type = 3;
|
||||
} else if ("holm" == str) {
|
||||
type = 4;
|
||||
} else if ("hommel" == str) {
|
||||
type = 5;
|
||||
} else {
|
||||
throw std::runtime_error(str + " doesn't match any accepted FDR types");
|
||||
}
|
||||
|
||||
// Bonferroni method
|
||||
if (2 == type) {
|
||||
std::vector<double> result(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
double b = pvalues[i] * size;
|
||||
if (b >= 1) {
|
||||
result[i] = 1;
|
||||
} else if (0 <= b && b < 1) {
|
||||
result[i] = b;
|
||||
} else {
|
||||
throw std::runtime_error("a value is outside [0, 1)");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
// Holm method
|
||||
else if (4 == type) {
|
||||
auto o = order(pvalues, false);
|
||||
std::vector<double> o2Double(o.begin(), o.end());
|
||||
std::vector<double> cummaxInput(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
cummaxInput[i] = (size - i) * pvalues[o[i]];
|
||||
}
|
||||
auto ro = order(o2Double, false);
|
||||
auto cummaxOutput = cummax(cummaxInput);
|
||||
auto pmin = pminx(cummaxOutput, 1.0);
|
||||
std::vector<double> result(size);
|
||||
std::transform(ro.cbegin(), ro.cend(), result.begin(), [&pmin](int a) { return pmin[a]; });
|
||||
return result;
|
||||
}
|
||||
// Hommel
|
||||
else if (5 == type) {
|
||||
auto indices = seqLen(size, size);
|
||||
auto o = order(pvalues, false);
|
||||
std::vector<double> p(size);
|
||||
std::transform(o.cbegin(), o.cend(), p.begin(), [&pvalues](int a) { return pvalues[a]; });
|
||||
std::vector<double> o2Double(o.begin(), o.end());
|
||||
auto ro = order(o2Double, false);
|
||||
std::vector<double> q(size);
|
||||
std::vector<double> pa(size);
|
||||
std::vector<double> npi(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
npi[i] = p[i] * size / indices[i];
|
||||
}
|
||||
double min = *std::min_element(npi.begin(), npi.end());
|
||||
std::fill(q.begin(), q.end(), min);
|
||||
std::fill(pa.begin(), pa.end(), min);
|
||||
for (int j = size; j >= 2; --j) {
|
||||
auto ij = seqLen(1, size - j + 1);
|
||||
std::transform(ij.cbegin(), ij.cend(), ij.begin(), [](int a) { return a - 1; });
|
||||
int i2Length = j - 1;
|
||||
std::vector<int> i2(i2Length);
|
||||
for (int i = 0; i < i2Length; ++i) {
|
||||
i2[i] = size - j + 2 + i - 1;
|
||||
}
|
||||
double q1 = j * p[i2[0]] / 2.0;
|
||||
for (int i = 1; i < i2Length; ++i) {
|
||||
double temp_q1 = p[i2[i]] * j / (2.0 + i);
|
||||
if (temp_q1 < q1) q1 = temp_q1;
|
||||
}
|
||||
for (size_t i = 0; i < size - j + 1; ++i) {
|
||||
q[ij[i]] = std::min(p[ij[i]] * j, q1);
|
||||
}
|
||||
for (int i = 0; i < i2Length; ++i) {
|
||||
q[i2[i]] = q[size - j];
|
||||
}
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (pa[i] < q[i]) {
|
||||
pa[i] = q[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
std::transform(ro.cbegin(), ro.cend(), q.begin(), [&pa](int a) { return pa[a]; });
|
||||
return q;
|
||||
}
|
||||
|
||||
std::vector<double> ni(size);
|
||||
std::vector<int> o = order(pvalues, true);
|
||||
std::vector<double> od(o.begin(), o.end());
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
if (pvalues[i] < 0 || pvalues[i]>1) {
|
||||
throw std::runtime_error("a value is outside [0, 1]");
|
||||
}
|
||||
ni[i] = (double)size / (size - i);
|
||||
}
|
||||
auto ro = order(od, false);
|
||||
std::vector<double> cumminInput(size);
|
||||
if (0 == type) { // BH method
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
cumminInput[i] = ni[i] * pvalues[o[i]];
|
||||
}
|
||||
} else if (1 == type) { // BY method
|
||||
double q = 0;
|
||||
for (size_t i = 1; i < size + 1; ++i) {
|
||||
q += 1.0 / i;
|
||||
}
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
cumminInput[i] = q * ni[i] * pvalues[o[i]];
|
||||
}
|
||||
} else if (3 == type) { // Hochberg method
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
cumminInput[i] = (i + 1) * pvalues[o[i]];
|
||||
}
|
||||
}
|
||||
auto cumminArray = cummin(cumminInput);
|
||||
auto pmin = pminx(cumminArray, 1.0);
|
||||
std::vector<double> result(size);
|
||||
for (size_t i = 0; i < size; ++i) {
|
||||
result[i] = pmin[ro[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int main() {
|
||||
using namespace std;
|
||||
|
||||
vector<double> pvalues{
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
};
|
||||
|
||||
vector<vector<double>> correctAnswers{
|
||||
// Benjamini-Hochberg
|
||||
{
|
||||
6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02
|
||||
},
|
||||
// Benjamini & Yekutieli
|
||||
{
|
||||
1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02
|
||||
},
|
||||
// Bonferroni
|
||||
{
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01
|
||||
},
|
||||
// Hochberg
|
||||
{
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
},
|
||||
// Holm
|
||||
{
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
},
|
||||
// Hommel
|
||||
{
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01
|
||||
}
|
||||
};
|
||||
|
||||
vector<string> types{ "bh", "by", "bonferroni", "hochberg", "holm", "hommel" };
|
||||
for (size_t type = 0; type < types.size(); ++type) {
|
||||
auto q = pAdjust(pvalues, types[type]);
|
||||
double error = 0.0;
|
||||
for (size_t i = 0; i < pvalues.size(); ++i) {
|
||||
error += abs(q[i] - correctAnswers[type][i]);
|
||||
}
|
||||
doubleSay(q);
|
||||
printf("\ntype = %d = '%s' has a cumulative error of %g\n\n\n", type, types[type].c_str(), error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
332
Task/P-value-correction/C-sharp/p-value-correction.cs
Normal file
332
Task/P-value-correction/C-sharp/p-value-correction.cs
Normal file
|
|
@ -0,0 +1,332 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace PValueCorrection {
|
||||
class Program {
|
||||
static List<int> SeqLen(int start, int end) {
|
||||
var result = new List<int>();
|
||||
if (start == end) {
|
||||
for (int i = 0; i < end + 1; ++i) {
|
||||
result.Add(i + 1);
|
||||
}
|
||||
} else if (start < end) {
|
||||
for (int i = 0; i < end - start + 1; ++i) {
|
||||
result.Add(start + i);
|
||||
}
|
||||
} else {
|
||||
for (int i = 0; i < start - end + 1; ++i) {
|
||||
result.Add(start - i);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static List<int> Order(List<double> array, bool decreasing) {
|
||||
List<int> idx = new List<int>();
|
||||
for (int i = 0; i < array.Count; ++i) {
|
||||
idx.Add(i);
|
||||
}
|
||||
|
||||
IComparer<int> cmp;
|
||||
if (decreasing) {
|
||||
cmp = Comparer<int>.Create((a, b) => array[a] < array[b] ? 1 : array[b] < array[a] ? -1 : 0);
|
||||
} else {
|
||||
cmp = Comparer<int>.Create((a, b) => array[b] < array[a] ? 1 : array[a] < array[b] ? -1 : 0);
|
||||
}
|
||||
|
||||
idx.Sort(cmp);
|
||||
return idx;
|
||||
}
|
||||
|
||||
static List<double> Cummin(List<double> array) {
|
||||
if (array.Count < 1) throw new ArgumentOutOfRangeException("cummin requires at least one element");
|
||||
var output = new List<double>();
|
||||
double cumulativeMin = array[0];
|
||||
for (int i = 0; i < array.Count; ++i) {
|
||||
if (array[i] < cumulativeMin) cumulativeMin = array[i];
|
||||
output.Add(cumulativeMin);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
static List<double> Cummax(List<double> array) {
|
||||
if (array.Count < 1) throw new ArgumentOutOfRangeException("cummax requires at least one element");
|
||||
var output = new List<double>();
|
||||
double cumulativeMax = array[0];
|
||||
for (int i = 0; i < array.Count; ++i) {
|
||||
if (array[i] > cumulativeMax) cumulativeMax = array[i];
|
||||
output.Add(cumulativeMax);
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
static List<double> Pminx(List<double> array, double x) {
|
||||
if (array.Count < 1) throw new ArgumentOutOfRangeException("pmin requires at least one element");
|
||||
var result = new List<double>();
|
||||
for (int i = 0; i < array.Count; ++i) {
|
||||
if (array[i] < x) {
|
||||
result.Add(array[i]);
|
||||
} else {
|
||||
result.Add(x);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Say(List<double> array) {
|
||||
Console.Write("[ 1] {0:E}", array[0]);
|
||||
for (int i = 1; i < array.Count; ++i) {
|
||||
Console.Write(" {0:E}", array[i]);
|
||||
if ((i + 1) % 5 == 0) Console.Write("\n[{0,2}]", i + 1);
|
||||
}
|
||||
Console.WriteLine();
|
||||
}
|
||||
|
||||
static List<double> PAdjust(List<double> pvalues, string str) {
|
||||
var size = pvalues.Count;
|
||||
if (size < 1) throw new ArgumentOutOfRangeException("pAdjust requires at least one element");
|
||||
|
||||
int type;
|
||||
switch (str.ToLower()) {
|
||||
case "bh":
|
||||
case "fdr":
|
||||
type = 0;
|
||||
break;
|
||||
case "by":
|
||||
type = 1;
|
||||
break;
|
||||
case "bonferroni":
|
||||
type = 2;
|
||||
break;
|
||||
case "hochberg":
|
||||
type = 3;
|
||||
break;
|
||||
case "holm":
|
||||
type = 4;
|
||||
break;
|
||||
case "hommel":
|
||||
type = 5;
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentException(str + " doesn't match any accepted FDR types");
|
||||
}
|
||||
|
||||
if (2 == type) { // Bonferroni method
|
||||
var result2 = new List<double>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
double b = pvalues[i] * size;
|
||||
if (b >= 1) {
|
||||
result2.Add(1);
|
||||
} else if (0 <= b && b < 1) {
|
||||
result2.Add(b);
|
||||
} else {
|
||||
throw new Exception(b + " is outside [0, 1)");
|
||||
}
|
||||
}
|
||||
return result2;
|
||||
} else if (4 == type) { // Holm method
|
||||
var o4 = Order(pvalues, false);
|
||||
var o4d = o4.ConvertAll(x => (double)x);
|
||||
var cummaxInput = new List<double>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cummaxInput.Add((size - i) * pvalues[o4[i]]);
|
||||
}
|
||||
var ro4 = Order(o4d, false);
|
||||
var cummaxOutput = Cummax(cummaxInput);
|
||||
var pmin4 = Pminx(cummaxOutput, 1.0);
|
||||
var hr = new List<double>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
hr.Add(pmin4[ro4[i]]);
|
||||
}
|
||||
return hr;
|
||||
} else if (5 == type) { // Hommel method
|
||||
var indices = SeqLen(size, size);
|
||||
var o5 = Order(pvalues, false);
|
||||
var p = new List<double>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
p.Add(pvalues[o5[i]]);
|
||||
}
|
||||
var o5d = o5.ConvertAll(x => (double)x);
|
||||
var ro5 = Order(o5d, false);
|
||||
var q = new List<double>();
|
||||
var pa = new List<double>();
|
||||
var npi = new List<double>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
npi.Add(p[i] * size / indices[i]);
|
||||
}
|
||||
double min = npi.Min();
|
||||
q.AddRange(Enumerable.Repeat(min, size));
|
||||
pa.AddRange(Enumerable.Repeat(min, size));
|
||||
for (int j = size; j >= 2; --j) {
|
||||
var ij = SeqLen(1, size - j + 1);
|
||||
for (int i = 0; i < size - j + 1; ++i) {
|
||||
ij[i]--;
|
||||
}
|
||||
int i2Length = j - 1;
|
||||
var i2 = new List<int>();
|
||||
for (int i = 0; i < i2Length; ++i) {
|
||||
i2.Add(size - j + 2 + i - 1);
|
||||
}
|
||||
double q1 = j * p[i2[0]] / 2.0;
|
||||
for (int i = 1; i < i2Length; ++i) {
|
||||
double temp_q1 = p[i2[i]] * j / (2.0 + i);
|
||||
if (temp_q1 < q1) q1 = temp_q1;
|
||||
}
|
||||
for (int i = 0; i < size - j + 1; ++i) {
|
||||
q[ij[i]] = Math.Min(p[ij[i]] * j, q1);
|
||||
}
|
||||
for (int i = 0; i < i2Length; ++i) {
|
||||
q[i2[i]] = q[size - j];
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (pa[i] < q[i]) {
|
||||
pa[i] = q[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
q[i] = pa[ro5[i]];
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
var ni = new List<double>();
|
||||
var o = Order(pvalues, true);
|
||||
var od = o.ConvertAll(x => (double)x);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (pvalues[i] < 0 || pvalues[i] > 1) {
|
||||
throw new Exception("array[" + i + "] = " + pvalues[i] + " is outside [0, 1]");
|
||||
}
|
||||
ni.Add((double)size / (size - i));
|
||||
}
|
||||
var ro = Order(od, false);
|
||||
var cumminInput = new List<double>();
|
||||
if (0 == type) { // BH method
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cumminInput.Add(ni[i] * pvalues[o[i]]);
|
||||
}
|
||||
} else if (1 == type) { // BY method
|
||||
double q = 0;
|
||||
for (int i = 1; i < size + 1; ++i) {
|
||||
q += 1.0 / i;
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cumminInput.Add(q * ni[i] * pvalues[o[i]]);
|
||||
}
|
||||
} else if (3 == type) { // Hochberg method
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cumminInput.Add((i + 1) * pvalues[o[i]]);
|
||||
}
|
||||
}
|
||||
var cumminArray = Cummin(cumminInput);
|
||||
var pmin = Pminx(cumminArray, 1.0);
|
||||
var result = new List<double>();
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result.Add(pmin[ro[i]]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static void Main(string[] args) {
|
||||
var pvalues = new List<double> {
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
};
|
||||
var correctAnswers = new List<List<double>> {
|
||||
new List<double> { // Benjamini-Hochberg
|
||||
6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02
|
||||
},
|
||||
new List<double> { // Benjamini & Yekutieli
|
||||
1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02
|
||||
},
|
||||
new List<double> { // Bonferroni
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01
|
||||
},
|
||||
new List<double> { // Hochberg
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
},
|
||||
new List<double> { // Holm
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
},
|
||||
new List<double> { // Hommel
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01
|
||||
}
|
||||
};
|
||||
|
||||
string[] types = { "bh", "by", "bonferroni", "hochberg", "holm", "hommel" };
|
||||
for (int type = 0; type < types.Length; ++type) {
|
||||
var q = PAdjust(pvalues, types[type]);
|
||||
double error = 0.0;
|
||||
for (int i = 0; i < pvalues.Count; ++i) {
|
||||
error += Math.Abs(q[i] - correctAnswers[type][i]);
|
||||
}
|
||||
Say(q);
|
||||
Console.WriteLine("type {0} = '{1}' has a cumulative error of {2:E}", type, types[type], error);
|
||||
Console.WriteLine();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
548
Task/P-value-correction/C/p-value-correction-1.c
Normal file
548
Task/P-value-correction/C/p-value-correction-1.c
Normal file
|
|
@ -0,0 +1,548 @@
|
|||
#include <stdio.h>//printf
|
||||
#include <stdlib.h>//qsort
|
||||
#include <math.h>//fabs
|
||||
#include <stdbool.h>//bool data type
|
||||
#include <strings.h>//strcasecmp
|
||||
#include <assert.h>//assert, necessary for random integer selection
|
||||
|
||||
unsigned int * seq_len(const unsigned int START, const unsigned int END) {
|
||||
//named after R function of same name, but simpler function
|
||||
unsigned start = (unsigned)START;
|
||||
unsigned end = (unsigned)END;
|
||||
if (START == END) {
|
||||
unsigned int *restrict sequence = malloc( (end+1) * sizeof(unsigned int));
|
||||
if (sequence == NULL) {
|
||||
printf("malloc failed at %s line %u\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned i = 0; i < end; i++) {
|
||||
sequence[i] = i+1;
|
||||
}
|
||||
return sequence;
|
||||
}
|
||||
if (START > END) {
|
||||
end = (unsigned)START;
|
||||
start = (unsigned)END;
|
||||
}
|
||||
const unsigned LENGTH = end - start ;
|
||||
unsigned int *restrict sequence = malloc( (1+LENGTH) * sizeof(unsigned int));
|
||||
if (sequence == NULL) {
|
||||
printf("malloc failed at %s line %u\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (START < END) {
|
||||
for (unsigned index = 0; index <= LENGTH; index++) {
|
||||
sequence[index] = start + index;
|
||||
}
|
||||
} else {
|
||||
for (unsigned index = 0; index <= LENGTH; index++) {
|
||||
sequence[index] = end - index;
|
||||
}
|
||||
}
|
||||
return sequence;
|
||||
}
|
||||
|
||||
//modified from https://phoxis.org/2012/07/12/get-sorted-index-orderting-of-an-array/
|
||||
|
||||
double *restrict base_arr = NULL;
|
||||
|
||||
static int compar_increase (const void *restrict a, const void *restrict b) {
|
||||
int aa = *((int *restrict ) a), bb = *((int *restrict) b);
|
||||
if (base_arr[aa] < base_arr[bb]) {
|
||||
return 1;
|
||||
} else if (base_arr[aa] == base_arr[bb]) {
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
static int compar_decrease (const void *restrict a, const void *restrict b) {
|
||||
int aa = *((int *restrict ) a), bb = *((int *restrict) b);
|
||||
if (base_arr[aa] < base_arr[bb]) {
|
||||
return -1;
|
||||
} else if (base_arr[aa] == base_arr[bb]) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int * order (const double *restrict ARRAY, const unsigned int SIZE, const bool DECREASING) {
|
||||
//this has the same name as the same R function
|
||||
unsigned int *restrict idx = malloc(SIZE * sizeof(unsigned int));
|
||||
if (idx == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
base_arr = malloc(sizeof(double) * SIZE);
|
||||
if (base_arr == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int i = 0; i < SIZE; i++) {
|
||||
base_arr[i] = ARRAY[i];
|
||||
idx[i] = i;
|
||||
}
|
||||
if (DECREASING == false) {
|
||||
qsort(idx, SIZE, sizeof(unsigned int), compar_decrease);
|
||||
} else if (DECREASING == true) {
|
||||
qsort(idx, SIZE, sizeof(unsigned int), compar_increase);
|
||||
}
|
||||
free(base_arr); base_arr = NULL;
|
||||
return idx;
|
||||
}
|
||||
|
||||
double * cummin(const double *restrict ARRAY, const unsigned int NO_OF_ARRAY_ELEMENTS) {
|
||||
//this takes the same name of the R function which it copies
|
||||
//this requires a free() afterward where it is used
|
||||
if (NO_OF_ARRAY_ELEMENTS < 1) {
|
||||
puts("cummin function requires at least one element.\n");
|
||||
printf("Failed at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double *restrict output = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (output == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double cumulative_min = ARRAY[0];
|
||||
for (unsigned int i = 0; i < NO_OF_ARRAY_ELEMENTS; i++) {
|
||||
if (ARRAY[i] < cumulative_min) {
|
||||
cumulative_min = ARRAY[i];
|
||||
}
|
||||
output[i] = cumulative_min;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
double * cummax(const double *restrict ARRAY, const unsigned int NO_OF_ARRAY_ELEMENTS) {
|
||||
//this takes the same name of the R function which it copies
|
||||
//this requires a free() afterward where it is used
|
||||
if (NO_OF_ARRAY_ELEMENTS < 1) {
|
||||
puts("function requires at least one element.\n");
|
||||
printf("Failed at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double *restrict output = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (output == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double cumulative_max = ARRAY[0];
|
||||
for (unsigned int i = 0; i < NO_OF_ARRAY_ELEMENTS; i++) {
|
||||
if (ARRAY[i] > cumulative_max) {
|
||||
cumulative_max = ARRAY[i];
|
||||
}
|
||||
output[i] = cumulative_max;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
double * pminx(const double *restrict ARRAY, const unsigned int NO_OF_ARRAY_ELEMENTS, const double X) {
|
||||
//named after the R function pmin
|
||||
if (NO_OF_ARRAY_ELEMENTS < 1) {
|
||||
puts("pmin requires at least one element.\n");
|
||||
printf("Failed at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double *restrict pmin_array = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (pmin_array == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
if (ARRAY[index] < X) {
|
||||
pmin_array[index] = ARRAY[index];
|
||||
} else {
|
||||
pmin_array[index] = X;
|
||||
}
|
||||
}
|
||||
return pmin_array;
|
||||
}
|
||||
|
||||
void double_say (const double *restrict ARRAY, const size_t NO_OF_ARRAY_ELEMENTS) {
|
||||
printf("[1] %e", ARRAY[0]);
|
||||
for (unsigned int i = 1; i < NO_OF_ARRAY_ELEMENTS; i++) {
|
||||
printf(" %.10f", ARRAY[i]);
|
||||
if (((i+1) % 5) == 0) {
|
||||
printf("\n[%u]", i+1);
|
||||
}
|
||||
}
|
||||
puts("\n");
|
||||
}
|
||||
|
||||
/*void uint_say (const unsigned int *restrict ARRAY, const size_t NO_OF_ARRAY_ELEMENTS) {
|
||||
//for debugging
|
||||
printf("%u", ARRAY[0]);
|
||||
for (size_t i = 1; i < NO_OF_ARRAY_ELEMENTS; i++) {
|
||||
printf(",%u", ARRAY[i]);
|
||||
}
|
||||
puts("\n");
|
||||
}*/
|
||||
|
||||
double * uint2double (const unsigned int *restrict ARRAY, const unsigned int NO_OF_ARRAY_ELEMENTS) {
|
||||
double *restrict doubleArray = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (doubleArray == NULL) {
|
||||
printf("Failure to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
doubleArray[index] = (double)ARRAY[index];
|
||||
}
|
||||
return doubleArray;
|
||||
}
|
||||
|
||||
double min2 (const double N1, const double N2) {
|
||||
if (N1 < N2) {
|
||||
return N1;
|
||||
} else {
|
||||
return N2;
|
||||
}
|
||||
}
|
||||
|
||||
double * p_adjust (const double *restrict PVALUES, const unsigned int NO_OF_ARRAY_ELEMENTS, const char *restrict STRING) {
|
||||
//this function is a translation of R's p.adjust "BH" method
|
||||
// i is always i[index] = NO_OF_ARRAY_ELEMENTS - index - 1
|
||||
if (NO_OF_ARRAY_ELEMENTS < 1) {
|
||||
puts("p_adjust requires at least one element.\n");
|
||||
printf("Failed at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
short int TYPE = -1;
|
||||
if (STRING == NULL) {
|
||||
TYPE = 0;
|
||||
} else if (strcasecmp(STRING, "BH") == 0) {
|
||||
TYPE = 0;
|
||||
} else if (strcasecmp(STRING, "fdr") == 0) {
|
||||
TYPE = 0;
|
||||
} else if (strcasecmp(STRING, "by") == 0) {
|
||||
TYPE = 1;
|
||||
} else if (strcasecmp(STRING, "Bonferroni") == 0) {
|
||||
TYPE = 2;
|
||||
} else if (strcasecmp(STRING, "hochberg") == 0) {
|
||||
TYPE = 3;
|
||||
} else if (strcasecmp(STRING, "holm") == 0) {
|
||||
TYPE = 4;
|
||||
} else if (strcasecmp(STRING, "hommel") == 0) {
|
||||
TYPE = 5;
|
||||
} else {
|
||||
printf("%s doesn't match any accepted FDR methods.\n", STRING);
|
||||
printf("Failed at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
if (TYPE == 2) {//Bonferroni method
|
||||
double *restrict bonferroni = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (bonferroni == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
const double BONFERRONI = PVALUES[index] * NO_OF_ARRAY_ELEMENTS;
|
||||
if (BONFERRONI >= 1.0) {
|
||||
bonferroni[index] = 1.0;
|
||||
} else if ((0.0 <= BONFERRONI) && (BONFERRONI < 1.0)) {
|
||||
bonferroni[index] = BONFERRONI;
|
||||
} else {
|
||||
printf("%g is outside of the interval I planned.\n", BONFERRONI);
|
||||
printf("Failure at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
return bonferroni;
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
} else if (TYPE == 4) {//Holm method
|
||||
/*these values are computed separately from BH, BY, and Hochberg because they are
|
||||
computed differently*/
|
||||
unsigned int *restrict o = order(PVALUES, NO_OF_ARRAY_ELEMENTS, false);
|
||||
//sorted in reverse of methods 0-3
|
||||
double *restrict o2double = uint2double(o, NO_OF_ARRAY_ELEMENTS);
|
||||
double *restrict cummax_input = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
for (unsigned index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
cummax_input[index] = (NO_OF_ARRAY_ELEMENTS - index ) * (double)PVALUES[o[index]];
|
||||
// printf("cummax_input[%zu] = %e\n", index, cummax_input[index]);
|
||||
}
|
||||
free(o); o = NULL;
|
||||
unsigned int *restrict ro = order(o2double, NO_OF_ARRAY_ELEMENTS, false);
|
||||
free(o2double); o2double = NULL;
|
||||
|
||||
double *restrict cummax_output = cummax(cummax_input, NO_OF_ARRAY_ELEMENTS);
|
||||
free(cummax_input); cummax_input = NULL;
|
||||
|
||||
double *restrict pmin = pminx(cummax_output, NO_OF_ARRAY_ELEMENTS, 1);
|
||||
free(cummax_output); cummax_output = NULL;
|
||||
double *restrict qvalues = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
qvalues[index] = pmin[ro[index]];
|
||||
}
|
||||
free(pmin); pmin = NULL;
|
||||
free(ro); ro = NULL;
|
||||
return qvalues;
|
||||
//---------------------------------------------------------------------------
|
||||
//---------------------------------------------------------------------------
|
||||
} else if (TYPE == 5) {//Hommel method
|
||||
//i <- seq_len(n)
|
||||
//o <- order(p)
|
||||
unsigned int *restrict o = order(PVALUES, NO_OF_ARRAY_ELEMENTS, false);//false is R's default
|
||||
//p <- p[o]
|
||||
double *restrict p = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (p == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
p[index] = PVALUES[o[index]];
|
||||
}
|
||||
//ro <- order(o)
|
||||
double *restrict o2double = uint2double(o, NO_OF_ARRAY_ELEMENTS);
|
||||
free(o); o = NULL;
|
||||
unsigned int *restrict ro = order(o2double, NO_OF_ARRAY_ELEMENTS, false);
|
||||
free(o2double); o2double = NULL;
|
||||
// puts("ro");
|
||||
//q <- pa <- rep.int(min(n * p/i), n)
|
||||
double *restrict q = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (q == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double *restrict pa = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (pa == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double min = (double)NO_OF_ARRAY_ELEMENTS * p[0];
|
||||
for (unsigned index = 1; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
const double TEMP = (double)NO_OF_ARRAY_ELEMENTS * p[index] / (double)(1+index);
|
||||
if (TEMP < min) {
|
||||
min = TEMP;
|
||||
}
|
||||
}
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
pa[index] = min;
|
||||
q[index] = min;
|
||||
}
|
||||
// puts("q & pa");
|
||||
// double_say(q, NO_OF_ARRAY_ELEMENTS);
|
||||
/*for (j in (n - 1):2) {
|
||||
ij <- seq_len(n - j + 1)
|
||||
i2 <- (n - j + 2):n
|
||||
q1 <- min(j * p[i2]/(2:j))
|
||||
q[ij] <- pmin(j * p[ij], q1)
|
||||
q[i2] <- q[n - j + 1]
|
||||
pa <- pmax(pa, q)
|
||||
}
|
||||
*/
|
||||
for (unsigned j = (NO_OF_ARRAY_ELEMENTS-1); j >= 2; j--) {
|
||||
// printf("j = %zu\n", j);
|
||||
unsigned int *restrict ij = seq_len(0,NO_OF_ARRAY_ELEMENTS - j);
|
||||
const size_t I2_LENGTH = j - 1;
|
||||
unsigned int *restrict i2 = malloc(I2_LENGTH * sizeof(unsigned int));
|
||||
for (unsigned i = 0; i < I2_LENGTH; i++) {
|
||||
i2[i] = NO_OF_ARRAY_ELEMENTS-j+2+i-1;
|
||||
//R's indices are 1-based, C's are 0-based, I added the -1
|
||||
}
|
||||
|
||||
double q1 = (double)j * p[i2[0]] / 2.0;
|
||||
for (unsigned int i = 1; i < I2_LENGTH; i++) {//loop through 2:j
|
||||
const double TEMP_Q1 = (double)j * p[i2[i]] / (double)(2 + i);
|
||||
if (TEMP_Q1 < q1) {
|
||||
q1 = TEMP_Q1;
|
||||
}
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < (NO_OF_ARRAY_ELEMENTS - j + 1); i++) {//q[ij] <- pmin(j * p[ij], q1)
|
||||
q[ij[i]] = min2( (double)j*p[ij[i]], q1);
|
||||
}
|
||||
free(ij); ij = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < I2_LENGTH; i++) {//q[i2] <- q[n - j + 1]
|
||||
q[i2[i]] = q[NO_OF_ARRAY_ELEMENTS - j];//subtract 1 because of starting index difference
|
||||
}
|
||||
free(i2); i2 = NULL;
|
||||
|
||||
for (unsigned int i = 0; i < NO_OF_ARRAY_ELEMENTS; i++) {//pa <- pmax(pa, q)
|
||||
if (pa[i] < q[i]) {
|
||||
pa[i] = q[i];
|
||||
}
|
||||
}
|
||||
// printf("j = %zu, pa = \n", j);
|
||||
// double_say(pa, N);
|
||||
}//end j loop
|
||||
free(p); p = NULL;
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
q[index] = pa[ro[index]];//Hommel q-values
|
||||
}
|
||||
//now free memory
|
||||
free(ro); ro = NULL;
|
||||
free(pa); pa = NULL;
|
||||
return q;
|
||||
}
|
||||
//The methods are similarly computed and thus can be combined for clarity
|
||||
unsigned int *restrict o = order(PVALUES, NO_OF_ARRAY_ELEMENTS, true);
|
||||
if (o == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
double *restrict o_double = uint2double(o, NO_OF_ARRAY_ELEMENTS);
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
if ((PVALUES[index] < 0) || (PVALUES[index] > 1)) {
|
||||
printf("array[%u] = %lf, which is outside the interval [0,1]\n", index, PVALUES[index]);
|
||||
printf("died at %s line %u\n", __FILE__, __LINE__);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
unsigned int *restrict ro = order(o_double, NO_OF_ARRAY_ELEMENTS, false);
|
||||
if (ro == NULL) {
|
||||
printf("failed to malloc at %s line %u.\n", __FILE__, __LINE__);
|
||||
perror("");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
free(o_double); o_double = NULL;
|
||||
double *restrict cummin_input = malloc(sizeof(double) * NO_OF_ARRAY_ELEMENTS);
|
||||
if (TYPE == 0) {//BH method
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
const double NI = (double)NO_OF_ARRAY_ELEMENTS / (double)(NO_OF_ARRAY_ELEMENTS - index);// n/i simplified
|
||||
cummin_input[index] = NI * PVALUES[o[index]];//PVALUES[o[index]] is p[o]
|
||||
}
|
||||
} else if (TYPE == 1) {//BY method
|
||||
double q = 1.0;
|
||||
for (unsigned int index = 2; index < (1+NO_OF_ARRAY_ELEMENTS); index++) {
|
||||
q += 1.0/(double)index;
|
||||
}
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
const double NI = (double)NO_OF_ARRAY_ELEMENTS / (double)(NO_OF_ARRAY_ELEMENTS - index);// n/i simplified
|
||||
cummin_input[index] = q * NI * PVALUES[o[index]];//PVALUES[o[index]] is p[o]
|
||||
}
|
||||
} else if (TYPE == 3) {//Hochberg method
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
// pmin(1, cummin((n - i + 1L) * p[o]))[ro]
|
||||
cummin_input[index] = (double)(index + 1) * PVALUES[o[index]];
|
||||
}
|
||||
}
|
||||
free(o); o = NULL;
|
||||
double *restrict cummin_array = NULL;
|
||||
cummin_array = cummin(cummin_input, NO_OF_ARRAY_ELEMENTS);
|
||||
free(cummin_input); cummin_input = NULL;//I don't need this anymore
|
||||
double *restrict pmin = pminx(cummin_array, NO_OF_ARRAY_ELEMENTS, 1);
|
||||
free(cummin_array); cummin_array = NULL;
|
||||
double *restrict q_array = malloc(NO_OF_ARRAY_ELEMENTS*sizeof(double));
|
||||
for (unsigned int index = 0; index < NO_OF_ARRAY_ELEMENTS; index++) {
|
||||
q_array[index] = pmin[ro[index]];
|
||||
}
|
||||
|
||||
free(ro); ro = NULL;
|
||||
free(pmin); pmin = NULL;
|
||||
return q_array;
|
||||
}
|
||||
|
||||
|
||||
int main(void) {
|
||||
const double PVALUES[] = {4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03};//just the pvalues
|
||||
const double CORRECT_ANSWERS[6][50] = {//each first index is type
|
||||
{6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02},//Benjamini-Hochberg
|
||||
{1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02},//Benjamini & Yekutieli
|
||||
{1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01},//Bonferroni
|
||||
{9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01},//Hochberg
|
||||
{1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01},//Holm
|
||||
{ 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01}//Hommel
|
||||
};
|
||||
//the following loop checks each type with R's answers
|
||||
const char *restrict TYPES[] = {"bh", "by", "bonferroni", "hochberg", "holm", "hommel"};
|
||||
for (unsigned short int type = 0; type <= 5; type++) {
|
||||
double *restrict q = p_adjust(PVALUES, sizeof(PVALUES) / sizeof(*PVALUES), TYPES[type]);
|
||||
double error = fabs(q[0] - CORRECT_ANSWERS[type][0]);
|
||||
// printf("%e - %e = %g\n", q[0], CORRECT_ANSWERS[type][0], error);
|
||||
// puts("p q");
|
||||
// printf("%g\t%g\n", pvalues[0], q[0]);
|
||||
for (unsigned int i = 1; i < sizeof(PVALUES) / sizeof(*PVALUES); i++) {
|
||||
const double this_error = fabs(q[i] - CORRECT_ANSWERS[type][i]);
|
||||
// printf("%e - %e = %g\n", q[i], CORRECT_ANSWERS[type][i], error);
|
||||
error += this_error;
|
||||
}
|
||||
double_say(q, sizeof(PVALUES) / sizeof(*PVALUES));
|
||||
free(q); q = NULL;
|
||||
printf("\ntype %u = '%s' has cumulative error of %g\n", type, TYPES[type], error);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
195
Task/P-value-correction/C/p-value-correction-2.c
Normal file
195
Task/P-value-correction/C/p-value-correction-2.c
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
|
||||
#define SIZE 50
|
||||
#define each_i(start, end) for (i = start; i < end; ++i)
|
||||
|
||||
typedef enum { UP, DOWN } direction;
|
||||
|
||||
typedef struct { int index; double value; } iv1;
|
||||
|
||||
typedef struct { int index; int value; } iv2;
|
||||
|
||||
/* test also for 'Unknown' correction type */
|
||||
const char *types[8] = {
|
||||
"Benjamini-Hochberg", "Benjamini-Yekutieli", "Bonferroni", "Hochberg",
|
||||
"Holm", "Hommel", "Šidák", "Unknown"
|
||||
};
|
||||
|
||||
int compare_iv1(const void *a, const void *b) {
|
||||
double aa = ((iv1 *)a) -> value;
|
||||
double bb = ((iv1 *)b) -> value;
|
||||
if (aa > bb) return 1;
|
||||
if (aa < bb) return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int compare_iv1_desc(const void *a, const void *b) {
|
||||
return -compare_iv1(a, b);
|
||||
}
|
||||
|
||||
int compare_iv2(const void *a, const void *b) {
|
||||
return ((iv2 *)a) -> value - ((iv2 *)b) -> value;
|
||||
}
|
||||
|
||||
void ratchet(double *pa, direction dir) {
|
||||
int i;
|
||||
double m = pa[0];
|
||||
if (dir == UP) {
|
||||
each_i(1, SIZE) {
|
||||
if (pa[i] > m) pa[i] = m;
|
||||
m = pa[i];
|
||||
}
|
||||
}
|
||||
else {
|
||||
each_i(1, SIZE) {
|
||||
if (pa[i] < m) pa[i] = m;
|
||||
m = pa[i];
|
||||
}
|
||||
}
|
||||
each_i(0, SIZE) if (pa[i] > 1.0) pa[i] = 1.0;
|
||||
}
|
||||
|
||||
void schwartzian(const double *p, double *pa, direction dir) {
|
||||
int i;
|
||||
int order[SIZE];
|
||||
int order2[SIZE];
|
||||
iv1 iv1s[SIZE];
|
||||
iv2 iv2s[SIZE];
|
||||
double pa2[SIZE];
|
||||
each_i(0, SIZE) { iv1s[i].index = i; iv1s[i].value = p[i]; }
|
||||
if (dir == UP)
|
||||
qsort(iv1s, SIZE, sizeof(iv1s[0]), compare_iv1_desc);
|
||||
else
|
||||
qsort(iv1s, SIZE, sizeof(iv1s[0]), compare_iv1);
|
||||
each_i(0, SIZE) order[i] = iv1s[i].index;
|
||||
each_i(0, SIZE) pa[i] *= p[order[i]];
|
||||
ratchet(pa, dir);
|
||||
each_i(0, SIZE) { iv2s[i].index = i; iv2s[i].value = order[i]; }
|
||||
qsort(iv2s, SIZE, sizeof(iv2s[0]), compare_iv2);
|
||||
each_i(0, SIZE) order2[i] = iv2s[i].index;
|
||||
each_i(0, SIZE) pa2[i] = pa[order2[i]];
|
||||
each_i(0, SIZE) pa[i] = pa2[i];
|
||||
}
|
||||
|
||||
void adjust(const double *p, double *pa, const char *type) {
|
||||
int i;
|
||||
if (!strcmp(type, "Benjamini-Hochberg")) {
|
||||
each_i(0, SIZE) pa[i] = (double)SIZE / (SIZE - i);
|
||||
schwartzian(p, pa, UP);
|
||||
}
|
||||
else if (!strcmp(type, "Benjamini-Yekutieli")) {
|
||||
double q = 0.0;
|
||||
each_i(1, SIZE + 1) q += 1.0 / i;
|
||||
each_i(0, SIZE) pa[i] = q * SIZE / (SIZE - i);
|
||||
schwartzian(p, pa, UP);
|
||||
}
|
||||
else if (!strcmp(type, "Bonferroni")) {
|
||||
each_i(0, SIZE) pa[i] = (p[i] * SIZE > 1.0) ? 1.0 : p[i] * SIZE;
|
||||
}
|
||||
else if (!strcmp(type, "Hochberg")) {
|
||||
each_i(0, SIZE) pa[i] = i + 1.0;
|
||||
schwartzian(p, pa, UP);
|
||||
}
|
||||
else if (!strcmp(type, "Holm")) {
|
||||
each_i(0, SIZE) pa[i] = SIZE - i;
|
||||
schwartzian(p, pa, DOWN);
|
||||
}
|
||||
else if (!strcmp(type, "Hommel")) {
|
||||
int i, j;
|
||||
int order[SIZE];
|
||||
int order2[SIZE];
|
||||
iv1 iv1s[SIZE];
|
||||
iv2 iv2s[SIZE];
|
||||
double s[SIZE];
|
||||
double q[SIZE];
|
||||
double pa2[SIZE];
|
||||
int indices[SIZE];
|
||||
each_i(0, SIZE) { iv1s[i].index = i; iv1s[i].value = p[i]; }
|
||||
qsort(iv1s, SIZE, sizeof(iv1s[0]), compare_iv1);
|
||||
each_i(0, SIZE) order[i] = iv1s[i].index;
|
||||
each_i(0, SIZE) s[i] = p[order[i]];
|
||||
double min = s[0] * SIZE;
|
||||
each_i(1, SIZE) {
|
||||
double temp = s[i] / (i + 1.0);
|
||||
if (temp < min) min = temp;
|
||||
}
|
||||
each_i(0, SIZE) q[i] = min;
|
||||
each_i(0, SIZE) pa2[i] = min;
|
||||
for (j = SIZE - 1; j >= 2; --j) {
|
||||
each_i(0, SIZE) indices[i] = i;
|
||||
int upper_start = SIZE - j + 1; /* upper indices start index */
|
||||
int upper_size = j - 1; /* size of upper indices */
|
||||
int lower_size = SIZE - upper_size; /* size of lower indices */
|
||||
double qmin = j * s[indices[upper_start]] / 2.0;
|
||||
each_i(1, upper_size) {
|
||||
double temp = s[indices[upper_start + i]] * j / (2.0 + i);
|
||||
if (temp < qmin) qmin = temp;
|
||||
}
|
||||
each_i(0, lower_size) {
|
||||
double temp = s[indices[i]] * j;
|
||||
q[indices[i]] = (temp < qmin) ? temp : qmin;
|
||||
}
|
||||
each_i(0, upper_size) q[indices[upper_start + i]] = q[SIZE - j];
|
||||
each_i(0, SIZE) if (pa2[i] < q[i]) pa2[i] = q[i];
|
||||
}
|
||||
each_i(0, SIZE) { iv2s[i].index = i; iv2s[i].value = order[i]; }
|
||||
qsort(iv2s, SIZE, sizeof(iv2s[0]), compare_iv2);
|
||||
each_i(0, SIZE) order2[i] = iv2s[i].index;
|
||||
each_i(0, SIZE) pa[i] = pa2[order2[i]];
|
||||
}
|
||||
else if (!strcmp(type, "Šidák")) {
|
||||
each_i(0, SIZE) pa[i] = 1.0 - pow(1.0 - p[i], SIZE);
|
||||
}
|
||||
else {
|
||||
printf("\nSorry, do not know how to do '%s' correction.\n", type);
|
||||
printf("Perhaps you want one of these?:\n");
|
||||
each_i(0, 7) printf(" %s\n", types[i]);
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
void adjusted(const double *p, const char *type) {
|
||||
int i;
|
||||
double pa[SIZE] = { 0.0 };
|
||||
if (check(p)) {
|
||||
adjust(p, pa, type);
|
||||
printf("\n%s", type);
|
||||
each_i(0, SIZE) {
|
||||
if (!(i % 5)) printf("\n[%2d] ", i);
|
||||
printf("%1.10f ", pa[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
else {
|
||||
printf("p-values must be in range 0.0 to 1.0\n");
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
int check(const double* p) {
|
||||
int i;
|
||||
each_i(0, SIZE) {
|
||||
if (p[i] < 0.0 || p[i] > 1.0) return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int main() {
|
||||
int i;
|
||||
double p_values[SIZE] = {
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
};
|
||||
each_i(0, 8) adjusted(p_values, types[i]);
|
||||
return 0;
|
||||
}
|
||||
340
Task/P-value-correction/D/p-value-correction.d
Normal file
340
Task/P-value-correction/D/p-value-correction.d
Normal file
|
|
@ -0,0 +1,340 @@
|
|||
import std.algorithm;
|
||||
import std.conv;
|
||||
import std.math;
|
||||
import std.stdio;
|
||||
import std.string;
|
||||
|
||||
int[] seqLen(int start, int end) {
|
||||
int[] result;
|
||||
if (start == end) {
|
||||
result.length = end+1;
|
||||
for (int i; i<result.length; i++) {
|
||||
result[i] = i+1;
|
||||
}
|
||||
} else if (start < end) {
|
||||
result.length = end - start + 1;
|
||||
for (int i; i<result.length; i++) {
|
||||
result[i] = start+i;
|
||||
}
|
||||
} else {
|
||||
result.length = start - end + 1;
|
||||
for (int i; i<result.length; i++) {
|
||||
result[i] = start-i;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int[] order(double[] array, bool decreasing) {
|
||||
int size = array.length;
|
||||
int[] idx;
|
||||
idx.length = size;
|
||||
double[] baseArr;
|
||||
baseArr.length = size;
|
||||
for (int i; i<size; i++) {
|
||||
baseArr[i] = array[i];
|
||||
idx[i] = i;
|
||||
}
|
||||
if (!decreasing) {
|
||||
alias comp = (a,b) => baseArr[a] < baseArr[b];
|
||||
idx.sort!comp;
|
||||
} else {
|
||||
alias comp = (a,b) => baseArr[b] < baseArr[a];
|
||||
idx.sort!comp;
|
||||
}
|
||||
return idx;
|
||||
}
|
||||
|
||||
double[] cummin(double[] array) {
|
||||
int size = array.length;
|
||||
if (size < 1) throw new Exception("cummin requires at least one element");
|
||||
double[] output;
|
||||
output.length = size;
|
||||
auto cumulativeMin = array[0];
|
||||
foreach (i; 0..size) {
|
||||
if (array[i] < cumulativeMin) cumulativeMin = array[i];
|
||||
output[i] = cumulativeMin;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
double[] cummax(double[] array) {
|
||||
auto size = array.length;
|
||||
if (size < 1) throw new Exception("cummax requires at least one element");
|
||||
double[] output;
|
||||
output.length = size;
|
||||
auto cumulativeMax = array[0];
|
||||
foreach (i; 0..size) {
|
||||
if (array[i] > cumulativeMax) cumulativeMax = array[i];
|
||||
output[i] = cumulativeMax;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
double[] pminx(double[] array, double x) {
|
||||
auto size = array.length;
|
||||
if (size < 1) throw new Exception("pmin requires at least one element");
|
||||
double[] result;
|
||||
result.length = size;
|
||||
foreach (i; 0..size) {
|
||||
if (array[i] < x) {
|
||||
result[i] = array[i];
|
||||
} else {
|
||||
result[i] = x;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void doubleSay(double[] array) {
|
||||
writef("[ 1] %e", array[0]);
|
||||
foreach (i; 1..array.length) {
|
||||
writef(" %.10f", array[i]);
|
||||
if ((i+1) % 5 == 0) writef("\n[%2d]", i+1);
|
||||
}
|
||||
writeln;
|
||||
}
|
||||
|
||||
auto toArray(T,U)(U[] array) {
|
||||
T[] result;
|
||||
result.length = array.length;
|
||||
foreach(i; 0..array.length) {
|
||||
result[i] = to!T(array[i]);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
double[] pAdjust(double[] pvalues, string str) {
|
||||
auto size = pvalues.length;
|
||||
if (size < 1) throw new Exception("pAdjust requires at least one element");
|
||||
int type = str.toLower.predSwitch!"a==b"(
|
||||
"bh", 0,
|
||||
"fdr", 0,
|
||||
"by", 1,
|
||||
"bonferroni", 2,
|
||||
"hochberg", 3,
|
||||
"holm", 4,
|
||||
"hommel", 5,
|
||||
{ throw new Exception(text("'",str,"' doesn't match any accepted FDR types")); }()
|
||||
);
|
||||
if (type == 2) { // Bonferroni method
|
||||
double[] result;
|
||||
result.length = size;
|
||||
foreach (i; 0..size) {
|
||||
auto b = pvalues[i] * size;
|
||||
if (b >= 1) {
|
||||
result[i] = 1;
|
||||
} else if (0 <= b && b < 1) {
|
||||
result[i] = b;
|
||||
} else {
|
||||
throw new Exception(text(b," is outside [0, 1)"));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else if (type == 4) { // Holm method
|
||||
auto o = order(pvalues, false);
|
||||
auto o2Double = toArray!(double,int)(o);
|
||||
double[] cummaxInput;
|
||||
cummaxInput.length = size;
|
||||
foreach (i; 0..size) {
|
||||
cummaxInput[i] = (size-i) * pvalues[o[i]];
|
||||
}
|
||||
auto ro = order(o2Double, false);
|
||||
auto cummaxOutput = cummax(cummaxInput);
|
||||
auto pmin = pminx(cummaxOutput, 1.0);
|
||||
double[] result;
|
||||
result.length = size;
|
||||
foreach (i; 0..size) {
|
||||
result[i] = pmin[ro[i]];
|
||||
}
|
||||
return result;
|
||||
} else if (type == 5) {
|
||||
auto indices = seqLen(size, size);
|
||||
auto o = order(pvalues, false);
|
||||
double[] p;
|
||||
p.length = size;
|
||||
foreach (i; 0..size) {
|
||||
p[i] = pvalues[o[i]];
|
||||
}
|
||||
auto o2Double = toArray!double(o);
|
||||
auto ro = order(o2Double, false);
|
||||
double[] q;
|
||||
q.length = size;
|
||||
double[] pa;
|
||||
pa.length = size;
|
||||
double[] npi;
|
||||
npi.length = size;
|
||||
foreach (i; 0..size) {
|
||||
npi[i] = p[i] * size / indices[i];
|
||||
}
|
||||
auto min_ = reduce!min(npi);
|
||||
q[] = min_;
|
||||
pa[] = min_;
|
||||
foreach_reverse (j; 2..size) {
|
||||
auto ij = seqLen(1, size - j + 1);
|
||||
foreach (i; 0..size-j+1) {
|
||||
ij[i]--;
|
||||
}
|
||||
auto i2Length = j-1;
|
||||
int[] i2;
|
||||
i2.length = i2Length;
|
||||
foreach(i; 0..i2Length) {
|
||||
i2[i] = size-j+2+i-1;
|
||||
}
|
||||
auto pi2Length = i2Length;
|
||||
double q1 = j*p[i2[0]] / 2.0;
|
||||
foreach (i; 1..pi2Length) {
|
||||
auto temp_q1 = p[i2[i]] * j / (2.0 + i);
|
||||
if (temp_q1 < q1) q1 = temp_q1;
|
||||
}
|
||||
foreach (i; 0..size-j+1) {
|
||||
q[ij[i]] = min(p[ij[i]] * j, q1);
|
||||
}
|
||||
foreach(i; 0..i2Length) {
|
||||
q[i2[i]] = q[size-j];
|
||||
}
|
||||
foreach(i; 0..size) if (pa[i] < q[i]) pa[i] = q[i];
|
||||
}
|
||||
foreach (index; 0..size) {
|
||||
q[index] = pa[ro[index]];
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
double[] ni;
|
||||
ni.length = size;
|
||||
auto o = order(pvalues, true);
|
||||
auto oDouble = toArray!double(o);
|
||||
foreach (index; 0..size) {
|
||||
if (pvalues[index] < 0 || pvalues[index] > 1) {
|
||||
throw new Exception(text("array[", index, "] = ", pvalues[index], " is outside [0, 1]"));
|
||||
}
|
||||
ni[index] = cast(double) size / (size - index);
|
||||
}
|
||||
auto ro = order(oDouble, false);
|
||||
double[] cumminInput;
|
||||
cumminInput.length = size;
|
||||
if (type == 0) { // BH method
|
||||
foreach (index; 0..size) {
|
||||
cumminInput[index] = ni[index] * pvalues[o[index]];
|
||||
}
|
||||
} else if (type == 1) { // BY method
|
||||
double q = 0;
|
||||
foreach (index; 1..size+1) q += 1.0 / index;
|
||||
foreach (index; 0..size) {
|
||||
cumminInput[index] = q * ni[index] * pvalues[o[index]];
|
||||
}
|
||||
} else if (type == 3) { // Hochberg method
|
||||
foreach (index; 0..size) {
|
||||
cumminInput[index] = (index + 1) * pvalues[o[index]];
|
||||
}
|
||||
}
|
||||
auto cumminArray =cummin(cumminInput);
|
||||
auto pmin = pminx(cumminArray, 1.0);
|
||||
double[] result;
|
||||
result.length = size;
|
||||
foreach (i; 0..size) {
|
||||
result[i] = pmin[ro[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
void main() {
|
||||
double[] pvalues = [
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
];
|
||||
|
||||
double[][] correctAnswers = [
|
||||
[ // Benjamini-Hochberg
|
||||
6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02
|
||||
],
|
||||
[ // Benjamini & Yekutieli
|
||||
1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02
|
||||
],
|
||||
[ // Bonferroni
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01
|
||||
],
|
||||
[ // Hochberg
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
],
|
||||
[ // Holm
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
],
|
||||
[ // Hommel
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01
|
||||
]
|
||||
];
|
||||
auto types = ["bh", "by", "bonferroni", "hochberg", "holm", "hommel"];
|
||||
foreach (type; 0..types.length) {
|
||||
auto q = pAdjust(pvalues, types[type]);
|
||||
double error = 0.0;
|
||||
foreach (i; 0..pvalues.length) {
|
||||
error += abs(q[i] - correctAnswers[type][i]);
|
||||
}
|
||||
doubleSay(q);
|
||||
writefln("\ntype %d = '%s' has a cumulative error of %g", type, types[type], error);
|
||||
}
|
||||
}
|
||||
304
Task/P-value-correction/Go/p-value-correction.go
Normal file
304
Task/P-value-correction/Go/p-value-correction.go
Normal file
|
|
@ -0,0 +1,304 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"log"
|
||||
"math"
|
||||
"os"
|
||||
"sort"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type pvalues = []float64
|
||||
|
||||
type iv1 struct {
|
||||
index int
|
||||
value float64
|
||||
}
|
||||
type iv2 struct{ index, value int }
|
||||
|
||||
type direction int
|
||||
|
||||
const (
|
||||
up direction = iota
|
||||
down
|
||||
)
|
||||
|
||||
// Test also for 'Unknown' correction type.
|
||||
var ctypes = []string{
|
||||
"Benjamini-Hochberg", "Benjamini-Yekutieli", "Bonferroni", "Hochberg",
|
||||
"Holm", "Hommel", "Šidák", "Unknown",
|
||||
}
|
||||
|
||||
func minimum(p pvalues) float64 {
|
||||
m := p[0]
|
||||
for i := 1; i < len(p); i++ {
|
||||
if p[i] < m {
|
||||
m = p[i]
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func maximum(p pvalues) float64 {
|
||||
m := p[0]
|
||||
for i := 1; i < len(p); i++ {
|
||||
if p[i] > m {
|
||||
m = p[i]
|
||||
}
|
||||
}
|
||||
return m
|
||||
}
|
||||
|
||||
func adjusted(p pvalues, ctype string) (string, error) {
|
||||
err := check(p)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
temp := pformat(adjust(p, ctype), 5)
|
||||
return fmt.Sprintf("\n%s\n%s", ctype, temp), nil
|
||||
}
|
||||
|
||||
func pformat(p pvalues, cols int) string {
|
||||
var lines []string
|
||||
for i := 0; i < len(p); i += cols {
|
||||
fchunk := p[i : i+cols]
|
||||
schunk := make([]string, cols)
|
||||
for j := 0; j < cols; j++ {
|
||||
schunk[j] = strconv.FormatFloat(fchunk[j], 'f', 10, 64)
|
||||
}
|
||||
lines = append(lines, fmt.Sprintf("[%2d] %s", i, strings.Join(schunk, " ")))
|
||||
}
|
||||
return strings.Join(lines, "\n")
|
||||
}
|
||||
|
||||
func check(p []float64) error {
|
||||
cond := len(p) > 0 && minimum(p) >= 0 && maximum(p) <= 1
|
||||
if !cond {
|
||||
return fmt.Errorf("p-values must be in range 0.0 to 1.0")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func ratchet(p pvalues, dir direction) {
|
||||
size := len(p)
|
||||
m := p[0]
|
||||
if dir == up {
|
||||
for i := 1; i < size; i++ {
|
||||
if p[i] > m {
|
||||
p[i] = m
|
||||
}
|
||||
m = p[i]
|
||||
}
|
||||
} else {
|
||||
for i := 1; i < size; i++ {
|
||||
if p[i] < m {
|
||||
p[i] = m
|
||||
}
|
||||
m = p[i]
|
||||
}
|
||||
}
|
||||
for i := 0; i < size; i++ {
|
||||
if p[i] > 1.0 {
|
||||
p[i] = 1.0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func schwartzian(p pvalues, mult pvalues, dir direction) pvalues {
|
||||
size := len(p)
|
||||
order := make([]int, size)
|
||||
iv1s := make([]iv1, size)
|
||||
for i := 0; i < size; i++ {
|
||||
iv1s[i] = iv1{i, p[i]}
|
||||
}
|
||||
if dir == up {
|
||||
sort.Slice(iv1s, func(i, j int) bool {
|
||||
return iv1s[i].value > iv1s[j].value
|
||||
})
|
||||
} else {
|
||||
sort.Slice(iv1s, func(i, j int) bool {
|
||||
return iv1s[i].value < iv1s[j].value
|
||||
})
|
||||
}
|
||||
for i := 0; i < size; i++ {
|
||||
order[i] = iv1s[i].index
|
||||
}
|
||||
pa := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
pa[i] = mult[i] * p[order[i]]
|
||||
}
|
||||
ratchet(pa, dir)
|
||||
order2 := make([]int, size)
|
||||
iv2s := make([]iv2, size)
|
||||
for i := 0; i < size; i++ {
|
||||
iv2s[i] = iv2{i, order[i]}
|
||||
}
|
||||
sort.Slice(iv2s, func(i, j int) bool {
|
||||
return iv2s[i].value < iv2s[j].value
|
||||
})
|
||||
for i := 0; i < size; i++ {
|
||||
order2[i] = iv2s[i].index
|
||||
}
|
||||
pa2 := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
pa2[i] = pa[order2[i]]
|
||||
}
|
||||
return pa2
|
||||
}
|
||||
|
||||
func adjust(p pvalues, ctype string) pvalues {
|
||||
size := len(p)
|
||||
if size == 0 {
|
||||
return p
|
||||
}
|
||||
fsize := float64(size)
|
||||
switch ctype {
|
||||
case "Benjamini-Hochberg":
|
||||
mult := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
mult[i] = fsize / float64(size-i)
|
||||
}
|
||||
return schwartzian(p, mult, up)
|
||||
case "Benjamini-Yekutieli":
|
||||
q := 0.0
|
||||
for i := 1; i <= size; i++ {
|
||||
q += 1.0 / float64(i)
|
||||
}
|
||||
mult := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
mult[i] = q * fsize / (fsize - float64(i))
|
||||
}
|
||||
return schwartzian(p, mult, up)
|
||||
case "Bonferroni":
|
||||
p2 := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
p2[i] = math.Min(p[i]*fsize, 1.0)
|
||||
}
|
||||
return p2
|
||||
case "Hochberg":
|
||||
mult := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
mult[i] = float64(i) + 1
|
||||
}
|
||||
return schwartzian(p, mult, up)
|
||||
case "Holm":
|
||||
mult := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
mult[i] = fsize - float64(i)
|
||||
}
|
||||
return schwartzian(p, mult, down)
|
||||
case "Hommel":
|
||||
order := make([]int, size)
|
||||
iv1s := make([]iv1, size)
|
||||
for i := 0; i < size; i++ {
|
||||
iv1s[i] = iv1{i, p[i]}
|
||||
}
|
||||
sort.Slice(iv1s, func(i, j int) bool {
|
||||
return iv1s[i].value < iv1s[j].value
|
||||
})
|
||||
for i := 0; i < size; i++ {
|
||||
order[i] = iv1s[i].index
|
||||
}
|
||||
s := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
s[i] = p[order[i]]
|
||||
}
|
||||
m := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
m[i] = s[i] * fsize / (float64(i) + 1)
|
||||
}
|
||||
min := minimum(m)
|
||||
q := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
q[i] = min
|
||||
}
|
||||
pa := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
pa[i] = min
|
||||
}
|
||||
for j := size - 1; j >= 2; j-- {
|
||||
lower := make([]int, size-j+1) // lower indices
|
||||
for i := 0; i < len(lower); i++ {
|
||||
lower[i] = i
|
||||
}
|
||||
upper := make([]int, j-1) // upper indices
|
||||
for i := 0; i < len(upper); i++ {
|
||||
upper[i] = size - j + 1 + i
|
||||
}
|
||||
qmin := float64(j) * s[upper[0]] / 2.0
|
||||
for i := 1; i < len(upper); i++ {
|
||||
temp := s[upper[i]] * float64(j) / (2.0 + float64(i))
|
||||
if temp < qmin {
|
||||
qmin = temp
|
||||
}
|
||||
}
|
||||
for i := 0; i < len(lower); i++ {
|
||||
q[lower[i]] = math.Min(s[lower[i]]*float64(j), qmin)
|
||||
}
|
||||
for i := 0; i < len(upper); i++ {
|
||||
q[upper[i]] = q[size-j]
|
||||
}
|
||||
for i := 0; i < size; i++ {
|
||||
if pa[i] < q[i] {
|
||||
pa[i] = q[i]
|
||||
}
|
||||
}
|
||||
}
|
||||
order2 := make([]int, size)
|
||||
iv2s := make([]iv2, size)
|
||||
for i := 0; i < size; i++ {
|
||||
iv2s[i] = iv2{i, order[i]}
|
||||
}
|
||||
sort.Slice(iv2s, func(i, j int) bool {
|
||||
return iv2s[i].value < iv2s[j].value
|
||||
})
|
||||
for i := 0; i < size; i++ {
|
||||
order2[i] = iv2s[i].index
|
||||
}
|
||||
pa2 := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
pa2[i] = pa[order2[i]]
|
||||
}
|
||||
return pa2
|
||||
case "Šidák":
|
||||
p2 := make(pvalues, size)
|
||||
for i := 0; i < size; i++ {
|
||||
p2[i] = 1.0 - math.Pow(1.0-float64(p[i]), fsize)
|
||||
}
|
||||
return p2
|
||||
default:
|
||||
fmt.Printf("\nSorry, do not know how to do '%s' correction.\n", ctype)
|
||||
fmt.Println("Perhaps you want one of these?:")
|
||||
temp := make([]string, len(ctypes)-1)
|
||||
for i := 0; i < len(temp); i++ {
|
||||
temp[i] = fmt.Sprintf(" %s", ctypes[i])
|
||||
}
|
||||
fmt.Println(strings.Join(temp, "\n"))
|
||||
os.Exit(1)
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
func main() {
|
||||
p := pvalues{
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03,
|
||||
}
|
||||
for _, ctype := range ctypes {
|
||||
s, err := adjusted(p, ctype)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
fmt.Println(s)
|
||||
}
|
||||
}
|
||||
350
Task/P-value-correction/Java/p-value-correction.java
Normal file
350
Task/P-value-correction/Java/p-value-correction.java
Normal file
|
|
@ -0,0 +1,350 @@
|
|||
import java.util.Arrays;
|
||||
import java.util.Comparator;
|
||||
|
||||
public class PValueCorrection {
|
||||
private static int[] seqLen(int start, int end) {
|
||||
int[] result;
|
||||
if (start == end) {
|
||||
result = new int[end + 1];
|
||||
for (int i = 0; i < result.length; ++i) {
|
||||
result[i] = i + 1;
|
||||
}
|
||||
} else if (start < end) {
|
||||
result = new int[end - start + 1];
|
||||
for (int i = 0; i < result.length; ++i) {
|
||||
result[i] = start + i;
|
||||
}
|
||||
} else {
|
||||
result = new int[start - end + 1];
|
||||
for (int i = 0; i < result.length; ++i) {
|
||||
result[i] = start - i;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static int[] order(double[] array, boolean decreasing) {
|
||||
int size = array.length;
|
||||
int[] idx = new int[size];
|
||||
double[] baseArr = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
baseArr[i] = array[i];
|
||||
idx[i] = i;
|
||||
}
|
||||
|
||||
Comparator<Integer> cmp;
|
||||
if (!decreasing) {
|
||||
cmp = Comparator.comparingDouble(a -> baseArr[a]);
|
||||
} else {
|
||||
cmp = (a, b) -> Double.compare(baseArr[b], baseArr[a]);
|
||||
}
|
||||
|
||||
return Arrays.stream(idx)
|
||||
.boxed()
|
||||
.sorted(cmp)
|
||||
.mapToInt(a -> a)
|
||||
.toArray();
|
||||
}
|
||||
|
||||
private static double[] cummin(double[] array) {
|
||||
if (array.length < 1) throw new IllegalArgumentException("cummin requires at least one element");
|
||||
double[] output = new double[array.length];
|
||||
double cumulativeMin = array[0];
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] < cumulativeMin) cumulativeMin = array[i];
|
||||
output[i] = cumulativeMin;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static double[] cummax(double[] array) {
|
||||
if (array.length < 1) throw new IllegalArgumentException("cummax requires at least one element");
|
||||
double[] output = new double[array.length];
|
||||
double cumulativeMax = array[0];
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] > cumulativeMax) cumulativeMax = array[i];
|
||||
output[i] = cumulativeMax;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private static double[] pminx(double[] array, double x) {
|
||||
if (array.length < 1) throw new IllegalArgumentException("pmin requires at least one element");
|
||||
double[] result = new double[array.length];
|
||||
for (int i = 0; i < array.length; ++i) {
|
||||
if (array[i] < x) {
|
||||
result[i] = array[i];
|
||||
} else {
|
||||
result[i] = x;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static void doubleSay(double[] array) {
|
||||
System.out.printf("[ 1] %e", array[0]);
|
||||
for (int i = 1; i < array.length; ++i) {
|
||||
System.out.printf(" %.10f", array[i]);
|
||||
if ((i + 1) % 5 == 0) System.out.printf("\n[%2d]", i + 1);
|
||||
}
|
||||
System.out.println();
|
||||
}
|
||||
|
||||
private static double[] intToDouble(int[] array) {
|
||||
double[] result = new double[array.length];
|
||||
for (int i = 0; i < array.length; i++) {
|
||||
result[i] = array[i];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private static double doubleArrayMin(double[] array) {
|
||||
if (array.length < 1) throw new IllegalArgumentException("pAdjust requires at least one element");
|
||||
return Arrays.stream(array).min().orElse(Double.NaN);
|
||||
}
|
||||
|
||||
private static double[] pAdjust(double[] pvalues, String str) {
|
||||
int size = pvalues.length;
|
||||
if (size < 1) throw new IllegalArgumentException("pAdjust requires at least one element");
|
||||
int type;
|
||||
switch (str.toLowerCase()) {
|
||||
case "bh":
|
||||
case "fdr":
|
||||
type = 0;
|
||||
break;
|
||||
case "by":
|
||||
type = 1;
|
||||
break;
|
||||
case "bonferroni":
|
||||
type = 2;
|
||||
break;
|
||||
case "hochberg":
|
||||
type = 3;
|
||||
break;
|
||||
case "holm":
|
||||
type = 4;
|
||||
break;
|
||||
case "hommel":
|
||||
type = 5;
|
||||
break;
|
||||
default:
|
||||
throw new IllegalArgumentException(str + " doesn't match any accepted FDR types");
|
||||
}
|
||||
|
||||
if (type == 2) { // Bonferroni method
|
||||
double[] result = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
double b = pvalues[i] * size;
|
||||
if (b >= 1) {
|
||||
result[i] = 1;
|
||||
} else if (0 <= b && b < 1) {
|
||||
result[i] = b;
|
||||
} else {
|
||||
throw new RuntimeException("" + b + " is outside [0, 1)");
|
||||
}
|
||||
}
|
||||
return result;
|
||||
} else if (type == 4) { // Holm method
|
||||
int[] o = order(pvalues, false);
|
||||
double[] o2Double = intToDouble(o);
|
||||
double[] cummaxInput = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cummaxInput[i] = (size - i) * pvalues[o[i]];
|
||||
}
|
||||
int[] ro = order(o2Double, false);
|
||||
double[] cummaxOutput = cummax(cummaxInput);
|
||||
double[] pmin = pminx(cummaxOutput, 1.0);
|
||||
double[] result = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result[i] = pmin[ro[i]];
|
||||
}
|
||||
return result;
|
||||
} else if (type == 5) {
|
||||
int[] indices = seqLen(size, size);
|
||||
int[] o = order(pvalues, false);
|
||||
double[] p = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
p[i] = pvalues[o[i]];
|
||||
}
|
||||
double[] o2Double = intToDouble(o);
|
||||
int[] ro = order(o2Double, false);
|
||||
double[] q = new double[size];
|
||||
double[] pa = new double[size];
|
||||
double[] npi = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
npi[i] = p[i] * size / indices[i];
|
||||
}
|
||||
double min = doubleArrayMin(npi);
|
||||
Arrays.fill(q, min);
|
||||
Arrays.fill(pa, min);
|
||||
for (int j = size; j >= 2; --j) {
|
||||
int[] ij = seqLen(1, size - j + 1);
|
||||
for (int i = 0; i < size - j + 1; ++i) {
|
||||
ij[i]--;
|
||||
}
|
||||
int i2Length = j - 1;
|
||||
int[] i2 = new int[i2Length];
|
||||
for (int i = 0; i < i2Length; ++i) {
|
||||
i2[i] = size - j + 2 + i - 1;
|
||||
}
|
||||
double q1 = j * p[i2[0]] / 2.0;
|
||||
for (int i = 1; i < i2Length; ++i) {
|
||||
double temp_q1 = p[i2[i]] * j / (2.0 + i);
|
||||
if (temp_q1 < q1) q1 = temp_q1;
|
||||
}
|
||||
for (int i = 0; i < size - j + 1; ++i) {
|
||||
q[ij[i]] = Math.min(p[ij[i]] * j, q1);
|
||||
}
|
||||
for (int i = 0; i < i2Length; ++i) {
|
||||
q[i2[i]] = q[size - j];
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (pa[i] < q[i]) {
|
||||
pa[i] = q[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
q[i] = pa[ro[i]];
|
||||
}
|
||||
return q;
|
||||
}
|
||||
|
||||
double[] ni = new double[size];
|
||||
int[] o = order(pvalues, true);
|
||||
double[] oDouble = intToDouble(o);
|
||||
for (int i = 0; i < size; ++i) {
|
||||
if (pvalues[i] < 0 || pvalues[i] > 1) {
|
||||
throw new RuntimeException("array[" + i + "] = " + pvalues[i] + " is outside [0, 1]");
|
||||
}
|
||||
ni[i] = (double) size / (size - i);
|
||||
}
|
||||
int[] ro = order(oDouble, false);
|
||||
double[] cumminInput = new double[size];
|
||||
if (type == 0) { // BH method
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cumminInput[i] = ni[i] * pvalues[o[i]];
|
||||
}
|
||||
} else if (type == 1) { // BY method
|
||||
double q = 0;
|
||||
for (int i = 1; i < size + 1; ++i) {
|
||||
q += 1.0 / i;
|
||||
}
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cumminInput[i] = q * ni[i] * pvalues[o[i]];
|
||||
}
|
||||
} else if (type == 3) { // Hochberg method
|
||||
for (int i = 0; i < size; ++i) {
|
||||
cumminInput[i] = (i + 1) * pvalues[o[i]];
|
||||
}
|
||||
}
|
||||
double[] cumminArray = cummin(cumminInput);
|
||||
double[] pmin = pminx(cumminArray, 1.0);
|
||||
double[] result = new double[size];
|
||||
for (int i = 0; i < size; ++i) {
|
||||
result[i] = pmin[ro[i]];
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static void main(String[] args) {
|
||||
double[] pvalues = new double[]{
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
};
|
||||
|
||||
double[][] correctAnswers = new double[][]{
|
||||
new double[]{ // Benjamini-Hochberg
|
||||
6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02
|
||||
},
|
||||
new double[]{ // Benjamini & Yekutieli
|
||||
1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02
|
||||
},
|
||||
new double[]{ // Bonferroni
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01
|
||||
},
|
||||
new double[]{ // Hochberg
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
},
|
||||
new double[]{ // Holm
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
},
|
||||
new double[]{ // Hommel
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01
|
||||
}
|
||||
};
|
||||
|
||||
String[] types = new String[]{"bh", "by", "bonferroni", "hochberg", "holm", "hommel"};
|
||||
for (int type = 0; type < types.length; ++type) {
|
||||
double[] q = pAdjust(pvalues, types[type]);
|
||||
double error = 0.0;
|
||||
for (int i = 0; i < pvalues.length; ++i) {
|
||||
error += Math.abs(q[i] - correctAnswers[type][i]);
|
||||
}
|
||||
doubleSay(q);
|
||||
System.out.printf("\ntype %d = '%s' has a cumulative error of %g\n", type, types[type], error);
|
||||
}
|
||||
}
|
||||
}
|
||||
25
Task/P-value-correction/Julia/p-value-correction.julia
Normal file
25
Task/P-value-correction/Julia/p-value-correction.julia
Normal file
|
|
@ -0,0 +1,25 @@
|
|||
using MultipleTesting, IterTools, Printf
|
||||
|
||||
p = [4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03]
|
||||
|
||||
function printpvalues(v)
|
||||
for chunk in partition(v, 10)
|
||||
println(join((@sprintf("%4.7f", p) for p in chunk), ", "))
|
||||
end
|
||||
end
|
||||
|
||||
println("Original p-values:")
|
||||
printpvalues(p)
|
||||
for corr in (Bonferroni(), BenjaminiHochberg(), BenjaminiYekutieli(), Holm(), Hochberg(), Hommel())
|
||||
println("\n", corr)
|
||||
printpvalues(adjust(p, corr))
|
||||
end
|
||||
282
Task/P-value-correction/Kotlin/p-value-correction-1.kotlin
Normal file
282
Task/P-value-correction/Kotlin/p-value-correction-1.kotlin
Normal file
|
|
@ -0,0 +1,282 @@
|
|||
// version 1.1.51
|
||||
|
||||
import java.util.Arrays
|
||||
|
||||
typealias IAE = IllegalArgumentException
|
||||
|
||||
fun seqLen(start: Int, end: Int) =
|
||||
when {
|
||||
start == end -> IntArray(end + 1) { it + 1 }
|
||||
start < end -> IntArray(end - start + 1) { start + it }
|
||||
else -> IntArray(start - end + 1) { start - it }
|
||||
}
|
||||
|
||||
var baseArr: DoubleArray? = null
|
||||
|
||||
fun compareIncrease(a: Int, b: Int): Int = baseArr!![b].compareTo(baseArr!![a])
|
||||
|
||||
fun compareDecrease(a: Int, b: Int): Int = baseArr!![a].compareTo(baseArr!![b])
|
||||
|
||||
fun order(array: DoubleArray, decreasing: Boolean): IntArray {
|
||||
val size = array.size
|
||||
var idx = IntArray(size) { it }
|
||||
baseArr = array.copyOf()
|
||||
if (!decreasing) {
|
||||
idx = Arrays.stream(idx)
|
||||
.boxed()
|
||||
.sorted { a, b -> compareDecrease(a, b) }
|
||||
.mapToInt { it }
|
||||
.toArray()
|
||||
}
|
||||
else {
|
||||
idx = Arrays.stream(idx)
|
||||
.boxed()
|
||||
.sorted { a, b -> compareIncrease(a, b) }
|
||||
.mapToInt { it }
|
||||
.toArray()
|
||||
}
|
||||
baseArr = null
|
||||
return idx
|
||||
}
|
||||
|
||||
fun cummin(array: DoubleArray): DoubleArray {
|
||||
val size = array.size
|
||||
if (size < 1) throw IAE("cummin requires at least one element")
|
||||
val output = DoubleArray(size)
|
||||
var cumulativeMin = array[0]
|
||||
for (i in 0 until size) {
|
||||
if (array[i] < cumulativeMin) cumulativeMin = array[i]
|
||||
output[i] = cumulativeMin
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
fun cummax(array: DoubleArray): DoubleArray {
|
||||
val size = array.size
|
||||
if (size < 1) throw IAE("cummax requires at least one element")
|
||||
val output = DoubleArray(size)
|
||||
var cumulativeMax = array[0]
|
||||
for (i in 0 until size) {
|
||||
if (array[i] > cumulativeMax) cumulativeMax = array[i]
|
||||
output[i] = cumulativeMax
|
||||
}
|
||||
return output
|
||||
}
|
||||
|
||||
fun pminx(array: DoubleArray, x: Double): DoubleArray {
|
||||
val size = array.size
|
||||
if (size < 1) throw IAE("pmin requires at least one element")
|
||||
return DoubleArray(size) { if (array[it] < x) array[it] else x }
|
||||
}
|
||||
|
||||
fun doubleSay(array: DoubleArray) {
|
||||
print("[ 1] %e".format(array[0]))
|
||||
for (i in 1 until array.size) {
|
||||
print(" %.10f".format(array[i]))
|
||||
if ((i + 1) % 5 == 0) print("\n[%2d]".format(i + 1))
|
||||
}
|
||||
println()
|
||||
}
|
||||
|
||||
fun intToDouble(array: IntArray) = DoubleArray(array.size) { array[it].toDouble() }
|
||||
|
||||
fun doubleArrayMin(array: DoubleArray) =
|
||||
if (array.size < 1) throw IAE("pAdjust requires at least one element")
|
||||
else array.min()!!
|
||||
|
||||
fun pAdjust(pvalues: DoubleArray, str: String): DoubleArray {
|
||||
val size = pvalues.size
|
||||
if (size < 1) throw IAE("pAdjust requires at least one element")
|
||||
val type = when(str.toLowerCase()) {
|
||||
"bh", "fdr" -> 0
|
||||
"by" -> 1
|
||||
"bonferroni" -> 2
|
||||
"hochberg" -> 3
|
||||
"holm" -> 4
|
||||
"hommel" -> 5
|
||||
else -> throw IAE("'$str' doesn't match any accepted FDR types")
|
||||
}
|
||||
if (type == 2) { // Bonferroni method
|
||||
return DoubleArray(size) {
|
||||
val b = pvalues[it] * size
|
||||
when {
|
||||
b >= 1 -> 1.0
|
||||
0 <= b && b < 1 -> b
|
||||
else -> throw RuntimeException("$b is outside [0, 1)")
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (type == 4) { // Holm method
|
||||
val o = order(pvalues, false)
|
||||
val o2Double = intToDouble(o)
|
||||
val cummaxInput = DoubleArray(size) { (size - it) * pvalues[o[it]] }
|
||||
val ro = order(o2Double, false)
|
||||
val cummaxOutput = cummax(cummaxInput)
|
||||
val pmin = pminx(cummaxOutput, 1.0)
|
||||
return DoubleArray(size) { pmin[ro[it]] }
|
||||
}
|
||||
else if (type == 5) { // Hommel method
|
||||
val indices = seqLen(size, size)
|
||||
val o = order(pvalues, false)
|
||||
val p = DoubleArray(size) { pvalues[o[it]] }
|
||||
val o2Double = intToDouble(o)
|
||||
val ro = order(o2Double, false)
|
||||
val q = DoubleArray(size)
|
||||
val pa = DoubleArray(size)
|
||||
val npi = DoubleArray(size) { p[it] * size / indices[it] }
|
||||
val min = doubleArrayMin(npi)
|
||||
q.fill(min)
|
||||
pa.fill(min)
|
||||
for (j in size - 1 downTo 2) {
|
||||
val ij = seqLen(1, size - j + 1)
|
||||
for (i in 0 until size - j + 1) ij[i]--
|
||||
val i2Length = j - 1
|
||||
val i2 = IntArray(i2Length) { size - j + 2 + it - 1 }
|
||||
val pi2Length = i2Length
|
||||
var q1 = j * p[i2[0]] / 2.0
|
||||
for (i in 1 until pi2Length) {
|
||||
val temp_q1 = p[i2[i]] * j / (2.0 + i)
|
||||
if(temp_q1 < q1) q1 = temp_q1
|
||||
}
|
||||
for (i in 0 until size - j + 1) {
|
||||
q[ij[i]] = minOf(p[ij[i]] * j, q1)
|
||||
}
|
||||
for (i in 0 until i2Length) q[i2[i]] = q[size - j]
|
||||
for (i in 0 until size) if (pa[i] < q[i]) pa[i] = q[i]
|
||||
}
|
||||
for (index in 0 until size) q[index] = pa[ro[index]]
|
||||
return q
|
||||
}
|
||||
val ni = DoubleArray(size)
|
||||
val o = order(pvalues, true)
|
||||
val oDouble = intToDouble(o)
|
||||
for (index in 0 until size) {
|
||||
if (pvalues[index] !in 0.0 .. 1.0) {
|
||||
throw RuntimeException("array[$index] = ${pvalues[index]} is outside [0, 1]")
|
||||
}
|
||||
ni[index] = size.toDouble() / (size - index)
|
||||
}
|
||||
val ro = order(oDouble, false)
|
||||
val cumminInput = DoubleArray(size)
|
||||
if (type == 0) { // BH method
|
||||
for (index in 0 until size) {
|
||||
cumminInput[index] = ni[index] * pvalues[o[index]]
|
||||
}
|
||||
}
|
||||
else if (type == 1) { // BY method
|
||||
var q = 0.0
|
||||
for (index in 1 until size + 1) q += 1.0 / index
|
||||
for (index in 0 until size) {
|
||||
cumminInput[index] = q * ni[index] * pvalues[o[index]]
|
||||
}
|
||||
}
|
||||
else if (type == 3) { // Hochberg method
|
||||
for (index in 0 until size) {
|
||||
cumminInput[index] = (index + 1) * pvalues[o[index]]
|
||||
}
|
||||
}
|
||||
val cumminArray = cummin(cumminInput)
|
||||
val pmin = pminx(cumminArray, 1.0)
|
||||
return DoubleArray(size) { pmin[ro[it]] }
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val pvalues = doubleArrayOf(
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
)
|
||||
|
||||
val correctAnswers = listOf(
|
||||
doubleArrayOf( // Benjamini-Hochberg
|
||||
6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02
|
||||
),
|
||||
doubleArrayOf( // Benjamini & Yekutieli
|
||||
1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02
|
||||
),
|
||||
doubleArrayOf( // Bonferroni
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01
|
||||
),
|
||||
doubleArrayOf( // Hochberg
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
),
|
||||
doubleArrayOf( // Holm
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01
|
||||
),
|
||||
doubleArrayOf( // Hommel
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01
|
||||
)
|
||||
)
|
||||
val types = listOf("bh", "by", "bonferroni", "hochberg", "holm", "hommel")
|
||||
val f = "\ntype %d = '%s' has cumulative error of %g"
|
||||
for (type in 0 until types.size) {
|
||||
val q = pAdjust(pvalues, types[type])
|
||||
var error = 0.0
|
||||
for (i in 0 until pvalues.size) {
|
||||
error += Math.abs(q[i] - correctAnswers[type][i])
|
||||
}
|
||||
doubleSay(q)
|
||||
println(f.format(type, types[type], error))
|
||||
}
|
||||
}
|
||||
146
Task/P-value-correction/Kotlin/p-value-correction-2.kotlin
Normal file
146
Task/P-value-correction/Kotlin/p-value-correction-2.kotlin
Normal file
|
|
@ -0,0 +1,146 @@
|
|||
// version 1.2.21
|
||||
|
||||
typealias DList = List<Double>
|
||||
|
||||
enum class Direction { UP, DOWN }
|
||||
|
||||
// test also for 'Unknown' correction type
|
||||
val types = listOf(
|
||||
"Benjamini-Hochberg", "Benjamini-Yekutieli", "Bonferroni", "Hochberg",
|
||||
"Holm", "Hommel", "Šidák", "Unknown"
|
||||
)
|
||||
|
||||
fun adjusted(p: DList, type: String) = "\n$type\n${pFormat(adjust(check(p), type))}"
|
||||
|
||||
fun pFormat(p: DList, cols: Int = 5): String {
|
||||
var i = -cols
|
||||
val fmt = "%1.10f"
|
||||
return p.chunked(cols).map { chunk ->
|
||||
i += cols
|
||||
"[%2d] %s".format(i, chunk.map { fmt.format(it) }.joinToString(" "))
|
||||
}.joinToString("\n")
|
||||
}
|
||||
|
||||
fun check(p: DList): DList {
|
||||
require(p.size > 0 && p.min()!! >= 0.0 && p.max()!! <= 1.0) {
|
||||
"p-values must be in range 0.0 to 1.0"
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
fun ratchet(p: DList, dir: Direction): DList {
|
||||
val pp = p.toMutableList()
|
||||
var m = pp[0]
|
||||
if (dir == Direction.UP) {
|
||||
for (i in 1 until pp.size) {
|
||||
if (pp[i] > m) pp[i] = m
|
||||
m = pp[i]
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (i in 1 until pp.size) {
|
||||
if (pp[i] < m) pp[i] = m
|
||||
m = pp[i]
|
||||
}
|
||||
}
|
||||
return pp.map { if (it < 1.0) it else 1.0 }
|
||||
}
|
||||
|
||||
fun schwartzian(p: DList, mult: DList, dir: Direction): DList {
|
||||
val size = p.size
|
||||
val order = if (dir == Direction.UP)
|
||||
p.withIndex().sortedByDescending { it.value }.map { it.index }
|
||||
else
|
||||
p.withIndex().sortedBy { it.value }.map { it.index }
|
||||
var pa = List(size) { mult[it] * p[order[it]] }
|
||||
pa = ratchet(pa, dir)
|
||||
val order2 = order.withIndex().sortedBy{ it.value }.map { it.index }
|
||||
return List(size) { pa[order2[it]] }
|
||||
}
|
||||
|
||||
fun adjust(p: DList, type: String): DList {
|
||||
val size = p.size
|
||||
require(size > 0)
|
||||
when (type) {
|
||||
"Benjamini-Hochberg" -> {
|
||||
val mult = List(size) { size.toDouble() / (size - it) }
|
||||
return schwartzian(p, mult, Direction.UP)
|
||||
}
|
||||
|
||||
"Benjamini-Yekutieli" -> {
|
||||
val q = (1..size).sumByDouble { 1.0 / it }
|
||||
val mult = List(size) { q * size / (size - it) }
|
||||
return schwartzian(p, mult, Direction.UP)
|
||||
}
|
||||
|
||||
"Bonferroni" -> {
|
||||
return p.map { minOf(it * size, 1.0) }
|
||||
}
|
||||
|
||||
"Hochberg" -> {
|
||||
val mult = List(size) { (it + 1).toDouble() }
|
||||
return schwartzian(p, mult, Direction.UP)
|
||||
}
|
||||
|
||||
"Holm" -> {
|
||||
val mult = List(size) { (size - it).toDouble() }
|
||||
return schwartzian(p, mult, Direction.DOWN)
|
||||
}
|
||||
|
||||
"Hommel" -> {
|
||||
val order = p.withIndex().sortedBy { it.value }.map { it.index }
|
||||
val s = List(size) { p[order[it]] }
|
||||
val min = List(size){ s[it] * size / ( it + 1) }.min()!!
|
||||
val q = MutableList(size) { min }
|
||||
val pa = MutableList(size) { min }
|
||||
for (j in size - 1 downTo 2) {
|
||||
val lower = IntArray(size - j + 1) { it } // lower indices
|
||||
val upper = IntArray(j - 1) { size - j + 1 + it } // upper indices
|
||||
var qmin = j * s[upper[0]] / 2.0
|
||||
for (i in 1 until upper.size) {
|
||||
val temp = s[upper[i]] * j / (2.0 + i)
|
||||
if (temp < qmin) qmin = temp
|
||||
}
|
||||
for (i in 0 until lower.size) {
|
||||
q[lower[i]] = minOf(s[lower[i]] * j, qmin)
|
||||
}
|
||||
for (i in 0 until upper.size) q[upper[i]] = q[size - j]
|
||||
for (i in 0 until size) if (pa[i] < q[i]) pa[i] = q[i]
|
||||
}
|
||||
val order2 = order.withIndex().sortedBy{ it.value }.map { it.index }
|
||||
return List(size) { pa[order2[it]] }
|
||||
}
|
||||
|
||||
"Šidák" -> {
|
||||
val m = size.toDouble()
|
||||
return p.map { 1.0 - Math.pow(1.0 - it, m) }
|
||||
}
|
||||
|
||||
else -> {
|
||||
println(
|
||||
"\nSorry, do not know how to do '$type' correction.\n" +
|
||||
"Perhaps you want one of these?:\n" +
|
||||
types.dropLast(1).map { " $it" }.joinToString("\n")
|
||||
)
|
||||
System.exit(1)
|
||||
}
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
val pValues = listOf(
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
)
|
||||
|
||||
types.forEach { println(adjusted(pValues, it)) }
|
||||
}
|
||||
155
Task/P-value-correction/Nim/p-value-correction.nim
Normal file
155
Task/P-value-correction/Nim/p-value-correction.nim
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import algorithm, math, sequtils, strformat, strutils, sugar
|
||||
|
||||
type
|
||||
|
||||
CorrectionType {.pure.} = enum
|
||||
BenjaminiHochberg = "Benjamini-Hochberg"
|
||||
BenjaminiYekutieli = "Benjamini-Yekutieli"
|
||||
Bonferroni = "Bonferroni"
|
||||
Hochberg = "Hochberg"
|
||||
Holm = "Holm"
|
||||
Hommel = "Hommel"
|
||||
Šidák = "Šidák"
|
||||
|
||||
Direction {.pure.} = enum Up, Down
|
||||
|
||||
PValues = seq[float]
|
||||
|
||||
|
||||
template newPValues(length: Natural): PValues =
|
||||
## Create a PValues object of given length.
|
||||
newSeq[float](length)
|
||||
|
||||
|
||||
func ratchet(p: var PValues; dir: Direction) =
|
||||
var m = p[0]
|
||||
case dir
|
||||
of Up:
|
||||
for i in 1..p.high:
|
||||
if p[i] > m: p[i] = m
|
||||
m = p[i]
|
||||
of Down:
|
||||
for i in 1..p.high:
|
||||
if p[i] < m: p[i] = m
|
||||
m = p[i]
|
||||
for i in 0..p.high:
|
||||
if p[i] > 1: p[i] = 1
|
||||
|
||||
|
||||
func schwartzian(p, mult: PValues; dir: Direction): PValues =
|
||||
|
||||
let length = p.len
|
||||
let sortOrder = if dir == Up: Descending else: Ascending
|
||||
let order1 = toSeq(p.pairs).sorted((x, y) => cmp(x.val, y.val), sortOrder).mapIt(it.key)
|
||||
|
||||
var pa = newPValues(length)
|
||||
for i in 0..pa.high:
|
||||
pa[i] = mult[i] * p[order1[i]]
|
||||
|
||||
ratchet(pa, dir)
|
||||
|
||||
let order2 = toSeq(order1.pairs).sortedByIt(it.val).mapIt(it.key)
|
||||
for idx in order2:
|
||||
result.add pa[idx]
|
||||
|
||||
|
||||
proc adjust(p: PValues; ctype: CorrectionType): PValues =
|
||||
let length = p.len
|
||||
assert length > 0
|
||||
let flength = length.toFloat
|
||||
|
||||
case ctype
|
||||
|
||||
of BenjaminiHochberg:
|
||||
var mult = newPValues(length)
|
||||
for i in 0..mult.high:
|
||||
mult[i] = flength / (flength - i.toFloat)
|
||||
return schwartzian(p, mult, Up)
|
||||
|
||||
of BenjaminiYekutieli:
|
||||
var q = 0.0
|
||||
for i in 1..length: q += 1 / i
|
||||
var mult = newPValues(length)
|
||||
for i in 0..mult.high:
|
||||
mult[i] = (q * flength) / (flength - i.toFloat)
|
||||
return schwartzian(p, mult, Up)
|
||||
|
||||
of Bonferroni:
|
||||
result = newPValues(length)
|
||||
for i in 0..result.high:
|
||||
result[i] = min(p[i] * flength, 1)
|
||||
return
|
||||
|
||||
of Hochberg:
|
||||
var mult = newPValues(length)
|
||||
for i in 0..mult.high:
|
||||
mult[i] = i.toFloat + 1
|
||||
return schwartzian(p, mult, Up)
|
||||
|
||||
of Holm:
|
||||
var mult = newPValues(length)
|
||||
for i in 0..mult.high:
|
||||
mult[i] = flength - i.toFloat
|
||||
return schwartzian(p, mult, Down)
|
||||
|
||||
of Hommel:
|
||||
let order1 = toSeq(p.pairs).sortedByIt(it.val).mapIt(it.key)
|
||||
let s = order1.mapIt(p[it])
|
||||
var m = Inf
|
||||
for i in 0..s.high:
|
||||
m = min(m, s[i] * flength / (i + 1).toFloat)
|
||||
var q, pa = repeat(m, length)
|
||||
|
||||
for j in countdown(length - 1, 2):
|
||||
let lower = toSeq(0..length - j)
|
||||
let upper = toSeq((length - j + 1)..<length)
|
||||
var qmin = j.toFloat * s[upper[0]] / 2
|
||||
for i in 1..upper.high:
|
||||
let val = s[upper[i]] * j.toFloat / (i + 2).toFloat
|
||||
if val < qmin: qmin = val
|
||||
for idx in lower: q[idx] = min(s[idx] * j.toFloat, qmin)
|
||||
for idx in upper: q[idx] = q[^j]
|
||||
for i, val in q:
|
||||
if pa[i] < val: pa[i] = val
|
||||
|
||||
let order2 = toSeq(order1.pairs).sortedByIt(it.val).mapIt(it.key)
|
||||
return order2.mapIt(pa[it])
|
||||
|
||||
of Šidák:
|
||||
result = newPValues(length)
|
||||
for i in 0..result.high:
|
||||
result[i] = 1 - (1 - p[i])^length
|
||||
return
|
||||
|
||||
|
||||
func pformat(p: PValues; cols = 5): string =
|
||||
var lines: seq[string]
|
||||
for i in countup(0, p.high, cols):
|
||||
let fchunk = p[i..<(i + cols)]
|
||||
var schunk = newSeq[string](fchunk.len)
|
||||
for j in 0..<cols:
|
||||
schunk[j] = fchunk[j].formatFloat(ffDecimal, 10)
|
||||
lines.add &"[{i:2}] {schunk.join(\" \")}"
|
||||
result = lines.join("\n")
|
||||
|
||||
|
||||
func adjusted(p: PValues; ctype: CorrectionType): string =
|
||||
doAssert p.len > 0 and min(p) >= 0 and max(p) <= 1, "p-values must be in range 0.0 to 1.0."
|
||||
result = &"\n{ctype}\n{pformat(p.adjust(ctype))}"
|
||||
|
||||
when isMainModule:
|
||||
|
||||
const PVals = @[
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03]
|
||||
|
||||
for ctype in CorrectionType:
|
||||
echo adjusted(PVals, ctype)
|
||||
310
Task/P-value-correction/Perl/p-value-correction.pl
Normal file
310
Task/P-value-correction/Perl/p-value-correction.pl
Normal file
|
|
@ -0,0 +1,310 @@
|
|||
#!/usr/bin/env perl
|
||||
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use autodie ':all';
|
||||
use List::Util 'min';
|
||||
use feature 'say';
|
||||
|
||||
sub pmin {
|
||||
my $array = shift;
|
||||
my $x = 1;
|
||||
my @pmin_array;
|
||||
my $n = scalar @$array;
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
$pmin_array[$index] = min(@$array[$index], $x);
|
||||
}
|
||||
@pmin_array
|
||||
}
|
||||
|
||||
sub cummin {
|
||||
my $array_ref = shift;
|
||||
my @cummin;
|
||||
my $cumulative_min = @$array_ref[0];
|
||||
foreach my $p (@$array_ref) {
|
||||
if ($p < $cumulative_min) {
|
||||
$cumulative_min = $p;
|
||||
}
|
||||
push @cummin, $cumulative_min;
|
||||
}
|
||||
@cummin
|
||||
}
|
||||
|
||||
sub cummax {
|
||||
my $array_ref = shift;
|
||||
my @cummax;
|
||||
my $cumulative_max = @$array_ref[0];
|
||||
foreach my $p (@$array_ref) {
|
||||
if ($p > $cumulative_max) {
|
||||
$cumulative_max = $p;
|
||||
}
|
||||
push @cummax, $cumulative_max;
|
||||
}
|
||||
@cummax
|
||||
}
|
||||
|
||||
sub order {#made to match R's "order"
|
||||
my $array_ref = shift;
|
||||
my $decreasing = 'false';
|
||||
if (defined $_[0]) {
|
||||
my $option = shift;
|
||||
if ($option =~ m/true/i) {
|
||||
$decreasing = 'true';
|
||||
} elsif ($option =~ m/false/i) {
|
||||
#do nothing, it's already set to false
|
||||
} else {
|
||||
print "2nd option should only be case-insensitive 'true' or 'false'";
|
||||
die;
|
||||
}
|
||||
}
|
||||
my @array;
|
||||
my $max_index = scalar @$array_ref-1;
|
||||
if ($decreasing eq 'false') {
|
||||
@array = sort { @$array_ref[$a] <=> @$array_ref[$b] } 0..$max_index;
|
||||
} elsif ($decreasing eq 'true') {
|
||||
@array = sort { @$array_ref[$b] <=> @$array_ref[$a] } 0..$max_index;
|
||||
}
|
||||
@array
|
||||
}
|
||||
|
||||
|
||||
sub p_adjust {
|
||||
my $pvalues_ref = shift;
|
||||
my $method;
|
||||
if (defined $_[0]) {
|
||||
$method = shift
|
||||
} else {
|
||||
$method = 'Holm'
|
||||
}
|
||||
my %methods = (
|
||||
'bh' => 1,
|
||||
'fdr' => 1,
|
||||
'by' => 1,
|
||||
'holm' => 1,
|
||||
'hommel' => 1,
|
||||
'bonferroni' => 1,
|
||||
'hochberg' => 1
|
||||
);
|
||||
my $method_found = 'no';
|
||||
foreach my $key (keys %methods) {
|
||||
if ((uc $method) eq (uc $key)) {
|
||||
$method = $key;
|
||||
$method_found = 'yes';
|
||||
last
|
||||
}
|
||||
}
|
||||
if ($method_found eq 'no') {
|
||||
if ($method =~ m/benjamini-?\s*hochberg/i) {
|
||||
$method = 'bh';
|
||||
$method_found = 'yes';
|
||||
} elsif ($method =~ m/benjamini-?\s*yekutieli/i) {
|
||||
$method = 'by';
|
||||
$method_found = 'yes';
|
||||
}
|
||||
}
|
||||
if ($method_found eq 'no') {
|
||||
print "No method could be determined from $method.\n";
|
||||
die
|
||||
}
|
||||
my $lp = scalar @$pvalues_ref;
|
||||
my $n = $lp;
|
||||
my @qvalues;
|
||||
if ($method eq 'hochberg') {
|
||||
my @o = order($pvalues_ref, 'TRUE');
|
||||
my @cummin_input;
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
$cummin_input[$index] = ($index+1)* @$pvalues_ref[$o[$index]];#PVALUES[$o[$index]] is p[o]
|
||||
}
|
||||
my @cummin = cummin(\@cummin_input);
|
||||
my @pmin = pmin(\@cummin);
|
||||
my @ro = order(\@o);
|
||||
@qvalues = @pmin[@ro];
|
||||
} elsif ($method eq 'bh') {
|
||||
my @o = order($pvalues_ref, 'TRUE');
|
||||
my @cummin_input;
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
$cummin_input[$index] = ($n/($n-$index))* @$pvalues_ref[$o[$index]];#PVALUES[$o[$index]] is p[o]
|
||||
}
|
||||
my @ro = order(\@o);
|
||||
my @cummin = cummin(\@cummin_input);
|
||||
my @pmin = pmin(\@cummin);
|
||||
@qvalues = @pmin[@ro];
|
||||
} elsif ($method eq 'by') {
|
||||
my $q = 0.0;
|
||||
my @o = order($pvalues_ref, 'TRUE');
|
||||
my @ro = order(\@o);
|
||||
for (my $index = 1; $index < ($n+1); $index++) {
|
||||
$q += 1.0 / $index;
|
||||
}
|
||||
my @cummin_input;
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
$cummin_input[$index] = $q * ($n/($n-$index)) * @$pvalues_ref[$o[$index]];#PVALUES[$o[$index]] is p[o]
|
||||
}
|
||||
# say join (',', @cummin_input);
|
||||
# say '@cummin_input # of elements = ' . scalar @cummin_input;
|
||||
my @cummin = cummin(\@cummin_input);
|
||||
undef @cummin_input;
|
||||
my @pmin = pmin(\@cummin);
|
||||
@qvalues = @pmin[@ro];
|
||||
} elsif ($method eq 'bonferroni') {
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
my $q = @$pvalues_ref[$index]*$n;
|
||||
if ((0 <= $q) && ($q < 1)) {
|
||||
$qvalues[$index] = $q;
|
||||
} elsif ($q >= 1) {
|
||||
$qvalues[$index] = 1.0;
|
||||
} else {
|
||||
say 'Failed to get Bonferroni adjusted p.';
|
||||
die;
|
||||
}
|
||||
}
|
||||
} elsif ($method eq 'holm') {
|
||||
my @o = order($pvalues_ref);
|
||||
my @cummax_input;
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
$cummax_input[$index] = ($n - $index) * @$pvalues_ref[$o[$index]];
|
||||
}
|
||||
my @ro = order(\@o);
|
||||
undef @o;
|
||||
my @cummax = cummax(\@cummax_input);
|
||||
undef @cummax_input;
|
||||
my @pmin = pmin(\@cummax);
|
||||
undef @cummax;
|
||||
@qvalues = @pmin[@ro];
|
||||
} elsif ($method eq 'hommel') {
|
||||
my @o = order($pvalues_ref);
|
||||
my @p = @$pvalues_ref[@o];
|
||||
my @ro = order(\@o);
|
||||
undef @o;
|
||||
my (@q, @pa);
|
||||
my $min = $n*$p[0];
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
my $temp = $n*$p[$index] / ($index + 1);
|
||||
$min = min($min, $temp);
|
||||
}
|
||||
for (my $index = 0; $index < $n; $index++) {
|
||||
$pa[$index] = $min;#q <- pa <- rep.int(min(n * p/i), n)
|
||||
$q[$index] = $min;#q <- pa <- rep.int(min(n * p/i), n)
|
||||
}
|
||||
for (my $j = ($n-1); $j >= 2; $j--) {
|
||||
my @ij = 0..($n - $j);#ij <- seq_len(n - j + 1)
|
||||
my $I2_LENGTH = $j - 1;
|
||||
my @i2;
|
||||
for (my $i = 0; $i < $I2_LENGTH; $i++) {
|
||||
$i2[$i] = $n-$j+2+$i-1;
|
||||
#R's indices are 1-based, C's are 0-based, I added the -1
|
||||
}
|
||||
|
||||
my $q1 = $j * $p[$i2[0]] / 2.0;
|
||||
for (my $i = 1; $i < $I2_LENGTH; $i++) {#loop through 2:j
|
||||
my $TEMP_Q1 = $j * $p[$i2[$i]] / (2 + $i);
|
||||
$q1 = min($TEMP_Q1, $q1);
|
||||
}
|
||||
for (my $i = 0; $i < ($n - $j + 1); $i++) {#q[ij] <- pmin(j * p[ij], q1)
|
||||
$q[$ij[$i]] = min( $j*$p[$ij[$i]], $q1);
|
||||
}
|
||||
|
||||
for (my $i = 0; $i < $I2_LENGTH; $i++) {#q[i2] <- q[n - j + 1]
|
||||
$q[$i2[$i]] = $q[$n - $j];
|
||||
}
|
||||
|
||||
for (my $i = 0; $i < $n; $i++) {#pa <- pmax(pa, q)
|
||||
if ($pa[$i] < $q[$i]) {
|
||||
$pa[$i] = $q[$i];
|
||||
}
|
||||
}
|
||||
# printf("j = %zu, pa = \n", j);
|
||||
# double_say(pa, N);
|
||||
}#end j loop
|
||||
@qvalues = @pa[@ro];
|
||||
} else {
|
||||
print "$method doesn't fit my types.\n";
|
||||
die
|
||||
}
|
||||
@qvalues
|
||||
}
|
||||
my @pvalues = (4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03);
|
||||
|
||||
my %correct_answers = (
|
||||
'Benjamini-Hochberg' => [6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02],
|
||||
'Benjamini-Yekutieli' => [1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02],
|
||||
'Bonferroni' => [1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01],
|
||||
|
||||
'Hochberg' => [9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01],
|
||||
'Holm' => [1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01],
|
||||
|
||||
'Hommel' => [9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01]);
|
||||
|
||||
|
||||
foreach my $method ('Hochberg','Benjamini-Hochberg','Benjamini-Yekutieli', 'Bonferroni', 'Holm', 'Hommel') {
|
||||
print "$method\n";
|
||||
my @qvalues = p_adjust(\@pvalues, $method);
|
||||
my $error = 0.0;
|
||||
foreach my $q (0..$#qvalues) {
|
||||
$error += abs($qvalues[$q] - $correct_answers{$method}[$q]);
|
||||
}
|
||||
printf("type $method has cumulative error of %g.\n", $error);
|
||||
}
|
||||
195
Task/P-value-correction/Phix/p-value-correction.phix
Normal file
195
Task/P-value-correction/Phix/p-value-correction.phix
Normal file
|
|
@ -0,0 +1,195 @@
|
|||
(phixonline)-->
|
||||
<span style="color: #008080;">with</span> <span style="color: #008080;">javascript_semantics</span>
|
||||
<span style="color: #008080;">enum</span> <span style="color: #000000;">UP</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">DOWN</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">ratchet</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">direction</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #008080;">iff</span><span style="color: #0000FF;">(</span><span style="color: #000000;">direction</span><span style="color: #0000FF;">=</span><span style="color: #000000;">UP</span><span style="color: #0000FF;">?</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]></span><span style="color: #000000;">m</span><span style="color: #0000FF;">:</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]<</span><span style="color: #000000;">m</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">then</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">m</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">schwartzian</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mult</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">integer</span> <span style="color: #000000;">direction</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">order</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">custom_sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)))</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">direction</span><span style="color: #0000FF;">=</span><span style="color: #000000;">UP</span> <span style="color: #008080;">then</span> <span style="color: #000000;">order</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">reverse</span><span style="color: #0000FF;">(</span><span style="color: #000000;">order</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">pa</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">ratchet</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">mult</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">order</span><span style="color: #0000FF;">)),</span> <span style="color: #000000;">direction</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">invert</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">function</span> <span style="color: #000000;">adjust</span><span style="color: #0000FF;">(</span><span style="color: #004080;">sequence</span> <span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #004080;">string</span> <span style="color: #000000;">method</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">integer</span> <span style="color: #000000;">size</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">mult</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">switch</span> <span style="color: #000000;">method</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Benjamini-Hochberg"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">mult</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mult</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">schwartzian</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mult</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">UP</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Benjamini-Yekutieli"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">q</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mult</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #000000;">mult</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #000000;">q</span><span style="color: #0000FF;">*</span><span style="color: #000000;">size</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mult</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">schwartzian</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mult</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">UP</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Bonferroni"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">sq_min</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span><span style="color: #000000;">size</span><span style="color: #0000FF;">),</span><span style="color: #000000;">1</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Hochberg"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">schwartzian</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mult</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">UP</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Holm"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">mult</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #000000;">mult</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">schwartzian</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">mult</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">DOWN</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Hommel"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">ivdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #000000;">0</span><span style="color: #0000FF;">,</span><span style="color: #000000;">size</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">size</span> <span style="color: #008080;">do</span> <span style="color: #000000;">ivdx</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">i</span><span style="color: #0000FF;">}</span> <span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">ivdx</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sort</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ivdx</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">s</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ivdx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">m</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_div</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_mul</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">,</span><span style="color: #000000;">size</span><span style="color: #0000FF;">),</span><span style="color: #000000;">mult</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">qh</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">),</span><span style="color: #000000;">size</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">pa</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">repeat</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">m</span><span style="color: #0000FF;">),</span><span style="color: #000000;">size</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">order</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">vslice</span><span style="color: #0000FF;">(</span><span style="color: #000000;">ivdx</span><span style="color: #0000FF;">,</span><span style="color: #000000;">2</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">=</span><span style="color: #000000;">size</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #000000;">2</span> <span style="color: #008080;">by</span> <span style="color: #0000FF;">-</span><span style="color: #000000;">1</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">lwr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">-</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span>
|
||||
<span style="color: #000000;">upr</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_add</span><span style="color: #0000FF;">(</span><span style="color: #000000;">size</span><span style="color: #0000FF;">-</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">tagset</span><span style="color: #0000FF;">(</span><span style="color: #000000;">j</span><span style="color: #0000FF;">-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">))</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">qmin</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">j</span><span style="color: #0000FF;">*</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">upr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]]/</span><span style="color: #000000;">2</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">2</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">upr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">qmin</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">upr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]*</span><span style="color: #000000;">j</span><span style="color: #0000FF;">/(</span><span style="color: #000000;">i</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">),</span><span style="color: #000000;">qmin</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">lwr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">qh</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lwr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">s</span><span style="color: #0000FF;">[</span><span style="color: #000000;">lwr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]*</span><span style="color: #000000;">j</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">qmin</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">upr</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">qh</span><span style="color: #0000FF;">[</span><span style="color: #000000;">upr</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">qh</span><span style="color: #0000FF;">[</span><span style="color: #000000;">size</span><span style="color: #0000FF;">-</span><span style="color: #000000;">j</span><span style="color: #0000FF;">+</span><span style="color: #000000;">1</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #000000;">pa</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sq_max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">qh</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #7060A8;">extract</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pa</span><span style="color: #0000FF;">,</span><span style="color: #000000;">order</span><span style="color: #0000FF;">,</span><span style="color: #000000;">invert</span><span style="color: #0000FF;">:=</span><span style="color: #004600;">true</span><span style="color: #0000FF;">)</span>
|
||||
|
||||
<span style="color: #008080;">case</span> <span style="color: #008000;">"Sidak"</span><span style="color: #0000FF;">:</span>
|
||||
<span style="color: #000000;">p</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">deep_copy</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">p</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">1</span> <span style="color: #0000FF;">-</span> <span style="color: #7060A8;">power</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">-</span><span style="color: #000000;">p</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">],</span><span style="color: #000000;">size</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">p</span>
|
||||
|
||||
<span style="color: #008080;">else</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #0000FF;">{}</span> <span style="color: #000080;font-style:italic;">-- (unknown method)</span>
|
||||
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">switch</span>
|
||||
<span style="color: #008080;">return</span> <span style="color: #000000;">p</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">function</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">types</span><span style="color: #0000FF;">,</span><span style="color: #000000;">correct_answers</span><span style="color: #0000FF;">}</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">columnize</span><span style="color: #0000FF;">({</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Benjamini-Hochberg"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">6.126681e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.521710e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.987205e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.891595e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.217789e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.301450e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.870370e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.301450e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.049731e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.826753e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">6.482629e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.253722e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.280973e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.769926e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.705703e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.241867e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.049731e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.856107e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.887526e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.136717e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">4.991891e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.769926e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.217789e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.301450e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">2.304958e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.832475e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.899547e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.521710e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.476843e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.683638e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.562902e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.516084e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.250189e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.636589e-03</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">2.562902e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.946883e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.166064e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.899547e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.688991e-03</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">4.502862e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.252228e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.881555e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.142613e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.846527e-03</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">2.562902e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.846527e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.101708e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.252032e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.205958e-02</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Benjamini-Yekutieli"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.940844e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.510676e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.114323e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.754486e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.644618e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">7.575031e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.153102e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.581959e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.812089e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.636176e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.153102e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.325863e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.774239e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.754486e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.209832e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">2.025930e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.634031e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.546073e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.413926e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.180552e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.153102e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.180552e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.956812e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.262838e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.925057e-02</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Bonferroni"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.019185e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">2.020365e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.516674e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.625735e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.909271e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.537741e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.125636e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.782670e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.803480e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.882294e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.005725e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.252228e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.713920e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.395577e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.088915e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.846527e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.305125e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.867745e-01</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Hochberg"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.632662e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.575885e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.383967e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.938014e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.600230e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.501973e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.383967e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.052971e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.426136e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.626366e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.656419e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">8.825610e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.252228e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.930759e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.394022e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.692284e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.023581e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.974152e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.172920e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.992520e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.179486e-01</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Holm"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.632662e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.000000e+00</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.575885e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.395341e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.938014e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.600230e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.501973e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.395341e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.052971e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.426136e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.626366e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.656419e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">8.825610e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.252228e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.930759e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.394022e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.692284e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.023581e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.974152e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.172920e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.992520e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.179486e-01</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Hommel"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.987624e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.595180e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.351895e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.766522e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.414256e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.304340e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.530937e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.887709e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.385602e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.322457e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.722920e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.426136e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.218158e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.581127e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">8.825610e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.252228e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.743649e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.016908e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.516461e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">9.582456e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.877222e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.172920e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.122276e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.950067e-01</span><span style="color: #0000FF;">}},</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #008000;">"Sidak"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9946598274</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9914285749</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9999515274</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9999999688</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9999999995</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9999998801</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9999999855</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9231179729</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">0.9999999956</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9999317605</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">0.9983109511</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.5068253940</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.0000000000</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.9703301333</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">0.1832692440</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0150545753</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.4320729669</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.6993672225</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0286818157</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">0.0152621104</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3391808707</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0656206307</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.4959194266</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0186503726</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">0.0009001752</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0000125222</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.8142104886</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.3772612062</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0430222116</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">0.0108312558</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0473319661</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.0032997780</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.7705015898</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">0.2499384839</span><span style="color: #0000FF;">}}})</span>
|
||||
<span style="color: #000080;font-style:italic;">-- {"Unknown",{1<nowiki>}}</nowiki>})</span>
|
||||
|
||||
<span style="color: #008080;">constant</span> <span style="color: #000000;">pValues</span> <span style="color: #0000FF;">=</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">4.533744e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.296024e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.936026e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.079658e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.801962e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">8.752257e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.922222e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.115421e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.355806e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.324867e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">4.926798e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.802978e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.485442e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.883130e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.729308e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">8.502518e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">4.268138e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.442008e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.030266e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.001555e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">3.194810e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.892933e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.991834e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.745691e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.037516e-01</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.198578e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.966083e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.403837e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">7.328671e-01</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.793476e-02</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">4.040730e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.033349e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.125147e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.375072e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.818542e-04</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">3.075482e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.251272e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.356534e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">1.360696e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.764588e-04</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">1.801145e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.504456e-07</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">3.310253e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.427839e-03</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">8.791153e-04</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #000000;">2.177831e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">9.693054e-04</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">6.610250e-05</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">2.900813e-02</span><span style="color: #0000FF;">,</span> <span style="color: #000000;">5.735490e-03</span><span style="color: #0000FF;">}</span>
|
||||
|
||||
<span style="color: #008080;">if</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pValues</span><span style="color: #0000FF;">)=</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">min</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pValues</span><span style="color: #0000FF;">)<</span><span style="color: #000000;">0</span> <span style="color: #008080;">or</span> <span style="color: #7060A8;">max</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pValues</span><span style="color: #0000FF;">)></span><span style="color: #000000;">1</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">crash</span><span style="color: #0000FF;">(</span><span style="color: #008000;">"p-values must be in range 0.0 to 1.0"</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
|
||||
<span style="color: #008080;">for</span> <span style="color: #000000;">i</span><span style="color: #0000FF;">=</span><span style="color: #000000;">1</span> <span style="color: #008080;">to</span> <span style="color: #7060A8;">length</span><span style="color: #0000FF;">(</span><span style="color: #000000;">types</span><span style="color: #0000FF;">)</span> <span style="color: #008080;">do</span>
|
||||
<span style="color: #004080;">string</span> <span style="color: #000000;">ti</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">types</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">]</span>
|
||||
<span style="color: #004080;">sequence</span> <span style="color: #000000;">res</span> <span style="color: #0000FF;">=</span> <span style="color: #000000;">adjust</span><span style="color: #0000FF;">(</span><span style="color: #000000;">pValues</span><span style="color: #0000FF;">,</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">)</span>
|
||||
<span style="color: #008080;">if</span> <span style="color: #000000;">res</span><span style="color: #0000FF;">={}</span> <span style="color: #008080;">then</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"\nSorry, do not know how to do %s correction.\n"</span><span style="color: #0000FF;">&</span>
|
||||
<span style="color: #008000;">"Perhaps you want one of these?:\n %s\n"</span><span style="color: #0000FF;">,</span>
|
||||
<span style="color: #0000FF;">{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #7060A8;">join</span><span style="color: #0000FF;">(</span><span style="color: #000000;">types</span><span style="color: #0000FF;">[</span><span style="color: #000000;">1</span><span style="color: #0000FF;">..$-</span><span style="color: #000000;">1</span><span style="color: #0000FF;">],</span><span style="color: #008000;">"\n "</span><span style="color: #0000FF;">)})</span>
|
||||
<span style="color: #008080;">exit</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">if</span>
|
||||
<span style="color: #000080;font-style:italic;">-- printf(1,"%s\n",{ti})
|
||||
-- res = correct_answers[i] -- (for easier comparison only)
|
||||
-- pp(res,{pp_FltFmt,"%13.10f",pp_IntFmt,"%13.10f",pp_Maxlen,75,pp_Pause,0})</span>
|
||||
<span style="color: #004080;">atom</span> <span style="color: #000000;">error</span> <span style="color: #0000FF;">=</span> <span style="color: #7060A8;">sum</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_abs</span><span style="color: #0000FF;">(</span><span style="color: #7060A8;">sq_sub</span><span style="color: #0000FF;">(</span><span style="color: #000000;">res</span><span style="color: #0000FF;">,</span><span style="color: #000000;">correct_answers</span><span style="color: #0000FF;">[</span><span style="color: #000000;">i</span><span style="color: #0000FF;">])))</span>
|
||||
<span style="color: #7060A8;">printf</span><span style="color: #0000FF;">(</span><span style="color: #000000;">1</span><span style="color: #0000FF;">,</span><span style="color: #008000;">"%s has cumulative error of %g\n"</span><span style="color: #0000FF;">,</span> <span style="color: #0000FF;">{</span><span style="color: #000000;">ti</span><span style="color: #0000FF;">,</span><span style="color: #000000;">error</span><span style="color: #0000FF;">})</span>
|
||||
<span style="color: #008080;">end</span> <span style="color: #008080;">for</span>
|
||||
<!--
|
||||
235
Task/P-value-correction/Python/p-value-correction.py
Normal file
235
Task/P-value-correction/Python/p-value-correction.py
Normal file
|
|
@ -0,0 +1,235 @@
|
|||
from __future__ import division
|
||||
import sys
|
||||
|
||||
def pminf(array):
|
||||
x = 1
|
||||
pmin_list = []
|
||||
N = len(array)
|
||||
for index in range(N):
|
||||
if array[index] < x:
|
||||
pmin_list.insert(index, array[index])
|
||||
else:
|
||||
pmin_list.insert(index, x)
|
||||
return pmin_list
|
||||
#end function
|
||||
|
||||
def cumminf(array):
|
||||
cummin = []
|
||||
cumulative_min = array[0]
|
||||
for p in array:
|
||||
if p < cumulative_min:
|
||||
cumulative_min = p
|
||||
cummin.append(cumulative_min)
|
||||
return cummin
|
||||
#end
|
||||
|
||||
def cummaxf(array):
|
||||
cummax = []
|
||||
cumulative_max = array[0]
|
||||
for e in array:
|
||||
if e > cumulative_max:
|
||||
cumulative_max = e
|
||||
cummax.append(cumulative_max)
|
||||
return cummax
|
||||
#end
|
||||
|
||||
def order(*args):
|
||||
if len(args) > 1:
|
||||
if args[1].lower() == 'false':# if ($string1 eq $string2) {
|
||||
return sorted(range(len(args[0])), key = lambda k: args[0][k])
|
||||
elif list(args[1].lower()) == list('true'):
|
||||
return sorted(range(len(args[0])), key = lambda k: args[0][k], reverse = True)
|
||||
else:
|
||||
print "%s isn't a recognized parameter" % args[1]
|
||||
sys.exit()
|
||||
elif len(args) == 1:
|
||||
return sorted(range(len(args[0])), key = lambda k: args[0][k])
|
||||
#end
|
||||
|
||||
def p_adjust(*args):
|
||||
method = "bh"
|
||||
pvalues = args[0]
|
||||
if len(args) > 1:
|
||||
methods = {"bh", "fdr", "by", "holm", "hommel", "bonferroni", "hochberg"}
|
||||
metharg = arg[1].lower()
|
||||
if metharg in methods:
|
||||
method = metharg
|
||||
lp = len(pvalues)
|
||||
n = lp
|
||||
qvalues = []
|
||||
|
||||
if method == 'hochberg':#already all lower case
|
||||
o = order(pvalues, 'TRUE')
|
||||
cummin_input = []
|
||||
for index in range(n):
|
||||
cummin_input.insert(index, (index+1)*pvalues[o[index]])
|
||||
cummin = cumminf(cummin_input)
|
||||
pmin = pminf(cummin)
|
||||
ro = order(o)
|
||||
qvalues = [pmin[i] for i in ro]
|
||||
elif method == 'bh':
|
||||
o = order(pvalues, 'TRUE')
|
||||
cummin_input = []
|
||||
for index in range(n):
|
||||
cummin_input.insert(index, (n/(n-index))* pvalues[o[index]])
|
||||
ro = order(o)
|
||||
cummin = cumminf(cummin_input)
|
||||
pmin = pminf(cummin)
|
||||
qvalues = [pmin[i] for i in ro]
|
||||
elif method == 'by':
|
||||
q = 0.0
|
||||
o = order(pvalues, 'TRUE')
|
||||
ro = order(o)
|
||||
for index in range(1, n+1):
|
||||
q += 1.0 / index;
|
||||
cummin_input = []
|
||||
for index in range(n):
|
||||
cummin_input.insert(index, q * (n/(n-index)) * pvalues[o[index]])
|
||||
cummin = cumminf(cummin_input)
|
||||
pmin = pminf(cummin)
|
||||
qvalues = [pmin[i] for i in ro]
|
||||
elif method == 'bonferroni':
|
||||
for index in range(n):
|
||||
q = pvalues[index] * n
|
||||
if (0 <= q) and (q < 1):
|
||||
qvalues.insert(index, q)
|
||||
elif q >= 1:
|
||||
qvalues.insert(index, 1)
|
||||
else:
|
||||
print '%g won\'t give a Bonferroni adjusted p' % q
|
||||
sys.exit()
|
||||
elif method == 'holm':
|
||||
o = order(pvalues)
|
||||
cummax_input = []
|
||||
for index in range(n):
|
||||
cummax_input.insert(index, (n - index) * pvalues[o[index]])
|
||||
ro = order(o)
|
||||
cummax = cummaxf(cummax_input)
|
||||
pmin = pminf(cummax)
|
||||
qvalues = [pmin[i] for i in ro]
|
||||
elif method == 'hommel':
|
||||
i = range(1,n+1)
|
||||
o = order(pvalues)
|
||||
p = [pvalues[index] for index in o]
|
||||
ro = order(o)
|
||||
pa = []
|
||||
q = []
|
||||
smin = n*p[0]
|
||||
for index in range(n):
|
||||
temp = n*p[index] / (index + 1)
|
||||
if temp < smin:
|
||||
smin = temp
|
||||
for index in range(n):
|
||||
pa.insert(index, smin)
|
||||
q.insert(index, smin)
|
||||
for j in range(n-1,1,-1):
|
||||
ij = range(1,n-j+2)
|
||||
for x in range(len(ij)):
|
||||
ij[x] -= 1
|
||||
I2_LENGTH = j - 1
|
||||
i2 = []
|
||||
for index in range(I2_LENGTH+1):
|
||||
i2.insert(index, n - j + 2 + index - 1)
|
||||
q1 = j * p[i2[0]] / 2.0
|
||||
for index in range(1,I2_LENGTH):
|
||||
TEMP_Q1 = j * p[i2[index]] / (2.0 + index)
|
||||
if TEMP_Q1 < q1:
|
||||
q1 = TEMP_Q1
|
||||
for index in range(n - j + 1):
|
||||
q[ij[index]] = min(j * p[ij[index]], q1)
|
||||
for index in range(I2_LENGTH):
|
||||
q[i2[index]] = q[n-j]
|
||||
for index in range(n):
|
||||
if pa[index] < q[index]:
|
||||
pa[index] = q[index]
|
||||
qvalues = [pa[index] for index in ro]
|
||||
else:
|
||||
print "method %s isn't defined." % method
|
||||
sys.exit()
|
||||
return qvalues
|
||||
|
||||
pvalues = [4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03]
|
||||
|
||||
correct_answers = {}
|
||||
|
||||
correct_answers['bh'] = [6.126681e-01, 8.521710e-01, 1.987205e-01, 1.891595e-01, 3.217789e-01,
|
||||
9.301450e-01, 4.870370e-01, 9.301450e-01, 6.049731e-01, 6.826753e-01,
|
||||
6.482629e-01, 7.253722e-01, 5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01, 4.887526e-01, 1.136717e-01,
|
||||
4.991891e-01, 8.769926e-01, 9.991834e-01, 3.217789e-01, 9.301450e-01,
|
||||
2.304958e-01, 5.832475e-01, 3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02, 6.250189e-02, 3.636589e-03,
|
||||
2.562902e-03, 2.946883e-02, 6.166064e-03, 3.899547e-02, 2.688991e-03,
|
||||
4.502862e-04, 1.252228e-05, 7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03, 7.252032e-02, 2.205958e-02]
|
||||
|
||||
correct_answers['by'] = [1.000000e+00, 1.000000e+00, 8.940844e-01, 8.510676e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 5.114323e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01, 2.812089e-01, 1.636176e-02,
|
||||
1.153102e-02, 1.325863e-01, 2.774239e-02, 1.754486e-01, 1.209832e-02,
|
||||
2.025930e-03, 5.634031e-05, 3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03, 3.262838e-01, 9.925057e-02]
|
||||
|
||||
correct_answers['bonferroni'] = [1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 7.019185e-01, 1.000000e+00, 1.000000e+00,
|
||||
2.020365e-01, 1.516674e-02, 5.625735e-01, 1.000000e+00, 2.909271e-02,
|
||||
1.537741e-02, 4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01, 4.395577e-02,
|
||||
1.088915e-02, 4.846527e-02, 3.305125e-03, 1.000000e+00, 2.867745e-01]
|
||||
|
||||
correct_answers['hochberg'] = [9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.632662e-01, 9.991834e-01, 9.991834e-01,
|
||||
1.575885e-01, 1.383967e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.383967e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01]
|
||||
|
||||
correct_answers['holm'] = [1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 4.632662e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.575885e-01, 1.395341e-02, 3.938014e-01, 7.600230e-01, 2.501973e-02,
|
||||
1.395341e-02, 3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01, 3.692284e-02,
|
||||
1.023581e-02, 3.974152e-02, 3.172920e-03, 8.992520e-01, 2.179486e-01]
|
||||
|
||||
correct_answers['hommel'] = [9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 4.351895e-01, 9.991834e-01, 9.766522e-01,
|
||||
1.414256e-01, 1.304340e-02, 3.530937e-01, 6.887709e-01, 2.385602e-02,
|
||||
1.322457e-02, 2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01, 3.516461e-02,
|
||||
9.582456e-03, 3.877222e-02, 3.172920e-03, 8.122276e-01, 1.950067e-01]
|
||||
|
||||
for key in correct_answers.keys():
|
||||
error = 0.0
|
||||
q = p_adjust(pvalues, key)
|
||||
for i in range(len(q)):
|
||||
error += abs(q[i] - correct_answers[key][i])
|
||||
print '%s error = %g' % (key.upper(), error)
|
||||
29
Task/P-value-correction/R/p-value-correction.r
Normal file
29
Task/P-value-correction/R/p-value-correction.r
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
p <- c(4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03)
|
||||
|
||||
p.adjust(p, method = 'BH')
|
||||
print("Benjamini-Hochberg")
|
||||
writeLines("\n")
|
||||
|
||||
p.adjust(p, method = 'BY')
|
||||
print("Benjamini & Yekutieli")
|
||||
writeLines("\n")
|
||||
|
||||
p.adjust(p, method = 'bonferroni')
|
||||
print("Bonferroni")
|
||||
writeLines("\n")
|
||||
|
||||
p.adjust(p, method = 'hochberg')
|
||||
print("Hochberg")
|
||||
writeLines("\n");
|
||||
|
||||
p.adjust(p, method = 'hommel')
|
||||
writeLines("Hommel\n")
|
||||
94
Task/P-value-correction/Raku/p-value-correction.raku
Normal file
94
Task/P-value-correction/Raku/p-value-correction.raku
Normal file
|
|
@ -0,0 +1,94 @@
|
|||
########################### Helper subs ###########################
|
||||
|
||||
sub adjusted (@p, $type) { "\n$type\n" ~ format adjust( check(@p), $type ) }
|
||||
|
||||
sub format ( @p, $cols = 5 ) {
|
||||
my $i = -$cols;
|
||||
my $fmt = "%1.10f";
|
||||
join "\n", @p.rotor($cols, :partial).map:
|
||||
{ sprintf "[%2d] { join ' ', $fmt xx $_ }", $i+=$cols, $_ };
|
||||
}
|
||||
|
||||
sub check ( @p ) { die 'p-values must be in range 0.0 to 1.0' if @p.min < 0 or 1 < @p.max; @p }
|
||||
|
||||
multi ratchet ( 'up', @p ) { my $m; @p[$_] min= $m, $m = @p[$_] for ^@p; @p }
|
||||
|
||||
multi ratchet ( 'dn', @p ) { my $m; @p[$_] max= $m, $m = @p[$_] for ^@p .reverse; @p }
|
||||
|
||||
sub schwartzian ( @p, &transform, :$ratchet ) {
|
||||
my @pa = @p.map( {[$_, $++]} ).sort( -*.[0] ).map: { [transform(.[0]), .[1]] };
|
||||
@pa[*;0] = ratchet($ratchet, @pa»[0]);
|
||||
@pa.sort( *.[1] )»[0]
|
||||
}
|
||||
|
||||
############# The various p-value correction routines #############
|
||||
|
||||
multi adjust( @p, 'Benjamini-Hochberg' ) {
|
||||
@p.&schwartzian: * * @p / (@p - $++) min 1, :ratchet('up')
|
||||
}
|
||||
|
||||
multi adjust( @p, 'Benjamini-Yekutieli' ) {
|
||||
my \r = ^@p .map( { 1 / ++$ } ).sum;
|
||||
@p.&schwartzian: * * r * @p / (@p - $++) min 1, :ratchet('up')
|
||||
}
|
||||
|
||||
multi adjust( @p, 'Hochberg' ) {
|
||||
my \m = @p.max;
|
||||
@p.&schwartzian: * * ++$ min m, :ratchet('up')
|
||||
}
|
||||
|
||||
multi adjust( @p, 'Holm' ) {
|
||||
@p.&schwartzian: * * ++$ min 1, :ratchet('dn')
|
||||
}
|
||||
|
||||
multi adjust( @p, 'Šidák' ) {
|
||||
@p.&schwartzian: 1 - (1 - *) ** ++$, :ratchet('dn')
|
||||
}
|
||||
|
||||
multi adjust( @p, 'Bonferroni' ) {
|
||||
@p.map: * * @p min 1
|
||||
}
|
||||
|
||||
# Hommel correction can't be easily reduced to a one pass transform
|
||||
multi adjust( @p, 'Hommel' ) {
|
||||
my @s = @p.map( {[$_, $++]} ).sort: *.[0] ; # sorted
|
||||
my \z = +@p; # array si(z)e
|
||||
my @pa = @s»[0].map( * * z / ++$ ).min xx z; # p adjusted
|
||||
my @q; # scratch array
|
||||
for (1 ..^ z).reverse -> $i {
|
||||
my @L = 0 .. z - $i; # lower indices
|
||||
my @U = z - $i ^..^ z; # upper indices
|
||||
my $q = @s[@U]»[0].map( { $_ * $i / (2 + $++) } ).min;
|
||||
@q[@L] = @s[@L]»[0].map: { min $_ * $i, $q, @s[*-1][0] };
|
||||
@pa = ^z .map: { max @pa[$_], @q[$_] }
|
||||
}
|
||||
@pa[@s[*;1].map( {[$_, $++]} ).sort( *.[0] )»[1]]
|
||||
}
|
||||
|
||||
multi adjust ( @p, $unknown ) {
|
||||
note "\nSorry, do not know how to do $unknown correction.\n" ~
|
||||
"Perhaps you want one of these?:\n" ~
|
||||
<Benjamini-Hochberg Benjamini-Yekutieli Bonferroni Hochberg
|
||||
Holm Hommel Šidák>.join("\n");
|
||||
exit
|
||||
}
|
||||
|
||||
########################### The task ###########################
|
||||
|
||||
my @p-values =
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
;
|
||||
|
||||
for < Benjamini-Hochberg Benjamini-Yekutieli Bonferroni Hochberg Holm Hommel Šidák >
|
||||
{
|
||||
say adjusted @p-values, $_
|
||||
}
|
||||
264
Task/P-value-correction/Ruby/p-value-correction.rb
Normal file
264
Task/P-value-correction/Ruby/p-value-correction.rb
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
def pmin(array)
|
||||
x = 1
|
||||
pmin_array = []
|
||||
array.each_index do |i|
|
||||
pmin_array[i] = [array[i], x].min
|
||||
abort if pmin_array[i] > 1
|
||||
end
|
||||
pmin_array
|
||||
end
|
||||
|
||||
def cummin(array)
|
||||
cumulative_min = array[0]
|
||||
arr_cummin = []
|
||||
array.each do |p|
|
||||
cumulative_min = [p, cumulative_min].min
|
||||
arr_cummin.push(cumulative_min)
|
||||
end
|
||||
arr_cummin
|
||||
end
|
||||
|
||||
def cummax(array)
|
||||
cumulative_max = array[0]
|
||||
arr_cummax = []
|
||||
array.each do |p|
|
||||
cumulative_max = [p, cumulative_max].max
|
||||
arr_cummax.push(cumulative_max)
|
||||
end
|
||||
arr_cummax
|
||||
end
|
||||
|
||||
# decreasing variable is optional
|
||||
def order(array, decreasing = false)
|
||||
if decreasing == false
|
||||
array.sort.map { |n| array.index(n) }
|
||||
else
|
||||
array.sort.map { |n| array.index(n) }.reverse
|
||||
end
|
||||
end
|
||||
|
||||
def p_adjust(arr_pvalues, method = 'Holm')
|
||||
lp = arr_pvalues.size
|
||||
n = lp
|
||||
if method.casecmp('hochberg').zero?
|
||||
arr_o = order(arr_pvalues, true)
|
||||
arr_cummin_input = []
|
||||
(0..n).each do |index|
|
||||
arr_cummin_input[index] = (index + 1) * arr_pvalues[arr_o[index].to_i]
|
||||
end
|
||||
arr_cummin = cummin(arr_cummin_input)
|
||||
arr_pmin = pmin(arr_cummin)
|
||||
arr_ro = order(arr_o)
|
||||
return arr_pmin.values_at(*arr_ro)
|
||||
elsif method.casecmp('bh').zero? || method.casecmp('benjamini-hochberg').zero?
|
||||
arr_o = order(arr_pvalues, true)
|
||||
arr_cummin_input = []
|
||||
(0..(n - 1)).each do |i|
|
||||
arr_cummin_input[i] = (n / (n - i).to_f) * arr_pvalues[arr_o[i]]
|
||||
end
|
||||
arr_ro = order(arr_o)
|
||||
arr_cummin = cummin(arr_cummin_input)
|
||||
arr_pmin = pmin(arr_cummin)
|
||||
return arr_pmin.values_at(*arr_ro)
|
||||
elsif method.casecmp('by').zero? || method.casecmp('benjamini-yekutieli').zero?
|
||||
q = 0.0
|
||||
arr_o = order(arr_pvalues, true)
|
||||
arr_ro = order(arr_o)
|
||||
(1..n).each do |index|
|
||||
q += 1.0 / index
|
||||
end
|
||||
arr_cummin_input = []
|
||||
(0..(n - 1)).each do |i|
|
||||
arr_cummin_input[i] = q * (n / (n - i).to_f) * arr_pvalues[arr_o[i]]
|
||||
end
|
||||
arr_cummin = cummin(arr_cummin_input)
|
||||
arr_pmin = pmin(arr_cummin)
|
||||
return arr_pmin.values_at(*arr_ro)
|
||||
elsif method.casecmp('bonferroni').zero?
|
||||
arr_qvalues = []
|
||||
(0..(n - 1)).each do |i|
|
||||
q = arr_pvalues[i] * n
|
||||
if (q >= 0) && (q < 1)
|
||||
arr_qvalues[i] = q
|
||||
elsif q >= 1
|
||||
arr_qvalues[i] = 1.0
|
||||
else
|
||||
puts "Falied to get Bonferroni adjusted p for #{arr_pvalues[i]}"
|
||||
end
|
||||
end
|
||||
return arr_qvalues
|
||||
elsif method.casecmp('holm').zero?
|
||||
o = order(arr_pvalues)
|
||||
cummax_input = []
|
||||
(0..(n - 1)).each do |index|
|
||||
cummax_input[index] = (n - index) * arr_pvalues[o[index]]
|
||||
end
|
||||
ro = order(o)
|
||||
arr_cummax = cummax(cummax_input)
|
||||
arr_pmin = pmin(arr_cummax)
|
||||
return arr_pmin.values_at(*ro)
|
||||
elsif method.casecmp('hommel').zero?
|
||||
o = order(arr_pvalues)
|
||||
arr_p = arr_pvalues.values_at(*o)
|
||||
ro = order(o)
|
||||
q = []
|
||||
pa = []
|
||||
min = n * arr_p[0]
|
||||
(0..(n - 1)).each do |index|
|
||||
temp = n * arr_p[index] / (index + 1)
|
||||
min = [min, temp].min
|
||||
end
|
||||
(0..(n - 1)).each do |index|
|
||||
pa[index] = min
|
||||
q[index] = min
|
||||
end
|
||||
j = n - 1
|
||||
while j >= 2
|
||||
ij = Array 0..(n - j)
|
||||
i2_length = j - 1
|
||||
i2 = []
|
||||
(0..(i2_length - 1)).each do |i|
|
||||
i2[i] = n - j + 2 + i - 1 # R's indices are 1-based, C's are 0-based
|
||||
end
|
||||
q1 = j * arr_p[i2[0]] / 2.0
|
||||
(1..(i2_length - 1)).each do |i|
|
||||
temp_q1 = j * arr_p[i2[i]] / (2 + i)
|
||||
q1 = [temp_q1, q1].min
|
||||
end
|
||||
(0..(n - j)).each do |i|
|
||||
tmp = j * arr_p[ij[i]]
|
||||
q[ij[i]] = [tmp, q1].min
|
||||
end
|
||||
(0..(i2_length - 1)).each do |i|
|
||||
q[i2[i]] = q[n - j]
|
||||
end
|
||||
(0..(n - 1)).each do |i|
|
||||
pa[i] = q[i] if pa[i] < q[i]
|
||||
end
|
||||
j -= 1
|
||||
end
|
||||
return pa.values_at(*ro)
|
||||
else
|
||||
puts "#{method} isn't accepted."
|
||||
abort
|
||||
end
|
||||
end
|
||||
|
||||
pvalues =
|
||||
[4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02,
|
||||
1.801962e-01, 8.752257e-01, 2.922222e-01, 9.115421e-01,
|
||||
4.355806e-01, 5.324867e-01, 4.926798e-01, 5.802978e-01,
|
||||
3.485442e-01, 7.883130e-01, 2.729308e-01, 8.502518e-01,
|
||||
4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01,
|
||||
9.037516e-01, 1.198578e-01, 3.966083e-01, 1.403837e-02,
|
||||
7.328671e-01, 6.793476e-02, 4.040730e-03, 3.033349e-04,
|
||||
1.125147e-02, 2.375072e-02, 5.818542e-04, 3.075482e-04,
|
||||
8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03,
|
||||
8.791153e-04, 2.177831e-04, 9.693054e-04, 6.610250e-05,
|
||||
2.900813e-02, 5.735490e-03]
|
||||
|
||||
correct_answers = {
|
||||
'Benjamini-Hochberg' => [6.126681e-01, 8.521710e-01, 1.987205e-01,
|
||||
1.891595e-01, 3.217789e-01, 9.301450e-01,
|
||||
4.870370e-01, 9.301450e-01, 6.049731e-01,
|
||||
6.826753e-01, 6.482629e-01, 7.253722e-01,
|
||||
5.280973e-01, 8.769926e-01, 4.705703e-01,
|
||||
9.241867e-01, 6.049731e-01, 7.856107e-01,
|
||||
4.887526e-01, 1.136717e-01, 4.991891e-01,
|
||||
8.769926e-01, 9.991834e-01, 3.217789e-01,
|
||||
9.301450e-01, 2.304958e-01, 5.832475e-01,
|
||||
3.899547e-02, 8.521710e-01, 1.476843e-01,
|
||||
1.683638e-02, 2.562902e-03, 3.516084e-02,
|
||||
6.250189e-02, 3.636589e-03, 2.562902e-03,
|
||||
2.946883e-02, 6.166064e-03, 3.899547e-02,
|
||||
2.688991e-03, 4.502862e-04, 1.252228e-05,
|
||||
7.881555e-02, 3.142613e-02, 4.846527e-03,
|
||||
2.562902e-03, 4.846527e-03, 1.101708e-03,
|
||||
7.252032e-02, 2.205958e-02],
|
||||
'Benjamini-Yekutieli' => [1.000000e+00, 1.000000e+00, 8.940844e-01,
|
||||
8.510676e-01, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 5.114323e-01, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.754486e-01, 1.000000e+00, 6.644618e-01,
|
||||
7.575031e-02, 1.153102e-02, 1.581959e-01,
|
||||
2.812089e-01, 1.636176e-02, 1.153102e-02,
|
||||
1.325863e-01, 2.774239e-02, 1.754486e-01,
|
||||
1.209832e-02, 2.025930e-03, 5.634031e-05,
|
||||
3.546073e-01, 1.413926e-01, 2.180552e-02,
|
||||
1.153102e-02, 2.180552e-02, 4.956812e-03,
|
||||
3.262838e-01, 9.925057e-02],
|
||||
'Bonferroni' => [1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 7.019185e-01,
|
||||
1.000000e+00, 1.000000e+00, 2.020365e-01, 1.516674e-02,
|
||||
5.625735e-01, 1.000000e+00, 2.909271e-02, 1.537741e-02,
|
||||
4.125636e-01, 6.782670e-02, 6.803480e-01, 1.882294e-02,
|
||||
9.005725e-04, 1.252228e-05, 1.000000e+00, 4.713920e-01,
|
||||
4.395577e-02, 1.088915e-02, 4.846527e-02, 3.305125e-03,
|
||||
1.000000e+00, 2.867745e-01],
|
||||
|
||||
'Hochberg' => [9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 4.632662e-01,
|
||||
9.991834e-01, 9.991834e-01, 1.575885e-01, 1.383967e-02,
|
||||
3.938014e-01, 7.600230e-01, 2.501973e-02, 1.383967e-02,
|
||||
3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01,
|
||||
3.692284e-02, 1.023581e-02, 3.974152e-02, 3.172920e-03,
|
||||
8.992520e-01, 2.179486e-01],
|
||||
'Holm' => [1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 1.000000e+00,
|
||||
1.000000e+00, 1.000000e+00, 1.000000e+00, 4.632662e-01,
|
||||
1.000000e+00, 1.000000e+00, 1.575885e-01, 1.395341e-02,
|
||||
3.938014e-01, 7.600230e-01, 2.501973e-02, 1.395341e-02,
|
||||
3.052971e-01, 5.426136e-02, 4.626366e-01, 1.656419e-02,
|
||||
8.825610e-04, 1.252228e-05, 9.930759e-01, 3.394022e-01,
|
||||
3.692284e-02, 1.023581e-02, 3.974152e-02, 3.172920e-03,
|
||||
8.992520e-01, 2.179486e-01],
|
||||
|
||||
'Hommel' => [9.991834e-01, 9.991834e-01, 9.991834e-01, 9.987624e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.595180e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 9.991834e-01,
|
||||
9.991834e-01, 9.991834e-01, 9.991834e-01, 4.351895e-01,
|
||||
9.991834e-01, 9.766522e-01, 1.414256e-01, 1.304340e-02,
|
||||
3.530937e-01, 6.887709e-01, 2.385602e-02, 1.322457e-02,
|
||||
2.722920e-01, 5.426136e-02, 4.218158e-01, 1.581127e-02,
|
||||
8.825610e-04, 1.252228e-05, 8.743649e-01, 3.016908e-01,
|
||||
3.516461e-02, 9.582456e-03, 3.877222e-02, 3.172920e-03,
|
||||
8.122276e-01, 1.950067e-01]
|
||||
}
|
||||
|
||||
# correct_answers.each do |method, answers|
|
||||
methods = ['Benjamini-Yekutieli', 'Benjamini-Hochberg', 'Hochberg',
|
||||
'Bonferroni', 'Holm', 'Hommel']
|
||||
methods.each do |method|
|
||||
puts method
|
||||
error = 0.0
|
||||
arr_q = p_adjust(pvalues, method)
|
||||
arr_q.each_index do |p|
|
||||
error += (correct_answers[method][p] - arr_q[p])
|
||||
end
|
||||
puts "total error for #{method} = #{error}"
|
||||
end
|
||||
232
Task/P-value-correction/Rust/p-value-correction.rust
Normal file
232
Task/P-value-correction/Rust/p-value-correction.rust
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
use std::iter;
|
||||
|
||||
#[rustfmt::skip]
|
||||
const PVALUES:[f64;50] = [
|
||||
4.533_744e-01, 7.296_024e-01, 9.936_026e-02, 9.079_658e-02, 1.801_962e-01,
|
||||
8.752_257e-01, 2.922_222e-01, 9.115_421e-01, 4.355_806e-01, 5.324_867e-01,
|
||||
4.926_798e-01, 5.802_978e-01, 3.485_442e-01, 7.883_130e-01, 2.729_308e-01,
|
||||
8.502_518e-01, 4.268_138e-01, 6.442_008e-01, 3.030_266e-01, 5.001_555e-02,
|
||||
3.194_810e-01, 7.892_933e-01, 9.991_834e-01, 1.745_691e-01, 9.037_516e-01,
|
||||
1.198_578e-01, 3.966_083e-01, 1.403_837e-02, 7.328_671e-01, 6.793_476e-02,
|
||||
4.040_730e-03, 3.033_349e-04, 1.125_147e-02, 2.375_072e-02, 5.818_542e-04,
|
||||
3.075_482e-04, 8.251_272e-03, 1.356_534e-03, 1.360_696e-02, 3.764_588e-04,
|
||||
1.801_145e-05, 2.504_456e-07, 3.310_253e-02, 9.427_839e-03, 8.791_153e-04,
|
||||
2.177_831e-04, 9.693_054e-04, 6.610_250e-05, 2.900_813e-02, 5.735_490e-03
|
||||
];
|
||||
|
||||
#[derive(Debug)]
|
||||
enum CorrectionType {
|
||||
BenjaminiHochberg,
|
||||
BenjaminiYekutieli,
|
||||
Bonferroni,
|
||||
Hochberg,
|
||||
Holm,
|
||||
Hommel,
|
||||
Sidak,
|
||||
}
|
||||
|
||||
enum SortDirection {
|
||||
Increasing,
|
||||
Decreasing,
|
||||
}
|
||||
|
||||
/// orders **input** vector by value and multiplies with **multiplier** vector
|
||||
/// Finally returns the multiplied values in the original order of **input**
|
||||
fn ordered_multiply(input: &[f64], multiplier: &[f64], direction: &SortDirection) -> Vec<f64> {
|
||||
let order_by_value = match direction {
|
||||
SortDirection::Increasing => {
|
||||
|a: &(f64, usize), b: &(f64, usize)| b.0.partial_cmp(&a.0).unwrap()
|
||||
}
|
||||
SortDirection::Decreasing => {
|
||||
|a: &(f64, usize), b: &(f64, usize)| a.0.partial_cmp(&b.0).unwrap()
|
||||
}
|
||||
};
|
||||
|
||||
let cmp_minmax = match direction {
|
||||
SortDirection::Increasing => |a: f64, b: f64| a.gt(&b),
|
||||
SortDirection::Decreasing => |a: f64, b: f64| a.lt(&b),
|
||||
};
|
||||
|
||||
// add original order index
|
||||
let mut input_indexed = input
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, &p_value)| (p_value, idx))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// order by value desc/asc
|
||||
input_indexed.sort_unstable_by(order_by_value);
|
||||
|
||||
// do the multiplication in place, clamp it at 1.0,
|
||||
// keep the original index in place
|
||||
for i in 0..input_indexed.len() {
|
||||
input_indexed[i] = (
|
||||
f64::min(1.0, input_indexed[i].0 * multiplier[i]),
|
||||
input_indexed[i].1,
|
||||
);
|
||||
}
|
||||
|
||||
// make vector strictly monotonous increasing/decreasing in place
|
||||
for i in 1..input_indexed.len() {
|
||||
if cmp_minmax(input_indexed[i].0, input_indexed[i - 1].0) {
|
||||
input_indexed[i] = (input_indexed[i - 1].0, input_indexed[i].1);
|
||||
}
|
||||
}
|
||||
|
||||
// re-sort back to original order
|
||||
input_indexed.sort_unstable_by(|a: &(f64, usize), b: &(f64, usize)| a.1.cmp(&b.1));
|
||||
|
||||
// remove ordering index
|
||||
let (resorted, _): (Vec<_>, Vec<_>) = input_indexed.iter().cloned().unzip();
|
||||
resorted
|
||||
}
|
||||
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn hommel(input: &[f64]) -> Vec<f64> {
|
||||
// using algorith described:
|
||||
// http://stat.wharton.upenn.edu/~steele/Courses/956/ResourceDetails/MultipleComparision/Writght92.pdf
|
||||
|
||||
// add original order index
|
||||
let mut input_indexed = input
|
||||
.iter()
|
||||
.enumerate()
|
||||
.map(|(idx, &p_value)| (p_value, idx))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
// order by value asc
|
||||
input_indexed
|
||||
.sort_unstable_by(|a: &(f64, usize), b: &(f64, usize)| a.0.partial_cmp(&b.0).unwrap());
|
||||
|
||||
let (p_values, order): (Vec<_>, Vec<_>) = input_indexed.iter().cloned().unzip();
|
||||
|
||||
let n = input.len();
|
||||
|
||||
// initial minimal n*p/i values
|
||||
// get the smalles of these values
|
||||
let min_result = (0..n)
|
||||
.map(|i| ((p_values[i] * n as f64) / (i + 1) as f64))
|
||||
.fold(1. / 0. /* -inf */, f64::min);
|
||||
|
||||
// // initialize result vector with minimal values
|
||||
let mut result = iter::repeat(min_result).take(n).collect::<Vec<_>>();
|
||||
|
||||
for m in (2..n).rev() {
|
||||
let cmin: f64;
|
||||
let m_as_float = m as f64;
|
||||
let mut a = p_values.clone();
|
||||
// println!("\nn: {}", m);
|
||||
{
|
||||
// split p-values into two group
|
||||
let (_, second) = p_values.split_at(n - m + 1);
|
||||
|
||||
// calculate minumum of m*p/i for this second group
|
||||
cmin = second
|
||||
.iter()
|
||||
.zip(2..=m)
|
||||
.map(|(p, i)| (m_as_float * p) / i as f64)
|
||||
.fold(1. / 0. /* inf */, f64::min);
|
||||
}
|
||||
|
||||
// replace p values if p<cmin in the second group
|
||||
((n - m + 1)..n).for_each(|i| a[i] = a[i].max(cmin));
|
||||
|
||||
// replace p values if min(cmin, m*p) > p
|
||||
(0..=(n - m)).for_each(|i| a[i] = a[i].max(f64::min(cmin, m_as_float * p_values[i])));
|
||||
|
||||
// store in the result vector if any adjusted p is higher than the current one
|
||||
(0..n).for_each(|i| result[i] = result[i].max(a[i]));
|
||||
}
|
||||
|
||||
// re-sort into the original order
|
||||
let mut result = result
|
||||
.into_iter()
|
||||
.zip(order.into_iter())
|
||||
.map(|(p, idx)| (p, idx))
|
||||
.collect::<Vec<_>>();
|
||||
result.sort_unstable_by(|a: &(f64, usize), b: &(f64, usize)| a.1.cmp(&b.1));
|
||||
let (result, _): (Vec<_>, Vec<_>) = result.iter().cloned().unzip();
|
||||
result
|
||||
}
|
||||
#[allow(clippy::cast_precision_loss)]
|
||||
fn p_value_correction(p_values: &[f64], ctype: &CorrectionType) -> Vec<f64> {
|
||||
let p_vec = p_values.to_vec();
|
||||
if p_values.is_empty() {
|
||||
return p_vec;
|
||||
}
|
||||
|
||||
let fsize = p_values.len() as f64;
|
||||
|
||||
match ctype {
|
||||
CorrectionType::BenjaminiHochberg => {
|
||||
let multiplier = (0..p_values.len())
|
||||
.map(|index| fsize / (fsize - index as f64))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ordered_multiply(&p_vec, &multiplier, &SortDirection::Increasing)
|
||||
}
|
||||
CorrectionType::BenjaminiYekutieli => {
|
||||
let q: f64 = (1..=p_values.len()).map(|index| 1. / index as f64).sum();
|
||||
let multiplier = (0..p_values.len())
|
||||
.map(|index| q * fsize / (fsize - index as f64))
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ordered_multiply(&p_vec, &multiplier, &SortDirection::Increasing)
|
||||
}
|
||||
CorrectionType::Bonferroni => p_vec
|
||||
.iter()
|
||||
.map(|p| f64::min(p * fsize, 1.0))
|
||||
.collect::<Vec<_>>(),
|
||||
CorrectionType::Hochberg => {
|
||||
let multiplier = (0..p_values.len())
|
||||
.map(|index| 1. + index as f64)
|
||||
.collect::<Vec<_>>();
|
||||
ordered_multiply(&p_vec, &multiplier, &SortDirection::Increasing)
|
||||
}
|
||||
CorrectionType::Holm => {
|
||||
let multiplier = (0..p_values.len())
|
||||
.map(|index| fsize - index as f64)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
ordered_multiply(&p_vec, &multiplier, &SortDirection::Decreasing)
|
||||
}
|
||||
CorrectionType::Sidak => p_vec
|
||||
.iter()
|
||||
.map(|x| 1. - (1. - x).powf(fsize))
|
||||
.collect::<Vec<_>>(),
|
||||
CorrectionType::Hommel => hommel(&p_vec),
|
||||
}
|
||||
}
|
||||
|
||||
// prints array into a nice table, max 5 floats/row
|
||||
fn array_to_string(a: &[f64]) -> String {
|
||||
a.chunks(5)
|
||||
.enumerate()
|
||||
.map(|(index, e)| {
|
||||
format!(
|
||||
"[{:>2}]: {}",
|
||||
index * 5,
|
||||
e.iter()
|
||||
.map(|x| format!("{:>1.10}", x))
|
||||
.collect::<Vec<_>>()
|
||||
.join(", ")
|
||||
)
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n")
|
||||
}
|
||||
fn main() {
|
||||
let ctypes = [
|
||||
CorrectionType::BenjaminiHochberg,
|
||||
CorrectionType::BenjaminiYekutieli,
|
||||
CorrectionType::Bonferroni,
|
||||
CorrectionType::Hochberg,
|
||||
CorrectionType::Holm,
|
||||
CorrectionType::Sidak,
|
||||
CorrectionType::Hommel,
|
||||
];
|
||||
|
||||
for ctype in &ctypes {
|
||||
println!("\n{:?}:", ctype);
|
||||
println!("{}", array_to_string(&p_value_correction(&PVALUES, ctype)));
|
||||
}
|
||||
}
|
||||
18
Task/P-value-correction/SAS/p-value-correction.sas
Normal file
18
Task/P-value-correction/SAS/p-value-correction.sas
Normal file
|
|
@ -0,0 +1,18 @@
|
|||
data pvalues;
|
||||
input raw_p @@;
|
||||
cards;
|
||||
4.533744e-01 7.296024e-01 9.936026e-02 9.079658e-02 1.801962e-01
|
||||
8.752257e-01 2.922222e-01 9.115421e-01 4.355806e-01 5.324867e-01
|
||||
4.926798e-01 5.802978e-01 3.485442e-01 7.883130e-01 2.729308e-01
|
||||
8.502518e-01 4.268138e-01 6.442008e-01 3.030266e-01 5.001555e-02
|
||||
3.194810e-01 7.892933e-01 9.991834e-01 1.745691e-01 9.037516e-01
|
||||
1.198578e-01 3.966083e-01 1.403837e-02 7.328671e-01 6.793476e-02
|
||||
4.040730e-03 3.033349e-04 1.125147e-02 2.375072e-02 5.818542e-04
|
||||
3.075482e-04 8.251272e-03 1.356534e-03 1.360696e-02 3.764588e-04
|
||||
1.801145e-05 2.504456e-07 3.310253e-02 9.427839e-03 8.791153e-04
|
||||
2.177831e-04 9.693054e-04 6.610250e-05 2.900813e-02 5.735490e-03
|
||||
;
|
||||
run;
|
||||
|
||||
proc multtest pdata=pvalues bon sid hom hoc holm;
|
||||
run;
|
||||
1
Task/P-value-correction/Stata/p-value-correction-1.stata
Normal file
1
Task/P-value-correction/Stata/p-value-correction-1.stata
Normal file
|
|
@ -0,0 +1 @@
|
|||
ssc install qqvalue
|
||||
23
Task/P-value-correction/Stata/p-value-correction-2.stata
Normal file
23
Task/P-value-correction/Stata/p-value-correction-2.stata
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
clear
|
||||
|
||||
#delimit ;
|
||||
input p;
|
||||
4.533744e-01;7.296024e-01;9.936026e-02;9.079658e-02;1.801962e-01;
|
||||
8.752257e-01;2.922222e-01;9.115421e-01;4.355806e-01;5.324867e-01;
|
||||
4.926798e-01;5.802978e-01;3.485442e-01;7.883130e-01;2.729308e-01;
|
||||
8.502518e-01;4.268138e-01;6.442008e-01;3.030266e-01;5.001555e-02;
|
||||
3.194810e-01;7.892933e-01;9.991834e-01;1.745691e-01;9.037516e-01;
|
||||
1.198578e-01;3.966083e-01;1.403837e-02;7.328671e-01;6.793476e-02;
|
||||
4.040730e-03;3.033349e-04;1.125147e-02;2.375072e-02;5.818542e-04;
|
||||
3.075482e-04;8.251272e-03;1.356534e-03;1.360696e-02;3.764588e-04;
|
||||
1.801145e-05;2.504456e-07;3.310253e-02;9.427839e-03;8.791153e-04;
|
||||
2.177831e-04;9.693054e-04;6.610250e-05;2.900813e-02;5.735490e-03;
|
||||
end;
|
||||
#delimit cr
|
||||
|
||||
loc meth bonferroni sidak holm holland hochberg simes yekutieli
|
||||
foreach m in `meth' {
|
||||
qqvalue p, method(`m') qvalue(`m')
|
||||
}
|
||||
|
||||
list
|
||||
155
Task/P-value-correction/Wren/p-value-correction.wren
Normal file
155
Task/P-value-correction/Wren/p-value-correction.wren
Normal file
|
|
@ -0,0 +1,155 @@
|
|||
import "/dynamic" for Enum
|
||||
import "/fmt" for Fmt
|
||||
import "/seq" for Lst
|
||||
import "/math" for Nums
|
||||
import "/sort" for Sort
|
||||
|
||||
var Direction = Enum.create("Direction", ["UP", "DOWN"])
|
||||
|
||||
// test also for 'Unknown' correction type
|
||||
var types = [
|
||||
"Benjamini-Hochberg", "Benjamini-Yekutieli", "Bonferroni", "Hochberg",
|
||||
"Holm", "Hommel", "Šidák", "Unknown"
|
||||
]
|
||||
|
||||
var pFormat = Fn.new { |p, cols|
|
||||
var i = -cols
|
||||
var fmt = "$1.10f"
|
||||
return Lst.chunks(p, cols).map { |chunk|
|
||||
i = i + cols
|
||||
return Fmt.swrite("[$2d $s", i, chunk.map { |v| Fmt.swrite(fmt, v) }.join(" "))
|
||||
}.join("\n")
|
||||
}
|
||||
|
||||
var check = Fn.new { |p|
|
||||
if (p.count == 0 || Nums.min(p) < 0 || Nums.max(p) > 1) {
|
||||
Fiber.abort("p-values must be in range 0 to 1")
|
||||
}
|
||||
return p
|
||||
}
|
||||
|
||||
var ratchet = Fn.new { |p, dir|
|
||||
var pp = p.toList
|
||||
var m = pp[0]
|
||||
if (dir == Direction.UP) {
|
||||
for (i in 1...pp.count) {
|
||||
if (pp[i] > m) pp[i] = m
|
||||
m = pp[i]
|
||||
}
|
||||
} else {
|
||||
for (i in 1...pp.count) {
|
||||
if (pp[i] < m) pp[i] = m
|
||||
m = pp[i]
|
||||
}
|
||||
}
|
||||
return pp.map { |v| (v < 1) ? v : 1 }.toList
|
||||
}
|
||||
|
||||
var schwartzian = Fn.new { |p, mult, dir|
|
||||
var size = p.count
|
||||
var pwi = List.filled(size, null)
|
||||
for (i in 0...size) pwi[i] = [i, p[i]]
|
||||
var cmp = (dir == Direction.UP) ? Fn.new { |a, b| (b[1] - a[1]).sign } :
|
||||
Fn.new { |a, b| (a[1] - b[1]).sign }
|
||||
var order = Sort.merge(pwi, cmp).map { |e| e[0] }.toList
|
||||
var pa = List.filled(size, 0)
|
||||
for (i in 0...size) pa[i] = mult[i] * p[order[i]]
|
||||
pa = ratchet.call(pa, dir)
|
||||
var owi = List.filled(order.count, null)
|
||||
for (i in 0...order.count) owi[i] = [i, order[i]]
|
||||
cmp = Fn.new { |a, b| (a[1] - b[1]).sign }
|
||||
var order2 = Sort.merge(owi, cmp).map { |e| e[0] }.toList
|
||||
var res = List.filled(size, 0)
|
||||
for (i in 0...size) res[i] = pa[order2[i]]
|
||||
return res
|
||||
}
|
||||
|
||||
var adjust = Fn.new { |p, type|
|
||||
var size = p.count
|
||||
if (size == 0) Fiber.abort("List cannot be empty.")
|
||||
if (type == "Benjamini-Hochberg") {
|
||||
var mult = List.filled(size, 0)
|
||||
for (i in 0...size) mult[i] = size / (size - i)
|
||||
return schwartzian.call(p, mult, Direction.UP)
|
||||
|
||||
} else if (type == "Benjamini-Yekutieli") {
|
||||
var q = (1..size).reduce { |acc, i| acc + 1/i }
|
||||
var mult = List.filled(size, 0)
|
||||
for (i in 0...size) mult[i] = q * size / (size - i)
|
||||
return schwartzian.call(p, mult, Direction.UP)
|
||||
|
||||
} else if (type == "Bonferroni") {
|
||||
return p.map { |v| (v * size).min(1) }.toList
|
||||
|
||||
} else if (type == "Hochberg") {
|
||||
var mult = List.filled(size, 0)
|
||||
for (i in 0...size) mult[i] = i + 1
|
||||
return schwartzian.call(p, mult, Direction.UP)
|
||||
|
||||
} else if (type == "Holm") {
|
||||
var mult = List.filled(size, 0)
|
||||
for (i in 0...size) mult[i] = size - i
|
||||
return schwartzian.call(p, mult, Direction.DOWN)
|
||||
|
||||
} else if (type == "Hommel") {
|
||||
var pwi = List.filled(size, null)
|
||||
for (i in 0...size) pwi[i] = [i, p[i]]
|
||||
var cmp = Fn.new { |a, b| (a[1] - b[1]).sign }
|
||||
var order = Sort.merge(pwi, cmp).map { |e| e[0] }.toList
|
||||
var s = List.filled(size, 0)
|
||||
for (i in 0...size) s[i] = p[order[i]]
|
||||
var m = List.filled(size, 0)
|
||||
for (i in 0...size) m[i] = s[i] * size / (i + 1)
|
||||
var min = Nums.min(m)
|
||||
var q = List.filled(size, min)
|
||||
var pa = List.filled(size, min)
|
||||
for (j in size-1..2) {
|
||||
var lower = List.filled(size - j + 1, 0) // lower indices
|
||||
for (i in 0...lower.count) lower[i] = i
|
||||
var upper = List.filled(j - 1, 0) // upper indices
|
||||
for (i in 0...upper.count) upper[i] = size - j + 1 + i
|
||||
var qmin = j * s[upper[0]] / 2
|
||||
for (i in 1...upper.count) {
|
||||
var temp = s[upper[i]] * j / (2 + i)
|
||||
if (temp < qmin) qmin = temp
|
||||
}
|
||||
for (i in 0...lower.count) {
|
||||
q[lower[i]] = qmin.min(s[lower[i]] * j)
|
||||
}
|
||||
for (i in 0...upper.count) q[upper[i]] = q[size - j]
|
||||
for (i in 0...size) if (pa[i] < q[i]) pa[i] = q[i]
|
||||
}
|
||||
var owi = List.filled(order.count, null)
|
||||
for (i in 0...order.count) owi[i] = [i, order[i]]
|
||||
var order2 = Sort.merge(owi, cmp).map { |e| e[0] }.toList
|
||||
var res = List.filled(size, 0)
|
||||
for (i in 0...size) res[i] = pa[order2[i]]
|
||||
return res
|
||||
|
||||
} else if (type == "Šidák") {
|
||||
return p.map { |v| 1 - (1 - v).pow(size) }.toList
|
||||
|
||||
} else {
|
||||
System.print("\nSorry, do not know how to do '%(type)' correction.\n" +
|
||||
"Perhaps you want one of these?:\n" +
|
||||
types[0...-1].map { |t| " %(t)" }.join("\n")
|
||||
)
|
||||
Fiber.suspend()
|
||||
}
|
||||
}
|
||||
|
||||
var adjusted = Fn.new { |p, type| "\n%(type)\n%(pFormat.call(adjust.call(check.call(p), type), 5))" }
|
||||
|
||||
var pValues = [
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03
|
||||
]
|
||||
types.each { |type| System.print(adjusted.call(pValues, type)) }
|
||||
65
Task/P-value-correction/Zkl/p-value-correction-1.zkl
Normal file
65
Task/P-value-correction/Zkl/p-value-correction-1.zkl
Normal file
|
|
@ -0,0 +1,65 @@
|
|||
fcn bh(pvalues){ // Benjamini-Hochberg
|
||||
psz,pszf := pvalues.len(), psz.toFloat();
|
||||
n_i := psz.pump(List,'wrap(n){ pszf/(psz - n) }); # N/(N-0),N/(N-1),..
|
||||
o,ro := order(pvalues,True),order(o,False); # sort pvalues, sort indices
|
||||
in := psz.pump(List,'wrap(n){ n_i[n]*pvalues[o[n]] });
|
||||
pmin := cummin(in).apply((1.0).min); # (min(1,c[0]),min(1,c[1]),...)
|
||||
ro.apply(pmin.get); # (pmin[ro[0]],pmin[ro[1]],...)
|
||||
}
|
||||
|
||||
fcn by(pvalues){ // Benjamini & Yekutieli
|
||||
psz,pszf := pvalues.len(), psz.toFloat();
|
||||
o,ro := order(pvalues,True),order(o,False); # sort pvalues, sort indices
|
||||
n_i := psz.pump(List,'wrap(n){ pszf/(psz - n) }); # N/(N-0),N/(N-1),..
|
||||
q := [1..psz].reduce(fcn(q,n){ q+=1.0/n },0.0);
|
||||
in := psz.pump(List,'wrap(n){ q * n_i[n] * pvalues[o[n]] });
|
||||
cummin(in).apply((1.0).min) : ro.apply(_.get);
|
||||
}
|
||||
|
||||
fcn hochberg(pvalues){
|
||||
psz,pszf := pvalues.len(), psz.toFloat();
|
||||
o,ro := order(pvalues,True),order(o,False); # sort pvalues, sort indices
|
||||
n_i := psz.pump(List,'wrap(n){ pszf/(psz - n) }); # N/(N-0),N/(N-1),..
|
||||
in := psz.pump(List,'wrap(n){ pvalues[o[n]]*(n + 1) });
|
||||
cummin(in).apply((1.0).min) : ro.apply(_.get);
|
||||
}
|
||||
|
||||
fcn cummin(pvalues){ // R's cumulative minima --> list of mins
|
||||
out,m := List.createLong(pvalues.len()), pvalues[0];
|
||||
foreach pv in (pvalues){ out.append(m=m.min(pv)) }
|
||||
out
|
||||
}
|
||||
fcn order(list,downUp){ // True==increasing, --> List(int) sorted indices
|
||||
f:=(downUp) and fcn(a,b){ a[1]>b[1] } or fcn(a,b){ a[1]<b[1] };
|
||||
[0..].zip(list).pump(List()).sort(f).pump(List,T("get",0))
|
||||
}
|
||||
|
||||
fcn bonferroni(pvalues){ // -->List
|
||||
sz,r := pvalues.len(),List();
|
||||
foreach pv in (pvalues){
|
||||
b:=pv*sz;
|
||||
if(b>=1.0) r.append(1.0);
|
||||
else if(0.0<=b<1.0) r.append(b);
|
||||
else throw(Exception.ValueError(
|
||||
"%g is outside of the interval I planned.".fmt(b)));
|
||||
}
|
||||
r
|
||||
}
|
||||
|
||||
fcn hommel(pvalues){
|
||||
psz,indices := pvalues.len(), [1..psz].walk(); // 1,2,3,4...
|
||||
o,ro := order(pvalues,False),order(o,False); # sort pvalues, sort indices
|
||||
p := o.apply('wrap(n){ pvalues[n] }).copy(); // pvalues[*o]
|
||||
npi := [1..].zip(p).apply('wrap([(n,p)]){ p*psz/n });
|
||||
min := (0.0).min(npi); // min value in npi
|
||||
pa,q := List.createLong(psz,min), pa.copy(); #(min,min,,,)
|
||||
foreach j in ([psz - 1..2,-1]){
|
||||
ij:=[0..psz - j].walk();
|
||||
i2:=(j - 1).pump(List,'+(psz - j + 1));
|
||||
q1:=(0.0).min((j-1).pump(List,'wrap(n){ p[i2[n]]*j/(2 + n) }));
|
||||
foreach i in (psz - j + 1){ q[ij[i]] = q1.min(p[ij[i]]*j) }
|
||||
foreach i in (j - 1){ q[i2[i]] = q[psz - j] }
|
||||
foreach i in (psz){ pa[i] = pa[i].max(q[i]) }
|
||||
}
|
||||
psz.pump(List,'wrap(n){ pa[ro[n]] }); // Hommel q-values
|
||||
}
|
||||
26
Task/P-value-correction/Zkl/p-value-correction-2.zkl
Normal file
26
Task/P-value-correction/Zkl/p-value-correction-2.zkl
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
pvalues:=T(
|
||||
4.533744e-01, 7.296024e-01, 9.936026e-02, 9.079658e-02, 1.801962e-01,
|
||||
8.752257e-01, 2.922222e-01, 9.115421e-01, 4.355806e-01, 5.324867e-01,
|
||||
4.926798e-01, 5.802978e-01, 3.485442e-01, 7.883130e-01, 2.729308e-01,
|
||||
8.502518e-01, 4.268138e-01, 6.442008e-01, 3.030266e-01, 5.001555e-02,
|
||||
3.194810e-01, 7.892933e-01, 9.991834e-01, 1.745691e-01, 9.037516e-01,
|
||||
1.198578e-01, 3.966083e-01, 1.403837e-02, 7.328671e-01, 6.793476e-02,
|
||||
4.040730e-03, 3.033349e-04, 1.125147e-02, 2.375072e-02, 5.818542e-04,
|
||||
3.075482e-04, 8.251272e-03, 1.356534e-03, 1.360696e-02, 3.764588e-04,
|
||||
1.801145e-05, 2.504456e-07, 3.310253e-02, 9.427839e-03, 8.791153e-04,
|
||||
2.177831e-04, 9.693054e-04, 6.610250e-05, 2.900813e-02, 5.735490e-03);
|
||||
|
||||
bh(pvalues) : format(_,"\nBenjamini-Hochberg");
|
||||
by(pvalues) : format(_,"\nBenjamini & Yekutieli");
|
||||
bonferroni(pvalues) : format(_,"\nBonferroni");
|
||||
hochberg(pvalues) : format(_,"\nHochberg");
|
||||
hommel(pvalues) : format(_,"\nHommel");
|
||||
|
||||
fcn format(list,title){
|
||||
print(title,":");
|
||||
foreach n in ([1..list.len(),5]){
|
||||
print("\n[%2d]:".fmt(n));
|
||||
foreach x in (list[n-1,5]){ print(" %.6e".fmt(x)) }
|
||||
}
|
||||
println();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue