1 /*
2  *  R : A Computer Language for Statistical Data Analysis
3  *  Copyright (C) 2000--2015 The  R Core Team
4  *
5  *  This program is free software; you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation; either version 2 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program; if not, a copy is available at
17  *  https://www.R-project.org/Licenses/
18  */
19 	/* Utilities for `dpq' handling (density/probability/quantile) */
20 
21 /* give_log in "d";  log_p in "p" & "q" : */
22 #define give_log log_p
23 							/* "DEFAULT" */
24 							/* --------- */
25 #define R_D__0	(log_p ? ML_NEGINF : 0.)		/* 0 */
26 #define R_D__1	(log_p ? 0. : 1.)			/* 1 */
27 #define R_DT_0	(lower_tail ? R_D__0 : R_D__1)		/* 0 */
28 #define R_DT_1	(lower_tail ? R_D__1 : R_D__0)		/* 1 */
29 #define R_D_half (log_p ? -M_LN2 : 0.5)		// 1/2 (lower- or upper tail)
30 
31 
32 /* Use 0.5 - p + 0.5 to perhaps gain 1 bit of accuracy */
33 #define R_D_Lval(p)	(lower_tail ? (p) : (0.5 - (p) + 0.5))	/*  p  */
34 #define R_D_Cval(p)	(lower_tail ? (0.5 - (p) + 0.5) : (p))	/*  1 - p */
35 
36 #define R_D_val(x)	(log_p	? log(x) : (x))		/*  x  in pF(x,..) */
37 #define R_D_qIv(p)	(log_p	? exp(p) : (p))		/*  p  in qF(p,..) */
38 #define R_D_exp(x)	(log_p	?  (x)	 : exp(x))	/* exp(x) */
39 #define R_D_log(p)	(log_p	?  (p)	 : log(p))	/* log(p) */
40 #define R_D_Clog(p)	(log_p	? log1p(-(p)) : (0.5 - (p) + 0.5)) /* [log](1-p) */
41 
42 // log(1 - exp(x))  in more stable form than log1p(- R_D_qIv(x)) :
43 #define R_Log1_Exp(x)   ((x) > -M_LN2 ? log(-expm1(x)) : log1p(-exp(x)))
44 
45 /* log(1-exp(x)):  R_D_LExp(x) == (log1p(- R_D_qIv(x))) but even more stable:*/
46 #define R_D_LExp(x)     (log_p ? R_Log1_Exp(x) : log1p(-x))
47 
48 #define R_DT_val(x)	(lower_tail ? R_D_val(x)  : R_D_Clog(x))
49 #define R_DT_Cval(x)	(lower_tail ? R_D_Clog(x) : R_D_val(x))
50 
51 /*#define R_DT_qIv(p)	R_D_Lval(R_D_qIv(p))		 *  p  in qF ! */
52 #define R_DT_qIv(p)	(log_p ? (lower_tail ? exp(p) : - expm1(p)) \
53 			       : R_D_Lval(p))
54 
55 /*#define R_DT_CIv(p)	R_D_Cval(R_D_qIv(p))		 *  1 - p in qF */
56 #define R_DT_CIv(p)	(log_p ? (lower_tail ? -expm1(p) : exp(p)) \
57 			       : R_D_Cval(p))
58 
59 #define R_DT_exp(x)	R_D_exp(R_D_Lval(x))		/* exp(x) */
60 #define R_DT_Cexp(x)	R_D_exp(R_D_Cval(x))		/* exp(1 - x) */
61 
62 #define R_DT_log(p)	(lower_tail? R_D_log(p) : R_D_LExp(p))/* log(p) in qF */
63 #define R_DT_Clog(p)	(lower_tail? R_D_LExp(p): R_D_log(p))/* log(1-p) in qF*/
64 #define R_DT_Log(p)	(lower_tail? (p) : R_Log1_Exp(p))
65 // ==   R_DT_log when we already "know" log_p == TRUE
66 
67 
68 #define R_Q_P01_check(p)			\
69     if ((log_p	&& p > 0) ||			\
70 	(!log_p && (p < 0 || p > 1)) )		\
71 	ML_WARN_return_NAN
72 
73 /* Do the boundaries exactly for q*() functions :
74  * Often  _LEFT_ = ML_NEGINF , and very often _RIGHT_ = ML_POSINF;
75  *
76  * R_Q_P01_boundaries(p, _LEFT_, _RIGHT_)  :<==>
77  *
78  *     R_Q_P01_check(p);
79  *     if (p == R_DT_0) return _LEFT_ ;
80  *     if (p == R_DT_1) return _RIGHT_;
81  *
82  * the following implementation should be more efficient (less tests):
83  */
84 #define R_Q_P01_boundaries(p, _LEFT_, _RIGHT_)		\
85     if (log_p) {					\
86 	if(p > 0)					\
87 	    ML_WARN_return_NAN;				\
88 	if(p == 0) /* upper bound*/			\
89 	    return lower_tail ? _RIGHT_ : _LEFT_;	\
90 	if(p == ML_NEGINF)				\
91 	    return lower_tail ? _LEFT_ : _RIGHT_;	\
92     }							\
93     else { /* !log_p */					\
94 	if(p < 0 || p > 1)				\
95 	    ML_WARN_return_NAN;				\
96 	if(p == 0)					\
97 	    return lower_tail ? _LEFT_ : _RIGHT_;	\
98 	if(p == 1)					\
99 	    return lower_tail ? _RIGHT_ : _LEFT_;	\
100     }
101 
102 #define R_P_bounds_01(x, x_min, x_max)	\
103     if(x <= x_min) return R_DT_0;		\
104     if(x >= x_max) return R_DT_1
105 /* is typically not quite optimal for (-Inf,Inf) where
106  * you'd rather have */
107 #define R_P_bounds_Inf_01(x)			\
108     if(!R_FINITE(x)) {				\
109 	if (x > 0) return R_DT_1;		\
110 	/* x < 0 */return R_DT_0;		\
111     }
112 
113 
114 
115 /* additions for density functions (C.Loader) */
116 #define R_D_fexp(f,x)     (give_log ? -0.5*log(f)+(x) : exp(x)/sqrt(f))
117 
118 /* [neg]ative or [non int]eger : */
119 #define R_D_negInonint(x) (x < 0. || R_nonint(x))
120 
121 // for discrete d<distr>(x, ...) :
122 #define R_D_nonint_check(x)				\
123    if(R_nonint(x)) {					\
124        MATHLIB_WARNING(_("non-integer x = %f"), x);	\
125 	return R_D__0;					\
126    }
127