home *** CD-ROM | disk | FTP | other *** search
- (*-------------------------------------------------------------------------*)
- (* GammaIn -- Incomplete Gamma integral *)
- (*-------------------------------------------------------------------------*)
-
- FUNCTION GammaIn( Y, P : REAL;
- Dprec : INTEGER;
- MaxIter : INTEGER;
- VAR Cprec : REAL;
- VAR Iter : INTEGER;
- VAR Ifault : INTEGER ) : REAL;
-
- (*-------------------------------------------------------------------------*)
- (* *)
- (* Function: GammaIn *)
- (* *)
- (* Purpose: Evaluates Incomplete Gamma integral *)
- (* *)
- (* Calling Sequence: *)
- (* *)
- (* P := GammaIn( Y, P : REAL; *)
- (* Dprec : INTEGER; *)
- (* MaxIter : INTEGER; *)
- (* VAR Cprec : REAL; *)
- (* VAR Iter : INTEGER; *)
- (* VAR Ifault : INTEGER ) : REAL; *)
- (* *)
- (* Y --- Gamma distrib. value *)
- (* P --- Degrees of freedom *)
- (* Ifault --- error indicator *)
- (* *)
- (* P --- Resultant probability *)
- (* *)
- (* Calls: *)
- (* *)
- (* None *)
- (* *)
- (* Remarks: *)
- (* *)
- (* Either an infinite series summation or a continued fraction *)
- (* approximation is used, depending upon the argument range. *)
- (* *)
- (*-------------------------------------------------------------------------*)
-
- CONST
- Oflo = 1.0E+37;
- MinExp = -87.0;
-
- VAR
- F: REAL;
- C: REAL;
- A: REAL;
- B: REAL;
- Term: REAL;
- Pn: ARRAY[1..6] OF REAL;
- Gin: REAL;
- An: REAL;
- Rn: REAL;
- Dif: REAL;
- Eps: REAL;
- Done: BOOLEAN;
-
- LABEL 9000;
-
- BEGIN (* GammaIn *)
- (* Check arguments *)
- Ifault := 1;
- GammaIn := 1.0;
-
- IF( ( Y <= 0.0 ) OR ( P <= 0.0 ) ) THEN GOTO 9000;
-
- (* Check value of F *)
- Ifault := 0;
- F := P * LN( Y ) - ALGama( P + 1.0 ) - Y;
- IF ( F < MinExp ) THEN GOTO 9000;
-
- F := EXP( F );
- IF( F = 0.0 ) THEN GOTO 9000;
-
- (* Set precision *)
- IF Dprec > MaxPrec THEN
- Dprec := MaxPrec
- ELSE IF Dprec <= 0 THEN
- Dprec := 1;
-
- Cprec := Dprec;
-
- Eps := PowTen( -Dprec );
-
- (* Choose infinite series or *)
- (* continued fraction. *)
-
- IF( ( Y > 1.0 ) AND ( Y >= P ) ) THEN
-
- BEGIN (* Continued Fraction *)
-
- A := 1.0 - P;
- B := A + Y + 1.0;
- Term := 0.0;
- Pn[ 1 ] := 1.0;
- Pn[ 2 ] := Y;
- Pn[ 3 ] := Y + 1.0;
- Pn[ 4 ] := Y * B;
- Gin := Pn[ 3 ] / Pn[ 4 ];
- Done := FALSE;
- Iter := 0;
-
- REPEAT
-
- Iter := Iter + 1;
- A := A + 1.0;
- B := B + 2.0;
- Term := Term + 1.0;
- An := A * Term;
-
- Pn[ 5 ] := B * Pn[ 3 ] - An * Pn[ 1 ];
- Pn[ 6 ] := B * Pn[ 4 ] - An * Pn[ 2 ];
-
- IF( Pn[ 6 ] <> 0.0 ) THEN
- BEGIN
-
- Rn := Pn[ 5 ] / Pn[ 6 ];
- Dif := ABS( Gin - Rn );
-
- IF( Dif <= Eps ) THEN
- IF( Dif <= ( Eps * Rn ) ) THEN Done := TRUE;
-
- Gin := Rn;
-
- END;
-
- Pn[ 1 ] := Pn[ 3 ];
- Pn[ 2 ] := Pn[ 4 ];
- Pn[ 3 ] := Pn[ 5 ];
- Pn[ 4 ] := Pn[ 6 ];
-
- IF( ABS( Pn[ 5 ] ) >= Oflo ) THEN
- BEGIN
- Pn[ 1 ] := Pn[ 1 ] / Oflo;
- Pn[ 2 ] := Pn[ 2 ] / Oflo;
- Pn[ 3 ] := Pn[ 3 ] / Oflo;
- Pn[ 4 ] := Pn[ 4 ] / Oflo;
- END;
-
- UNTIL ( Iter > MaxIter ) OR Done;
-
- Gin := 1.0 - ( F * Gin * P );
-
- GammaIn := Gin;
- (* Calculate precision of result *)
-
- IF Dif <> 0.0 THEN
- Cprec := -LogTen( Dif )
- ELSE
- Cprec := MaxPrec;
-
- END (* Continued Fraction *)
-
- ELSE
-
- BEGIN (* Infinite series *)
-
- Iter := 0;
-
- Term := 1.0;
- C := 1.0;
- A := P;
- Done := FALSE;
-
- REPEAT
-
- A := A + 1.0;
- Term := Term * Y / A;
- C := C + Term;
-
- Iter := Iter + 1;
-
- UNTIL ( Iter > MaxIter ) OR ( ( Term / C ) <= Eps );
-
- GammaIn := C * F;
- (* Calculate precision of result *)
-
- Cprec := -LogTen( Term / C );
-
- END (* Infinite series *);
-
- 9000: (* Error exit *)
-
- END (* GammaIn *);