1 /***************************************************************************** 2 * * 3 * UNURAN -- Universal Non-Uniform Random number generator * 4 * * 5 ***************************************************************************** 6 * * 7 * FILE: distr_source.h * 8 * * 9 * PURPOSE: * 10 * defines macros and function prototypes for handling * 11 * distribution objects. * 12 * * 13 * USAGE: * 14 * only included in source_unuran.h * 15 * * 16 ***************************************************************************** 17 * * 18 * Copyright (c) 2000-2006 Wolfgang Hoermann and Josef Leydold * 19 * Department of Statistics and Mathematics, WU Wien, Austria * 20 * * 21 * This program is free software; you can redistribute it and/or modify * 22 * it under the terms of the GNU General Public License as published by * 23 * the Free Software Foundation; either version 2 of the License, or * 24 * (at your option) any later version. * 25 * * 26 * This program is distributed in the hope that it will be useful, * 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * 29 * GNU General Public License for more details. * 30 * * 31 * You should have received a copy of the GNU General Public License * 32 * along with this program; if not, write to the * 33 * Free Software Foundation, Inc., * 34 * 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA * 35 * * 36 *****************************************************************************/ 37 38 /*---------------------------------------------------------------------------*/ 39 #ifndef UNUR_DISTR_SOURCE_H_SEEN 40 #define UNUR_DISTR_SOURCE_H_SEEN 41 /*---------------------------------------------------------------------------*/ 42 43 /*---------------------------------------------------------------------------*/ 44 /* indicate changed parameters */ 45 46 /* essential parameters */ 47 #define UNUR_DISTR_SET_MASK_ESSENTIAL 0xffff0000u 48 49 #define UNUR_DISTR_SET_DOMAIN 0x00010000u 50 #define UNUR_DISTR_SET_DOMAINBOUNDED 0x00020000u /* domain is bounded */ 51 #define UNUR_DISTR_SET_STDDOMAIN 0x00040000u /* domain not truncated (for standard distributions) */ 52 #define UNUR_DISTR_SET_TRUNCATED 0x00080000u /* truncated distribution, i.e. 53 the domain of the distribution has been 54 restricted AFTER initializing 55 the generator object */ 56 57 #define UNUR_DISTR_SET_MEAN 0x01000000u /* mean (vector for multivariate distr.) */ 58 #define UNUR_DISTR_SET_COVAR 0x02000000u /* covariance matrix (for multivar. distr.) */ 59 #define UNUR_DISTR_SET_COVAR_INV 0x04000000u /* inverse of covariance matrix (for multivar. distr.) */ 60 #define UNUR_DISTR_SET_COVAR_IDENT 0x40000000u /* covariance matrix is identity matrix */ 61 #define UNUR_DISTR_SET_CHOLESKY 0x08000000u /* cholesky factor of covariance matrix (for multivar. distr.) */ 62 #define UNUR_DISTR_SET_RANKCORR 0x10000000u /* rank-correlation (for multivar. distr.) */ 63 #define UNUR_DISTR_SET_RK_CHOLESKY 0x20000000u /* cholesky factor of covariance matrix (for multivar. distr.) */ 64 #define UNUR_DISTR_SET_STDMARGINAL 0x00100000u /* standardized marginal distribution (for multivar. distr.) */ 65 #define UNUR_DISTR_SET_MARGINAL 0x00200000u /* marginal distribution (for multivar. distr.) */ 66 67 #define UNUR_DISTR_SET_GENERIC 0x00080000u /* generic parameter (can be used for any purpose) */ 68 69 70 /* derived parameters */ 71 #define UNUR_DISTR_SET_MASK_DERIVED 0x0000ffffu 72 73 #define UNUR_DISTR_SET_MODE 0x00000001u 74 #define UNUR_DISTR_SET_MODE_APPROX 0x00000020u /* flag for approximate computation of mode */ 75 #define UNUR_DISTR_SET_CENTER 0x00000002u 76 #define UNUR_DISTR_SET_CENTER_APPROX 0x00000040u /* flag for approximate computation of center */ 77 #define UNUR_DISTR_SET_PDFAREA 0x00000004u 78 #define UNUR_DISTR_SET_PMFSUM 0x00000008u 79 #define UNUR_DISTR_SET_PDFVOLUME 0x00000010u 80 81 /*---------------------------------------------------------------------------*/ 82 /* call PDFs and CDFs */ 83 /* (no checking for NULL pointer !) */ 84 85 #define _unur_cont_PDF(x,distr) ((*((distr)->data.cont.pdf)) ((x),(distr))) 86 #define _unur_cont_dPDF(x,distr) ((*((distr)->data.cont.dpdf))((x),(distr))) 87 #define _unur_cont_logPDF(x,distr) ((*((distr)->data.cont.logpdf)) ((x),(distr))) 88 #define _unur_cont_dlogPDF(x,distr) ((*((distr)->data.cont.dlogpdf))((x),(distr))) 89 #define _unur_cont_CDF(x,distr) ((*((distr)->data.cont.cdf)) ((x),(distr))) 90 #define _unur_cont_logCDF(x,distr) ((*((distr)->data.cont.logcdf)) ((x),(distr))) 91 #define _unur_cont_invCDF(u,distr) ((*((distr)->data.cont.invcdf)) ((u),(distr))) 92 #define _unur_cont_HR(x,distr) ((*((distr)->data.cont.hr)) ((x),(distr))) 93 94 #define _unur_discr_PMF(x,distr) ((*((distr)->data.discr.pmf))((x),(distr))) 95 #define _unur_discr_CDF(x,distr) ((*((distr)->data.discr.cdf))((x),(distr))) 96 #define _unur_discr_invCDF(u,distr) ((int) (*((distr)->data.discr.invcdf)) ((u),(distr))) 97 98 /* #define _unur_cvec_PDF(x,distr) ((*((distr)->data.cvec.pdf)) ((x),(distr))) */ 99 /* #define _unur_cvec_dPDF(r,x,distr) ((*((distr)->data.cvec.dpdf)) ((r),(x),(distr))) */ 100 /* #define _unur_cvec_pdPDF(x,c,distr) ((*((distr)->data.cvec.pdpdf)) ((x),(c),(distr))) */ 101 /* #define _unur_cvec_logPDF(x,distr) ((*((distr)->data.cvec.logpdf)) ((x),(distr))) */ 102 /* #define _unur_cvec_dlogPDF(r,x,distr) ((*((distr)->data.cvec.dlogpdf)) ((r),(x),(distr))) */ 103 /* #define _unur_cvec_pdlogPDF(x,c,distr) ((*((distr)->data.cvec.pdlogpdf)) ((x),(c),(distr))) */ 104 105 double _unur_cvec_PDF(const double *x, struct unur_distr *distr); 106 int _unur_cvec_dPDF(double *result, const double *x, struct unur_distr *distr); 107 double _unur_cvec_pdPDF(const double *x, int coord, struct unur_distr *distr); 108 double _unur_cvec_logPDF(const double *x, struct unur_distr *distr); 109 int _unur_cvec_dlogPDF(double *result, const double *x, struct unur_distr *distr); 110 double _unur_cvec_pdlogPDF(const double *x, int coord, struct unur_distr *distr); 111 112 /*---------------------------------------------------------------------------*/ 113 /* check for existance of function pointers */ 114 115 #define _unur_cont_have_logPDF(distr) (((distr)->data.cont.logpdf==NULL)?FALSE:TRUE) 116 #define _unur_cont_have_dlogPDF(distr) (((distr)->data.cont.dlogpdf==NULL)?FALSE:TRUE) 117 118 /*---------------------------------------------------------------------------*/ 119 /* wrapper functions for PDF when only logPDF is given */ 120 121 double _unur_distr_cont_eval_pdf_from_logpdf( double x, const struct unur_distr *distr ); 122 double _unur_distr_cont_eval_dpdf_from_dlogpdf( double x, const struct unur_distr *distr ); 123 double _unur_distr_cont_eval_cdf_from_logcdf( double x, const struct unur_distr *distr ); 124 125 double _unur_distr_cvec_eval_pdf_from_logpdf( const double *x, struct unur_distr *distr ); 126 int _unur_distr_cvec_eval_dpdf_from_dlogpdf( double *result, const double *x, struct unur_distr *distr ); 127 double _unur_distr_cvec_eval_pdpdf_from_pdlogpdf( const double *x, int coord, struct unur_distr *distr ); 128 129 /*---------------------------------------------------------------------------*/ 130 /* generic creator for distribution objects */ 131 132 struct unur_distr *_unur_distr_generic_new( void ); 133 134 /*---------------------------------------------------------------------------*/ 135 /* make clone of distribution objects */ 136 137 struct unur_distr *_unur_distr_cemp_clone ( const struct unur_distr *distr ); 138 struct unur_distr *_unur_distr_cont_clone ( const struct unur_distr *distr ); 139 struct unur_distr *_unur_distr_matr_clone ( const struct unur_distr *distr ); 140 struct unur_distr *_unur_distr_cvec_clone ( const struct unur_distr *distr ); 141 struct unur_distr *_unur_distr_cvemp_clone( const struct unur_distr *distr ); 142 struct unur_distr *_unur_distr_discr_clone( const struct unur_distr *distr ); 143 144 #define _unur_distr_clone(distr) ((distr)->clone(distr)) 145 146 /*---------------------------------------------------------------------------*/ 147 /* destroy distribution object */ 148 #define _unur_distr_free(distr) do {if (distr) (distr)->destroy(distr);} while(0) 149 150 /*---------------------------------------------------------------------------*/ 151 /* debuging routines for distributions */ 152 #ifdef UNUR_ENABLE_LOGGING 153 154 void _unur_distr_cont_debug( const UNUR_DISTR *distribution, const char *genid ); 155 /* write info about distribution into logfile */ 156 157 void _unur_distr_corder_debug( const UNUR_DISTR *order_statistics, const char *genid ); 158 /* write info about distribution into logfile */ 159 160 void _unur_distr_cxtrans_debug( const UNUR_DISTR *cxtrans, const char *genid ); 161 /* write info about distribution into logfile */ 162 163 void _unur_distr_cemp_debug( const UNUR_DISTR *distribution, const char *genid, unsigned printvector ); 164 /* write info about distribution into logfile */ 165 166 void _unur_distr_matr_debug( const UNUR_DISTR *distribution, const char *genid ); 167 /* write info about matrix distribution into logfile */ 168 169 void _unur_distr_cvec_debug( const UNUR_DISTR *distribution, const char *genid ); 170 /* write info about distribution into logfile */ 171 172 void _unur_distr_condi_debug( const UNUR_DISTR *distribution, const char *genid ); 173 /* write info about distribution into logfile */ 174 175 void _unur_distr_cvemp_debug( const UNUR_DISTR *distribution, const char *genid, unsigned printvector ); 176 /* write info about distribution into logfile */ 177 178 void _unur_distr_discr_debug( const UNUR_DISTR *distribution, const char *genid, unsigned printvector ); 179 /* write info about distribution into logfile */ 180 181 #endif 182 /*---------------------------------------------------------------------------*/ 183 /* routines for creating info strings */ 184 #ifdef UNUR_ENABLE_INFO 185 186 void _unur_distr_info_typename( struct unur_gen *gen ); 187 /* write string that contains type and name of given distribution object */ 188 189 void _unur_distr_info_vector( struct unur_gen *gen, const double *vec, int n ); 190 /* write string that contains given vector */ 191 192 void _unur_distr_cvec_info_domain( struct unur_gen *gen ); 193 /* create character string that contains domain */ 194 195 #endif 196 /*---------------------------------------------------------------------------*/ 197 /* auxiliary routines */ 198 199 int _unur_distr_cont_find_center( struct unur_distr *distr ); 200 /* search for an appropriate point for center. */ 201 /* if such a point is found, then it is stored in 'distr'. */ 202 203 204 /* test whether all marginals are equal or not (returns TRUE or FALSE) */ 205 /* for dimesion 1, TRUE is returned. */ 206 /* WARNING: There is no checking of arguments in this function! */ 207 int _unur_distr_cvec_marginals_are_equal( struct unur_distr **marginals, int dim ); 208 209 /* Duplicate first marginal distribution in array of marginal */ 210 /* distributions into all other slots of this array */ 211 /* This is only executed when all entries in this array point to the */ 212 /* same distribution object, i.e. when all marginal distributions */ 213 /* are equal. */ 214 int _unur_distr_cvec_duplicate_firstmarginal( struct unur_distr *distribution ); 215 216 /* test whether 'x' is the in domain of 'distribution' */ 217 int _unur_distr_cvec_is_indomain( const double *x, const struct unur_distr *distribution); 218 219 /* check whether @var{distribution} has a bounded domain */ 220 int _unur_distr_cvec_has_boundeddomain( const struct unur_distr *distribution ); 221 222 223 /*---------------------------------------------------------------------------*/ 224 /* check if parameter object is of correct type, return 0 otherwise */ 225 226 #define _unur_check_distr_object( distr,distrtype, rcode ) \ 227 do { \ 228 if ((distr)->type != UNUR_DISTR_##distrtype) { \ 229 _unur_warning((distr)->name,UNUR_ERR_DISTR_INVALID,""); \ 230 return rcode; } \ 231 COOKIE_CHECK(distr,CK_DISTR_##distrtype,rcode); } while (0) 232 233 /*---------------------------------------------------------------------------*/ 234 #endif /* UNUR_DISTR_SOURCE_H_SEEN */ 235 /*---------------------------------------------------------------------------*/ 236