|
Rcpp Version 0.9.10
|
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