The R Project SVN R

Rev

Rev 68947 | Rev 80676 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 68947 Rev 70234
Line 4... Line 4...
4
 *    October 23, 2000 and Feb, 2001.
4
 *    October 23, 2000 and Feb, 2001.
5
 *
5
 *
6
 *    dnbinom_mu(): Martin Maechler, June 2008
6
 *    dnbinom_mu(): Martin Maechler, June 2008
7
 *
7
 *
8
 *  Merge in to R:
8
 *  Merge in to R:
9
 *	Copyright (C) 2000--2014, The R Core Team
9
 *	Copyright (C) 2000--2016, The R Core Team
10
 *
10
 *
11
 *  This program is free software; you can redistribute it and/or modify
11
 *  This program is free software; you can redistribute it and/or modify
12
 *  it under the terms of the GNU General Public License as published by
12
 *  it under the terms of the GNU General Public License as published by
13
 *  the Free Software Foundation; either version 2 of the License, or
13
 *  the Free Software Foundation; either version 2 of the License, or
14
 *  (at your option) any later version.
14
 *  (at your option) any later version.
Line 48... Line 48...
48
    R_D_nonint_check(x);
48
    R_D_nonint_check(x);
49
    if (x < 0 || !R_FINITE(x)) return R_D__0;
49
    if (x < 0 || !R_FINITE(x)) return R_D__0;
50
    /* limiting case as size approaches zero is point mass at zero */
50
    /* limiting case as size approaches zero is point mass at zero */
51
    if (x == 0 && size==0) return R_D__1;
51
    if (x == 0 && size==0) return R_D__1;
52
    x = R_forceint(x);
52
    x = R_forceint(x);
-
 
53
    if(!R_FINITE(size)) size = DBL_MAX;
53
 
54
 
54
    ans = dbinom_raw(size, x+size, prob, 1-prob, give_log);
55
    ans = dbinom_raw(size, x+size, prob, 1-prob, give_log);
55
    p = ((double)size)/(size+x);
56
    p = ((double)size)/(size+x);
56
    return((give_log) ? log(p) + ans : p * ans);
57
    return((give_log) ? log(p) + ans : p * ans);
57
}
58
}
58
 
59
 
59
double dnbinom_mu(double x, double size, double mu, int give_log)
60
double dnbinom_mu(double x, double size, double mu, int give_log)
60
{
61
{
61
    /* originally, just set  prob :=  size / (size + mu)  and called dbinom_raw(),
62
    /* originally, just set  prob :=  size / (size + mu)  and called dbinom_raw(),
62
     * but that suffers from cancellation when   mu << size  */
63
     * but that suffers from cancellation when   mu << size  */
63
    double ans, p;
-
 
64
 
64
 
65
#ifdef IEEE_754
65
#ifdef IEEE_754
66
    if (ISNAN(x) || ISNAN(size) || ISNAN(mu))
66
    if (ISNAN(x) || ISNAN(size) || ISNAN(mu))
67
        return x + size + mu;
67
        return x + size + mu;
68
#endif
68
#endif
Line 73... Line 73...
73
 
73
 
74
    /* limiting case as size approaches zero is point mass at zero,
74
    /* limiting case as size approaches zero is point mass at zero,
75
     * even if mu is kept constant. limit distribution does not
75
     * even if mu is kept constant. limit distribution does not
76
     * have mean mu, though.
76
     * have mean mu, though.
77
     */
77
     */
78
    if (x == 0 && size==0) return R_D__1;
78
    if (x == 0 && size == 0) return R_D__1;
79
 
-
 
80
    x = R_forceint(x);
79
    x = R_forceint(x);
-
 
80
    if(!R_FINITE(size)) // limit case: Poisson
-
 
81
	return(dpois_raw(x, mu, give_log));
-
 
82
 
81
    if(x == 0)/* be accurate, both for n << mu, and n >> mu :*/
83
    if(x == 0)/* be accurate, both for n << mu, and n >> mu :*/
82
	return R_D_exp(size * (size < mu ? log(size/(size+mu)) : log1p(- mu/(size+mu))));
84
	return R_D_exp(size * (size < mu ? log(size/(size+mu)) : log1p(- mu/(size+mu))));
83
    if(x < 1e-10 * size) { /* don't use dbinom_raw() but MM's formula: */
85
    if(x < 1e-10 * size) { /* don't use dbinom_raw() but MM's formula: */
84
	/* FIXME --- 1e-8 shows problem; rather use algdiv() from ./toms708.c */
86
	/* FIXME --- 1e-8 shows problem; rather use algdiv() from ./toms708.c */
85
	p = (size < mu ? log(size/(1 + size/mu)) : log(mu / (1 + mu/size)));
87
	double p = (size < mu ? log(size/(1 + size/mu)) : log(mu / (1 + mu/size)));
86
	return R_D_exp(x * p - mu - lgamma(x+1) +
88
	return R_D_exp(x * p - mu - lgamma(x+1) +
87
		       log1p(x*(x-1)/(2*size)));
89
		       log1p(x*(x-1)/(2*size)));
-
 
90
    } else {
-
 
91
	/* no unnecessary cancellation inside dbinom_raw, when
-
 
92
	 * x_ = size and n_ = x+size are so close that n_ - x_ loses accuracy */
-
 
93
	double p = ((double)size)/(size+x),
-
 
94
	    ans = dbinom_raw(size, x+size, size/(size+mu), mu/(size+mu), give_log);
-
 
95
	return((give_log) ? log(p) + ans : p * ans);
88
    }
96
    }
89
    /* else: no unnecessary cancellation inside dbinom_raw, when
-
 
90
     * x_ = size and n_ = x+size are so close that n_ - x_ loses accuracy
-
 
91
     */
-
 
92
    ans = dbinom_raw(size, x+size, size/(size+mu), mu/(size+mu), give_log);
-
 
93
    p = ((double)size)/(size+x);
-
 
94
    return((give_log) ? log(p) + ans : p * ans);
-
 
95
}
97
}