/** * * tncCdf.java * * Copyright(c) Visual Numerics, Inc. 2000 * */ package com.imsl.demo.Samples; import com.imsl.stat.Cdf; import com.imsl.math.JMath; import com.imsl.math.Sfun; // (defun tnc-cdf (T1 DF DELTA &key print (ifault 0) (tol .00001) (count-limit 40)) // "Args: (T1, DF, DELTA, print) // Translated from XLISP-STAT, FROM FORTRAN IN // << ALGORITHM AS 243 APPL. STATIST. (1989), VOL.38, NO. 1 // Cumulative probability at T of the non-central t-distribution // with DF degrees of freedom (may be fractional) and non-centrality // parameter DELTA. >> Vectorized." /** * * @author Gregory D. Rodd * @created October 20, 2002 */ public final class tncCdf { final static double R2PI = 1.0 / (Sfun.gamma(1.5) * JMath.sqrt(2.0)); final static double ITRMAX = 100.1; final static double ERRMAX = 1.0e-06 ; final static double ALNRPI = JMath.log(JMath.sqrt(JMath.PI)); // @return double; // @param t double; // @param df double; // @param delt double; public static double cdf(double t, double df, double delt) { boolean NEGDEL = (t < 0.0); double TT = (NEGDEL ? -1.0 * t : t); double DEL = (NEGDEL ? -1.0 * delt : delt); double ERRBD = 0.0; int IFAULT = 2; // C // C Initialize twin series (Guenther, J. Statist. Computn. Simuln. // C vol.6, 199, 1978). // C double EN = 1.0; double x = t * t / (t * t + df); double lmda = DEL * DEL; double P = 0.5 * JMath.exp(-0.5 * lmda); double Q = R2PI * P * DEL; double S = 0.5 - P; double A = 0.5; double B = 0.5 * df; double RXB = JMath.pow(1.0 - x, B); double ALBETA = ALNRPI + Sfun.logGamma(B) - Sfun.logGamma(0.5 + B); double XODD = Cdf.beta(x, 0.5, B); double GODD = 2.0 * RXB * JMath.exp(A * JMath.log(x) - ALBETA); double XEVEN = 1.0 - RXB; double GEVEN = B * x * RXB; double TNC = P * XODD + Q * XEVEN; do { A = A + 1.0; XODD = XODD - GODD; XEVEN = XEVEN - GEVEN; GODD = GODD * x * (A + B - 1.0) / A; GEVEN = GEVEN * x * (A + B - 0.5) / (A + 0.5); P = P * lmda / (2.0 * EN); Q = Q * lmda / ((2.0 * EN) + 1); S = S - P; EN += 1.0; TNC = TNC + P * XODD + Q * XEVEN; ERRBD = 2.0 * S * (XODD - GODD); } while( (ERRBD > ERRMAX) && (EN < ITRMAX) ); IFAULT = 1; if (EN > ITRMAX) { // TNC = Nan; IFAULT = 1; return Double.NaN; } else { IFAULT = 0; // Add on the UPPER tail of the normal TNC = TNC + (1.0 - Cdf.normal(DEL)); return (NEGDEL) ? 1.0 - TNC : TNC; } } }