home *** CD-ROM | disk | FTP | other *** search
- (*-------------------------------------------------------------------------*)
- (* CDBeta -- Cumulative Beta Distribution *)
- (*-------------------------------------------------------------------------*)
-
- FUNCTION CDBeta( X, Alpha, Beta: REAL;
- Dprec, MaxIter : INTEGER;
- VAR Cprec : REAL;
- VAR Iter : INTEGER;
- VAR Ifault : INTEGER ) : REAL;
-
- (*-------------------------------------------------------------------------*)
- (* *)
- (* Function: CDBeta *)
- (* *)
- (* Purpose: Evaluates CPDF of Incomplete Beta Function *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* P := CDBeta( X, Alpha, Beta: REAL; *)
- (* Dprec, Maxitr : INTEGER; *)
- (* VAR Cprec : REAL; *)
- (* VAR Iter : INTEGER; *)
- (* VAR Ifault : INTEGER ) : REAL; *)
- (* *)
- (* X --- Upper percentage point of PDF *)
- (* Alpha --- First shape parameter *)
- (* Beta --- Second shape parameter *)
- (* Dprec --- Number of digits of precision required *)
- (* Maxitr --- Maximum number of iterations *)
- (* Cprec --- Actual resulting precision *)
- (* Iter --- Iterations actually used *)
- (* Ifault --- error indicator *)
- (* = 0: no error *)
- (* = 1: argument error *)
- (* *)
- (* P --- Resultant probability *)
- (* *)
- (* Calls: *)
- (* *)
- (* ALGama *)
- (* *)
- (* Method: *)
- (* *)
- (* The continued fraction expansion as given by *)
- (* Abramowitz and Stegun (1964) is used. This *)
- (* method works well unless the minimum of (Alpha, Beta) *)
- (* exceeds about 70000. *)
- (* *)
- (* An error in the input arguments results in a returned *)
- (* probability of -1. *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- VAR
- Epsz : REAL;
- A : REAL;
- B : REAL;
- C : REAL;
- F : REAL;
- Fx : REAL;
- Apb : REAL;
- Zm : REAL;
- Alo : REAL;
- Ahi : REAL;
- Blo : REAL;
- Bhi : REAL;
- Bod : REAL;
- Bev : REAL;
- Zm1 : REAL;
- D1 : REAL;
- Aev : REAL;
- Aod : REAL;
-
- Ntries : INTEGER;
-
- Qswap : BOOLEAN;
- Qdoit : BOOLEAN;
- Qconv : BOOLEAN;
-
- LABEL 20, 9000;
-
- BEGIN (* CdBeta *)
-
- (* Initialize *)
- IF Dprec > MaxPrec THEN
- Dprec := MaxPrec
- ELSE IF Dprec <= 0 THEN
- Dprec := 1;
-
- Cprec := Dprec;
-
- Epsz := PowTen( -Dprec );
-
- X := X;
- A := Alpha;
- B := Beta;
- QSwap := FALSE;
- CDBeta := -1.0;
- Qdoit := TRUE;
- (* Check arguments *)
- (* Error if: *)
- (* X <= 0 *)
- (* A <= 0 *)
- (* B <= 0 *)
-
- Ifault := 1;
-
- IF( X <= 0.0 ) THEN GOTO 9000;
-
- IF( ( A <= 0.0 ) OR ( B <= 0.0 ) ) THEN GOTO 9000;
-
- CDBeta := 1.0;
- Ifault := 0;
- (* If X >= 1, return 1.0 as prob *)
-
- IF( X >= 1.0 ) THEN GOTO 9000;
-
- (* If X > A / ( A + B ) then swap *)
- (* A, B for more efficient eval. *)
-
- IF( X > ( A / ( A + B ) ) ) THEN
- BEGIN
- X := 1.0 - X;
- A := Beta;
- B := Alpha;
- QSwap := TRUE;
- END;
-
- (* Check for extreme values *)
-
- IF( ( X = A ) OR ( X = B ) ) THEN GOTO 20;
- IF( A = ( ( B * X ) / ( 1.0 - X ) ) ) THEN GOTO 20;
- IF( ABS( A - ( X * ( A + B ) ) ) <= Epsz ) THEN GOTO 20;
-
- C := ALGama( A + B ) + A * LN( X ) +
- B * LN( 1.0 - X ) - ALGama( A ) - ALGama( B ) -
- LN( A - X * ( A + B ) );
-
- IF( ( C < -36.0 ) AND QSwap ) THEN GOTO 9000;
-
- CDBeta := 0.0;
- IF( C < -180.0 ) THEN GOTO 9000;
-
- (* Set up continued fraction expansion *)
- (* evaluation. *)
-
- 20:
- Apb := A + B;
- Zm := 0.0;
- Alo := 0.0;
- Bod := 1.0;
- Bev := 1.0;
- Bhi := 1.0;
- Blo := 1.0;
-
- Ahi := EXP( ALGama( Apb ) + A * LN( X ) +
- B * LN( 1.0 - X ) - ALGama( A + 1.0 ) -
- ALGama( B ) );
-
- F := Ahi;
-
- Iter := 0;
-
- (* Continued fraction loop begins here. *)
- (* Evaluation continues until maximum *)
- (* iterations are exceeded, or *)
- (* convergence achieved. *)
-
- Qconv := FALSE;
-
- REPEAT
-
- Fx := F;
-
- Zm1 := Zm;
- Zm := Zm + 1.0;
- D1 := A + Zm + Zm1;
- Aev := -( A + Zm1 ) * ( Apb + Zm1 ) * X / D1 / ( D1 - 1.0 );
- Aod := Zm * ( B - Zm ) * X / D1 / ( D1 + 1.0 );
- Alo := Bev * Ahi + Aev * Alo;
- Blo := Bev * Bhi + Aev * Blo;
- Ahi := Bod * Alo + Aod * Ahi;
- Bhi := Bod * Blo + Aod * Bhi;
-
- IF ABS( Bhi ) < Rsmall THEN Bhi := 0.0;
-
- IF( Bhi <> 0.0 ) THEN
- BEGIN
- F := Ahi / Bhi;
- Qconv := ( ABS( ( F - Fx ) / F ) < Epsz );
- END;
-
- Iter := Iter + 1;
-
- UNTIL ( ( Iter > MaxIter ) OR Qconv ) ;
-
- (* Arrive here when convergence *)
- (* achieved, or maximum iterations *)
- (* exceeded. *)
-
- IF ( Qswap ) THEN
- CDBeta := 1.0 - F
- ELSE
- CDBeta := F;
-
- (* Calculate precision of result *)
-
- IF ABS( F - Fx ) <> 0.0 THEN
- Cprec := -LogTen( ABS( F - Fx ) )
- ELSE
- Cprec := MaxPrec;
-
- 9000: (* Error exit *)
-
- END (* CDBeta *);