1.计算卡方值和P值2.伽马函数3.不完全伽马函数
1.计算卡方值和P值
P值就是计算卡方分布的分布函数值,公式如下:
F(x;k)=γ(k2,x2)Γ(k2)=P(k2,x2) F ( x ; k ) = γ ( k 2 , x 2 ) Γ ( k 2 ) = P ( k 2 , x 2 )
其中,分子为不完全伽马函数,分母为伽马函数。
/** * 计算卡方值和P值 * @description */public class ChiSquareAndPValue { /** * 自由度v=(行数-1)(列数-1) * @param rowNum * @param columnNum * @return */ public static int degreeOfFreedomValue(int rowNum, int columnNum) { if (rowNum < 0 || columnNum < 0) { return 0; } return (rowNum – 1) * (columnNum – 1); } /** * 四格表格式计算卡方值 * 卡方值=n(ad-bc)^2/(a+b)(c+d)(a+c)(b+d) */ public static double chisquareValue(int a, int b, int c, int d) { if (a < 1 || b < 1 || c < 1 || d < 1) { return 0; } int n = a + b + c + d; double f = n * Math.pow((a * d – b * c), 2); double m = (a + b) * (c + d) * (a + c) * (b + d); double s = f / m; return s; } /** * 根据自由度和卡方值计算P值 * @param dof 自由度 * @param chi_squared 卡方值 * @return */ public static double chisqr2pValue(int dof, double chi_squared) { if (chi_squared < 0 || dof < 1) { return 0.0; } double k = ((double) dof) * 0.5; double v = chi_squared * 0.5; if (dof == 2) { return Math.exp(-1.0 * v); } double incompleteGamma = IncompleteGamma.log_igf(k, v); // 如果过小或者非数值或者无穷 if (Math.exp(incompleteGamma) <= 1e-8 || Double.isNaN(Math.exp(incompleteGamma)) || Double.isInfinite(Math.exp(incompleteGamma))) { return 1e-14; } double gamma = Math.log(Gamma.getApproxGamma(k)); incompleteGamma -= gamma; if (Math.exp(incompleteGamma) > 1) { return 1e-14; } double pValue = 1.0 – Math.exp(incompleteGamma); return (double) pValue; }} 2.伽马函数
斯特灵求伽马函数的近似公式:
Γ(z)≈2πz−−−√(1e(z+112z−110z))z Γ ( z ) ≈ 2 π z ( 1 e ( z + 1 12 z − 1 10 z ) ) z
public class Gamma { /** * 求伽马函数的近似公式 * @param n * @return */ public static double getApproxGamma(double n) { // RECIP_E = (E^-1) = (1.0 / E) double RECIP_E = 0.36787944117144232159552377016147; // TWOPI = 2.0 * PI double TWOPI = 6.283185307179586476925286766559; double d = 1.0 / (10.0 * n); d = 1.0 / ((12* n) – d); d = (d + n) *RECIP_E; d = Math.pow(d,n); d *= Math.sqrt(TWOPI/ n); return d; }} 3.不完全伽马函数
不完全伽马函数计算公式:
γ(s,z)=s−1zse−zM(1,s+1,z) γ ( s , z ) = s 快3导师群 double TWOPI = 6.283185307179586476925286766559; double d = 1.0 / (10.0 * n); d = 1.0 / ((12* n) – d); d = (d + n) *RECIP_E; d = Math.pow(d,n); d *= Math.sqrt(TWOPI/ n); return d; }} 3.不完全伽马函数
不完全伽马函数计算公式:
γ(s,z)=s−1zse−zM(1,s+1,z) γ ( s , z ) = s − 1 z s e − z M ( 1 , s + 1 , z )
其中M函数是合连几何函数,计算公式:
M(1,s+1,z)=1+zs+1+z2(s+1)(s+2)+z3(s+1)(s+2)(s+3)+⋯ M ( 1 , s + 1 , z ) = 1 + z s + 1 + z 2 ( s + 1 ) ( s + 2 ) + z 3 ( s + 1 ) ( s + 2 ) ( s + 3 ) + ⋯
public class IncompleteGamma { /** * 不完全伽马函数 * @param s * @param z * @return */ public static double log_igf(double s, double z) { if (z < 0.0) { return 0.0; } double sc = (Math.log(z) * s) – z – Math.log(s); double k = KM(s, z); return Math.log(k) + sc; } private static double KM(double s, double z) { double sum = 1.0; double nom = 1.0; double denom = 1.0; double log_nom = Math.log(nom); double log_denom = Math.log(denom); double log_s = Math.log(s); double log_z = Math.log(z); for (int i = 0; i < 1000; ++i) { log_nom += log_z; s++; log_s = Math.log(s); log_denom += log_s; double log_sum = log_nom – log_denom; sum += Math.exp(log_sum); } return sum; } }
本文参考:
卡方检验值转换为P值