11/*
22 * Mathlib : A C Library of Special Functions
3+ * Copyright (C) 2000-2021 The R Core Team
34 * Copyright (C) 1998 Ross Ihaka
4- * Copyright (C) 2000-12 The R Core Team
55 *
66 * This program is free software; you can redistribute it and/or modify
77 * it under the terms of the GNU General Public License as published by
@@ -56,10 +56,6 @@ double dnbeta(double x, double a, double b, double ncp, int give_log)
5656{
5757 const static double eps = 1.e-15 ;
5858
59- int kMax ;
60- double k , ncp2 , dx2 , d , D ;
61- LDOUBLE sum , term , p_k , q ;
62-
6359#ifdef IEEE_754
6460 if (ISNAN (x ) || ISNAN (a ) || ISNAN (b ) || ISNAN (ncp ))
6561 return x + a + b + ncp ;
@@ -74,18 +70,21 @@ double dnbeta(double x, double a, double b, double ncp, int give_log)
7470 if (ncp == 0 )
7571 return dbeta (x , a , b , give_log );
7672
77- /* New algorithm, starting with *largest* term : */
78- ncp2 = 0.5 * ncp ;
79- dx2 = ncp2 * x ;
80- d = (dx2 - a - 1 )/2 ;
81- D = d * d + dx2 * (a + b ) - a ;
73+ /* Non-central Beta: New algorithm, starting with *largest* term : */
74+ double
75+ ncp2 = ldexp (ncp , -1 ), // = 0.5 * ncp
76+ dx2 = ncp2 * x ,
77+ d = ldexp (dx2 - a - 1 , -1 ), // = (...)/2
78+ D = d * d + dx2 * (a + b ) - a ;
79+ int kMax ;
8280 if (D <= 0 ) {
8381 kMax = 0 ;
8482 } else {
8583 D = ceil (d + sqrt (D ));
8684 kMax = (D > 0 ) ? (int )D : 0 ;
8785 }
8886
87+ LDOUBLE sum , term , p_k , q ;
8988 /* The starting "middle term" --- first look at it's log scale: */
9089 term = dbeta (x , a + kMax , b , /* log = */ TRUE);
9190 p_k = dpois_raw (kMax , ncp2 , TRUE);
@@ -101,7 +100,7 @@ double dnbeta(double x, double a, double b, double ncp, int give_log)
101100 /* Now sum from the inside out */
102101 sum = term = 1. /* = mid term */ ;
103102 /* middle to the left */
104- k = kMax ;
103+ double k = kMax ;
105104 while (k > 0 && term > sum * eps ) {
106105 k -- ;
107106 q = /* 1 / r_k = */ (k + 1 )* (k + a ) / (k + a + b ) / dx2 ;
0 commit comments