如何在C/C++中将百分比转换为正态分布的z分数



目标是说:"这些值位于正态分布中平均值周围值的95%的范围内">

现在,我正在尝试将百分比转换为z分数,这样我就可以得到精确的值范围。像<lower bound , upper bound>这样的东西就足够了。

所以我需要像这样的东西

double z_score(double percentage) {
// ...
}
// ...
// according to https://en.wikipedia.org/wiki/68–95–99.7_rule
z_score(68.27) == 1
z_score(95.45) == 2
z_score(99.73) == 3

我发现一篇文章解释了如何使用boost库中的函数来实现这一点,但

double z_score( double percentage ) {
return - sqrt( 2 ) / boost::math::erfc_inv( 2 * percentage / 100 );
}

工作不正常,并且返回奇怪的值。

z_score(95) == 1.21591 // instead of 1.96

此外,boost库有点重,我计划将其用于Ruby gem,所以它应该尽可能轻。

有人有主意吗?

我说你是"足够接近";。

#include <iostream>
#include <boost/math/special_functions/erf.hpp>
#include <cmath>
double z_score(double percentage) {
return sqrt(2) * boost::math::erf_inv(percentage / 100);
}
int main() {
#define _(x)  std::cout << x << " " << z_score(x) << "n"
_(68.27);
_(95.45);
_(99.73);
}

输出:

68.27 1.00002
95.45 2
99.73 2.99998

我不知道你是怎么把-放在前面的,它是erf>>c<<_inv,它是被sqrt(2)除以的

p <- this is probability, ie. your input
u <- mean value
o <- std dev
n <- the count of std deviations from mean, ie. 1, 2, 3 etc.
p = F(u + no) - F(u + no) = fi(n) - fi(-n) = erf(n / sqrt(2))
p = erf(n / sqrt(2))
erf_inv(p) = n / sqrt(2)
erf_inv(p) * sqrt(2) = n
n = sqrt(2) * erf_inv(p)

此外,boost库的有点重

5分钟的搜索产生了这个和这个C实现erf_inv

最新更新