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