Rcpp Version 1.0.9
macros.h
Go to the documentation of this file.
1 /*
2  * R : A Computer Language for Statistical Data Analysis
3  * Copyright (C) 2000--2007 R Development 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  * http://www.r-project.org/Licenses/
18  */
19  /* Utilities for `dpq' handling (density/probability/quantile) */
20 
21 /* This is borrowed from R, with some changes */
22 
23 /* give_log in "d"; log_p in "p" & "q" : */
24 #define give_log log_p
25  /* "DEFAULT" */
26  /* --------- */
27 #define R_D__0 (log_p ? ML_NEGINF : 0.) /* 0 */
28 #define R_D__1 (log_p ? 0. : 1.) /* 1 */
29 #define R_DT_0 (lower_tail ? R_D__0 : R_D__1) /* 0 */
30 #define R_DT_1 (lower_tail ? R_D__1 : R_D__0) /* 1 */
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  return R_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  return R_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  return R_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 #define R_D_forceint(x) floor((x) + 0.5)
118 #define R_D_nonint(x) (fabs((x) - floor((x)+0.5)) > 1e-7)
119 /* [neg]ative or [non int]eger : */
120 #define R_D_negInonint(x) (x < 0. || R_D_nonint(x))
121 
122 #define R_D_nonint_check(x) \
123  if(R_D_nonint(x)) { \
124  MATHLIB_WARNING("non-integer x = %f", x); \
125  return R_D__0; \
126  }
127