Rcpp Version 0.9.10
macros.h
Go to the documentation of this file.
00001 /*
00002  *  R : A Computer Language for Statistical Data Analysis
00003  *  Copyright (C) 2000--2007  R Development Core Team
00004  *
00005  *  This program is free software; you can redistribute it and/or modify
00006  *  it under the terms of the GNU General Public License as published by
00007  *  the Free Software Foundation; either version 2 of the License, or
00008  *  (at your option) any later version.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, a copy is available at
00017  *  http://www.r-project.org/Licenses/
00018  */
00019         /* Utilities for `dpq' handling (density/probability/quantile) */
00020 
00021 /* This is borrowed from R, with some changes */
00022         
00023 /* give_log in "d";  log_p in "p" & "q" : */
00024 #define give_log log_p
00025                                                         /* "DEFAULT" */
00026                                                         /* --------- */
00027 #define R_D__0  (log_p ? ML_NEGINF : 0.)                /* 0 */
00028 #define R_D__1  (log_p ? 0. : 1.)                       /* 1 */
00029 #define R_DT_0  (lower_tail ? R_D__0 : R_D__1)          /* 0 */
00030 #define R_DT_1  (lower_tail ? R_D__1 : R_D__0)          /* 1 */
00031 
00032 /* Use 0.5 - p + 0.5 to perhaps gain 1 bit of accuracy */
00033 #define R_D_Lval(p)     (lower_tail ? (p) : (0.5 - (p) + 0.5))  /*  p  */
00034 #define R_D_Cval(p)     (lower_tail ? (0.5 - (p) + 0.5) : (p))  /*  1 - p */
00035 
00036 #define R_D_val(x)      (log_p  ? ::log(x) : (x))               /*  x  in pF(x,..) */
00037 #define R_D_qIv(p)      (log_p  ? ::exp(p) : (p))               /*  p  in qF(p,..) */
00038 #define R_D_exp(x)      (log_p  ?  (x)   : ::exp(x))    /* exp(x) */
00039 #define R_D_log(p)      (log_p  ?  (p)   : ::log(p))    /* log(p) */
00040 #define R_D_Clog(p)     (log_p  ? ::log1p(-(p)) : (0.5 - (p) + 0.5)) /* [log](1-p) */
00041 
00042 /* log(1 - exp(x))  in more stable form than log1p(- R_D_qIv(x))) : */
00043 #define R_Log1_Exp(x)   ((x) > -M_LN2 ? ::log(-::expm1(x)) : ::log1p(-::exp(x)))
00044 
00045 /* log(1-exp(x)):  R_D_LExp(x) == (log1p(- R_D_qIv(x))) but even more stable:*/
00046 #define R_D_LExp(x)     (log_p ? R_Log1_Exp(x) : ::log1p(-x))
00047 
00048 #define R_DT_val(x)     (lower_tail ? R_D_val(x)  : R_D_Clog(x))
00049 #define R_DT_Cval(x)    (lower_tail ? R_D_Clog(x) : R_D_val(x))
00050 
00051 /*#define R_DT_qIv(p)   R_D_Lval(R_D_qIv(p))             *  p  in qF ! */
00052 #define R_DT_qIv(p)     (log_p ? (lower_tail ? ::exp(p) : - ::expm1(p)) \
00053                                : R_D_Lval(p))
00054 
00055 /*#define R_DT_CIv(p)   R_D_Cval(R_D_qIv(p))             *  1 - p in qF */
00056 #define R_DT_CIv(p)     (log_p ? (lower_tail ? -expm1(p) : ::exp(p)) \
00057                                : R_D_Cval(p))
00058 
00059 #define R_DT_exp(x)     R_D_exp(R_D_Lval(x))            /* exp(x) */
00060 #define R_DT_Cexp(x)    R_D_exp(R_D_Cval(x))            /* exp(1 - x) */
00061 
00062 #define R_DT_log(p)     (lower_tail? R_D_log(p) : R_D_LExp(p))/* log(p) in qF */
00063 #define R_DT_Clog(p)    (lower_tail? R_D_LExp(p): R_D_log(p))/* log(1-p) in qF*/
00064 #define R_DT_Log(p)     (lower_tail? (p) : R_Log1_Exp(p))
00065 /* ==   R_DT_log when we already "know" log_p == TRUE :*/
00066 
00067 
00068 #define R_Q_P01_check(p)                        \
00069     if ((log_p  && p > 0) ||                    \
00070         (!log_p && (p < 0 || p > 1)) )          \
00071         return R_NaN
00072 
00073 /* Do the boundaries exactly for q*() functions :
00074  * Often  _LEFT_ = ML_NEGINF , and very often _RIGHT_ = ML_POSINF;
00075  *
00076  * R_Q_P01_boundaries(p, _LEFT_, _RIGHT_)  :<==>
00077  *
00078  *     R_Q_P01_check(p);
00079  *     if (p == R_DT_0) return _LEFT_ ;
00080  *     if (p == R_DT_1) return _RIGHT_;
00081  *
00082  * the following implementation should be more efficient (less tests):
00083  */
00084 #define R_Q_P01_boundaries(p, _LEFT_, _RIGHT_)          \
00085     if (log_p) {                                        \
00086         if(p > 0)                                       \
00087             return R_NaN ;                              \
00088         if(p == 0) /* upper bound*/                     \
00089             return lower_tail ? _RIGHT_ : _LEFT_;       \
00090         if(p == ML_NEGINF)                              \
00091             return lower_tail ? _LEFT_ : _RIGHT_;       \
00092     }                                                   \
00093     else { /* !log_p */                                 \
00094         if(p < 0 || p > 1)                              \
00095             return R_NaN ;                              \
00096         if(p == 0)                                      \
00097             return lower_tail ? _LEFT_ : _RIGHT_;       \
00098         if(p == 1)                                      \
00099             return lower_tail ? _RIGHT_ : _LEFT_;       \
00100     }
00101 
00102 #define R_P_bounds_01(x, x_min, x_max)  \
00103     if(x <= x_min) return R_DT_0;               \
00104     if(x >= x_max) return R_DT_1
00105 /* is typically not quite optimal for (-Inf,Inf) where
00106  * you'd rather have */
00107 #define R_P_bounds_Inf_01(x)                    \
00108     if(!R_FINITE(x)) {                          \
00109         if (x > 0) return R_DT_1;               \
00110         /* x < 0 */return R_DT_0;               \
00111     }
00112 
00113 
00114 
00115 /* additions for density functions (C.Loader) */
00116 #define R_D_fexp(f,x)     (give_log ? -0.5*log(f)+(x) : exp(x)/sqrt(f))
00117 #define R_D_forceint(x)   floor((x) + 0.5)
00118 #define R_D_nonint(x)     (fabs((x) - floor((x)+0.5)) > 1e-7)
00119 /* [neg]ative or [non int]eger : */
00120 #define R_D_negInonint(x) (x < 0. || R_D_nonint(x))
00121 
00122 #define R_D_nonint_check(x)                             \
00123    if(R_D_nonint(x)) {                                  \
00124         MATHLIB_WARNING("non-integer x = %f", x);       \
00125         return R_D__0;                                  \
00126    }
00127 
 All Classes Namespaces Files Functions Variables Typedefs Enumerator Friends Defines