我正在尝试将excel电子表格中的内容转换为Javascript,并在电子表格中使用了NORMSINV()宏。
NormSInv()很好地记录在http://office.microsoft.com/en-us/excel-help/normsinv-HP005209195.aspx。基本上它是形式 Z = NormSInv(概率),如果给它概率(比如0.90),它给出标准正态分布的Z值(Z = 1.33)。
我可以根据http://en.wikipedia.org/wiki/Standard_normal_table编码整个转换表,但是要避免重新发明轮子。
那么,Javascript中是否有这样的功能?例如。在Javascript的数学库中(如果有这样的东西!)。
由于 SID
答案 0 :(得分:7)
我不知道嵌入JavaScript的核心内容。
您可能想看一下JStat JavaScript library。这似乎为统计计算提供了一系列功能。
答案 1 :(得分:6)
我最终在javascript中实现了NormSInv()。当我只需要一个函数时,包含整个统计库是没有意义的
function NormSInv(p) {
var a1 = -39.6968302866538, a2 = 220.946098424521, a3 = -275.928510446969;
var a4 = 138.357751867269, a5 = -30.6647980661472, a6 = 2.50662827745924;
var b1 = -54.4760987982241, b2 = 161.585836858041, b3 = -155.698979859887;
var b4 = 66.8013118877197, b5 = -13.2806815528857, c1 = -7.78489400243029E-03;
var c2 = -0.322396458041136, c3 = -2.40075827716184, c4 = -2.54973253934373;
var c5 = 4.37466414146497, c6 = 2.93816398269878, d1 = 7.78469570904146E-03;
var d2 = 0.32246712907004, d3 = 2.445134137143, d4 = 3.75440866190742;
var p_low = 0.02425, p_high = 1 - p_low;
var q, r;
var retVal;
if ((p < 0) || (p > 1))
{
alert("NormSInv: Argument out of range.");
retVal = 0;
}
else if (p < p_low)
{
q = Math.sqrt(-2 * Math.log(p));
retVal = (((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) / ((((d1 * q + d2) * q + d3) * q + d4) * q + 1);
}
else if (p <= p_high)
{
q = p - 0.5;
r = q * q;
retVal = (((((a1 * r + a2) * r + a3) * r + a4) * r + a5) * r + a6) * q / (((((b1 * r + b2) * r + b3) * r + b4) * r + b5) * r + 1);
}
else
{
q = Math.sqrt(-2 * Math.log(1 - p));
retVal = -(((((c1 * q + c2) * q + c3) * q + c4) * q + c5) * q + c6) / ((((d1 * q + d2) * q + d3) * q + d4) * q + 1);
}
return retVal;
}
答案 2 :(得分:0)
我将jStat.distribution.normal.inv
提取到一个独立的函数中,可以将其作为webpack的闭包使用(或单独使用)。
import normalinv from 'jsfile'
let yourMath = normalinv()
或
var yourMath = normalinv();
yourMath(p, m, d)
export default function normalinv() {
function erfcinv(p) {
var j = 0;
var x, err, t, pp;
if (p >= 2)
return -100;
if (p <= 0)
return 100;
pp = (p < 1) ? p : 2 - p;
t = Math.sqrt(-2 * Math.log(pp / 2));
x = -0.70711 * ((2.30753 + t * 0.27061) /
(1 + t * (0.99229 + t * 0.04481)) - t);
for (; j < 2; j++) {
err = erfc(x) - pp;
x += err / (1.12837916709551257 * Math.exp(-x * x) - x * err);
}
return (p < 1) ? x : -x;
}
function erfc(x) {
return 1 - erf(x);
}
function erf(x) {
var cof = [-1.3026537197817094, 6.4196979235649026e-1, 1.9476473204185836e-2,
-9.561514786808631e-3, -9.46595344482036e-4, 3.66839497852761e-4,
4.2523324806907e-5, -2.0278578112534e-5, -1.624290004647e-6,
1.303655835580e-6, 1.5626441722e-8, -8.5238095915e-8,
6.529054439e-9, 5.059343495e-9, -9.91364156e-10,
-2.27365122e-10, 9.6467911e-11, 2.394038e-12,
-6.886027e-12, 8.94487e-13, 3.13092e-13,
-1.12708e-13, 3.81e-16, 7.106e-15,
-1.523e-15, -9.4e-17, 1.21e-16,
-2.8e-17
];
var j = cof.length - 1;
var isneg = false;
var d = 0;
var dd = 0;
var t, ty, tmp, res;
if (x < 0) {
x = -x;
isneg = true;
}
t = 2 / (2 + x);
ty = 4 * t - 2;
for (; j > 0; j--) {
tmp = d;
d = ty * d - dd + cof[j];
dd = tmp;
}
res = t * Math.exp(-x * x + 0.5 * (cof[0] + ty * d) - dd);
return isneg ? res - 1 : 1 - res;
}
return function inv(p, mean, std) {
return -1.41421356237309505 * std * erfcinv(2 * p) + mean;
}
}