Zum Hauptinhalt springen
clawam tools
Werkzeuge Dokumente Daoark EN Startseite Startseite / Calculadora › Startseite manifest.json 0; }).map(function(x) { return parseFloat(x); }).filter(function(x) { return !isNaN(x); }); } function parseMatrix(text) { var lines = text.split('\n').filter(function(l) { return l.trim().length > 0; }); return lines.map(function(l) { return parseNums(l); }).filter(function(r) { return r.length > 0; }); } // log Γ function logGamma(x) { var g = 7; var c = [0.99999999999980993, 676.5203681218851, -1259.1392167224028, 771.32342877765313, -176.61502916214059, 12.507343278686905, -0.13857109526572012, 9.9843695780195716e-6, 1.5056327351493116e-7]; if (x < 0.5) return Math.log(Math.PI / Math.sin(Math.PI * x)) - logGamma(1 - x); x -= 1; var a = c[0]; var t = x + g + 0.5; for (var i = 1; i < g + 2; i++) a += c[i] / (x + i); return 0.5 * Math.log(2 * Math.PI) + (x + 0.5) * Math.log(t) - t + Math.log(a); } // 不完全 gamma(下限) P(a, x) function gammaSeries(a, x) { var ITMAX = 300, EPS = 1e-12; if (x <= 0) return 0; var ap = a; var sum = 1 / a; var del = sum; for (var n = 1; n <= ITMAX; n++) { ap += 1; del *= x / ap; sum += del; if (Math.abs(del) < Math.abs(sum) * EPS) break; } return sum * Math.exp(-x + a * Math.log(x) - logGamma(a)); } function gammaContinued(a, x) { var ITMAX = 300, EPS = 1e-12, FPMIN = 1e-300; var b = x + 1 - a; var c = 1 / FPMIN; var d = 1 / b; var h = d; for (var i = 1; i <= ITMAX; i++) { var an = -i * (i - a); b += 2; d = an * d + b; if (Math.abs(d) < FPMIN) d = FPMIN; c = b + an / c; if (Math.abs(c) < FPMIN) c = FPMIN; d = 1 / d; var del = d * c; h *= del; if (Math.abs(del - 1) < EPS) break; } return Math.exp(-x + a * Math.log(x) - logGamma(a)) * h; } // P(a, x) = γ(a, x) / Γ(a) function gammaP(a, x) { if (x < 0 || a <= 0) return NaN; if (x < a + 1) return gammaSeries(a, x); return 1 - gammaContinued(a, x); } // p-value for chi-square: P(χ² > x) = 1 - P(df/2, x/2) = Q(df/2, x/2) function chiSquareP(x, df) { if (x <= 0) return 1; return 1 - gammaP(df / 2, x / 2); } function doProcess() { try { var op = getVal('op'); var alpha = parseFloat(getVal('alpha')); var chi2, df, p; var out = ''; if (op === 'goodness') { var obs = parseNums(getVal('obs')); if (obs.length < 2) { showError('观测值至少 2 个'); return; } var expStr = getVal('exp').trim(); var exp; if (expStr) { exp = parseNums(expStr); if (exp.length !== obs.length) { showError('期望值个数(' + exp.length + ') ≠ 观测值个数(' + obs.length + ')'); return; } } else { var sumObs = obs.reduce(function(s, x) { return s + x; }, 0); var uniform = sumObs / obs.length; exp = obs.map(function() { return uniform; }); } chi2 = 0; for (var i = 0; i < obs.length; i++) { if (exp[i] < 5) out += ' 期望值 ' + exp[i].toFixed(2) + ' < 5,建议加大样本或合并类别\n'; chi2 += Math.pow(obs[i] - exp[i], 2) / exp[i]; } df = obs.length - 1; p = chiSquareP(chi2, df); out += 'χ² = ' + chi2.toFixed(4) + '\ndf = ' + df + '\np = ' + p.toFixed(6) + (p < 1e-4 ? ' (< 0.0001)' : '') + '\n结论: ' + (p < alpha ? '拒绝 H₀(分布不符合期望)' : '不拒绝 H₀(无显著差异)'); } else { var mat = parseMatrix(getVal('table')); if (mat.length < 2) { showError('列联表至少 2 行'); return; } var nCols = mat[0].length; for (var i = 1; i < mat.length; i++) if (mat[i].length !== nCols) { showError('每行等长'); return; } var rowSums = mat.map(function(r) { return r.reduce(function(s, x) { return s + x; }, 0); }); var colSums = []; for (var j = 0; j < nCols; j++) { var s = 0; for (var i = 0; i < mat.length; i++) s += mat[i][j]; colSums.push(s); } var total = rowSums.reduce(function(s, x) { return s + x; }, 0); if (total === 0) { showError('总数为 0'); return; } chi2 = 0; for (var i = 0; i < mat.length; i++) { for (var j = 0; j < nCols; j++) { var e = rowSums[i] * colSums[j] / total; if (e < 5) out += ' 期望 ' + e.toFixed(2) + ' < 5 @ (' + i + ',' + j + ')\n'; if (e > 0) chi2 += Math.pow(mat[i][j] - e, 2) / e; } } df = (mat.length - 1) * (nCols - 1); p = chiSquareP(chi2, df); out += 'χ² = ' + chi2.toFixed(4) + '\ndf = (r-1)(c-1) = ' + df + '\np = ' + p.toFixed(6) + (p < 1e-4 ? ' (< 0.0001)' : '') + '\n结论: ' + (p < alpha ? '拒绝 H₀(变量不独立)' : '不拒绝 H₀(无显著关联)'); } showResult(out, op + ', α=' + alpha); } catch (e) { showError('计算失败: ' + (e.message || e)); } } var opEl = $('op'); function refreshGroup() { var isIndep = opEl.value === 'independence'; $('obs-group').style.display = isIndep ? 'none' : 'block'; $('exp-group').style.display = isIndep ? 'none' : 'block'; $('table-group').style.display = isIndep ? 'block' : 'none'; } opEl.addEventListener('change', refreshGroup); refreshGroup(); $('btn-main').addEventListener('click', function(e) { e.preventDefault(); doProcess(); }); $('btn-clear').addEventListener('click', function() { var inputs = document.querySelectorAll('input,textarea,select'); for (var i = 0; i < inputs.length; i++) { if (inputs[i].tagName === 'SELECT') inputs[i].selectedIndex = 0; else inputs[i].value = inputs[i].defaultValue; } refreshGroup(); var ra = $('result-area'); ra.hidden = true; ra.style.display = 'none'; var em = $('error-msg'); em.hidden = true; em.style.display = 'none'; }); })();