/* * Concept profile generation tool suite * Copyright (C) 2015 Biosemantics Group, Erasmus University Medical Center, * Rotterdam, The Netherlands * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published * by the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.erasmusmc.math; public class ChiSquaredProbabilityFunction { static public double chiSquaredProbabilityFunction(double chiSquared, int degreesOfFreedom){ double factor; // factor which multiplies sum of series double g; // lngamma(k1+1) double k1; // adjusted degrees of freedom double sum; // temporary storage for partial sums double term; // term of series double x1; // adjusted argument of funtion double chi2prob; // chi-squared probability // the distribution function of the chi-squared distribution based on k d.f. if ((chiSquared < 0.01) || (chiSquared > 1000.0)){ if (chiSquared < 0.01){ chi2prob = 0.0001; } else { chi2prob = 0.999999; } } else{ x1 = 0.5 * chiSquared; k1 = 0.5 * degreesOfFreedom; g = gammaLN(k1 + 1); factor = Math.exp(k1 * Math.log(x1) - g - x1); sum = 0.0; if (factor > 0) { term = 1.0; sum = 1.0; while ((term / sum) > 0.000001) { k1 = k1 + 1; term = term * (x1 / k1); sum = sum + term; } } chi2prob = sum * factor; } //end if .. else return (1-chi2prob); } protected static double gammaLN(double input){ double X, tmp, ser; double[] cof = new double[6]; int j; cof[0] = 76.18009173; cof[1] = -86.50532033; cof[2] = 24.01409822; cof[3] = -1.231739516; cof[4] = 0.00120858003; cof[5] = -0.00000536382; X = input - 1.0; tmp = X + 5.5; tmp = tmp - ((X + 0.5) * Math.log(tmp)); ser = 1.0; for (j = 0;j<=5;j++){ X = X + 1.0; ser = ser + cof[j] / X; } return ( -tmp + Math.log(2.50662827465 * ser) ); } }