1/*****************************************************************************
2 *                                                                           *
3 *          UNURAN -- Universal Non-Uniform Random number generator          *
4 *                                                                           *
5 *****************************************************************************
6 *                                                                           *
7 *   FILE:      mvtdr_newset.c                                               *
8 *                                                                           *
9 *   TYPE:      continuous multivariate random variate                       *
10 *   METHOD:    multivariate transformed density rejection                   *
11 *                                                                           *
12 *   DESCRIPTION:                                                            *
13 *      Given (logarithm of the) PDF of a log-concave distribution;          *
14 *      produce a value x consistent with its density.                       *
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/**  Public: User Interface (API)                                           **/
40/*****************************************************************************/
41
42struct unur_par *
43unur_mvtdr_new( const struct unur_distr *distr )
44     /*----------------------------------------------------------------------*/
45     /* get default parameters                                               */
46     /*                                                                      */
47     /* parameters:                                                          */
48     /*   distr ... pointer to distribution object                           */
49     /*                                                                      */
50     /* return:                                                              */
51     /*   default parameters (pointer to structure)                          */
52     /*                                                                      */
53     /* error:                                                               */
54     /*   return NULL                                                        */
55     /*----------------------------------------------------------------------*/
56{
57  struct unur_par *par;
58
59  /* check arguments */
60  _unur_check_NULL( GENTYPE,distr,NULL );
61
62  /* check distribution */
63  if (distr->type != UNUR_DISTR_CVEC) {
64    _unur_error(GENTYPE,UNUR_ERR_DISTR_INVALID,""); return NULL; }
65  COOKIE_CHECK(distr,CK_DISTR_CVEC,NULL);
66
67  if (distr->dim < 2) {
68    _unur_error(GENTYPE,UNUR_ERR_DISTR_PROP,"dim < 2"); return NULL; }
69
70  if ( ! ((DISTR_IN.pdf && DISTR_IN.dpdf) || (DISTR_IN.logpdf && DISTR_IN.dlogpdf)) ) {
71    _unur_error(GENTYPE,UNUR_ERR_DISTR_REQUIRED,"d/(log)PDF");
72    return NULL;
73  }
74
75  /* allocate structure */
76  par = _unur_par_new( sizeof(struct unur_mvtdr_par) );
77  COOKIE_SET(par,CK_MVTDR_PAR);
78
79  /* copy input */
80  par->distr    = distr;      /* pointer to distribution object              */
81
82  /* set default values */
83  par->method   = UNUR_METH_MVTDR ;   /* method                              */
84  par->variant  = 0u;                 /* default variant                     */
85  par->set      = 0u;                 /* inidicate default parameters        */
86  par->urng     = unur_get_default_urng(); /* use default urng               */
87  par->urng_aux = NULL;                    /* no auxilliary URNG required    */
88
89  par->debug    = _unur_default_debugflag; /* set default debugging flags    */
90
91  /* routine for starting generator */
92  par->init = _unur_mvtdr_init;
93
94  /* set default values */
95  /* minimum number of triangulation steps */
96  PAR->steps_min = 5;
97
98  /* maximum number of cones (at least 2^(dim+T_STEPS_MIN) */
99  PAR->max_cones = 10000;
100
101  /* bound for splitting cones */
102  PAR->bound_splitting = 1.5;
103
104  /** TODO !! **/
105  /* move mode to boundary if |mode - boundary| / length < MODE_TO_BOUNDARY */
106  /*   PAR->mode_to_boundary = 0.01; */
107
108  return par;
109
110} /* end of unur_mvtdr_new() */
111
112/*---------------------------------------------------------------------------*/
113
114int
115unur_mvtdr_set_stepsmin( struct unur_par *par, int stepsmin )
116     /*----------------------------------------------------------------------*/
117     /* set minimum number of triangulation step for each starting cone      */
118     /*                                                                      */
119     /* parameters:                                                          */
120     /*   par      ... pointer to parameter object                           */
121     /*   stepsmin ... minimum number of triangulation steps                 */
122     /*                                                                      */
123     /* return:                                                              */
124     /*   UNUR_SUCCESS ... on success                                        */
125     /*   error code   ... on error                                          */
126     /*----------------------------------------------------------------------*/
127{
128  /* check arguments */
129  _unur_check_NULL( GENTYPE, par, UNUR_ERR_NULL );
130  _unur_check_par_object( par, MVTDR );
131
132  /* check new parameter for generator */
133  if (stepsmin < 0) {
134    _unur_warning(GENTYPE,UNUR_ERR_PAR_SET,"stepsmin < 0");
135    return UNUR_ERR_PAR_SET;
136  }
137
138  /* store date */
139  PAR->steps_min = stepsmin;
140
141  /* changelog */
142  par->set |= MVTDR_SET_STEPSMIN;
143
144  return UNUR_SUCCESS;
145
146} /* end of unur_mvtdr_set_stepsmin() */
147
148/*---------------------------------------------------------------------------*/
149
150int
151unur_mvtdr_set_boundsplitting( UNUR_PAR *par, double boundsplitting )
152     /*----------------------------------------------------------------------*/
153     /* set bound for splitting cones. all cones are splitted when the       */
154     /* volume below the hat is greater than boundsplitting times the        */
155     /* average volume over all cones.                                       */
156     /*                                                                      */
157     /* parameters:                                                          */
158     /*   par            ... pointer to parameter object                     */
159     /*   boundsplitting ... maximum number of cones                         */
160     /*                                                                      */
161     /* return:                                                              */
162     /*   UNUR_SUCCESS ... on success                                        */
163     /*   error code   ... on error                                          */
164     /*----------------------------------------------------------------------*/
165{
166  /* check arguments */
167  _unur_check_NULL( GENTYPE, par, UNUR_ERR_NULL );
168  _unur_check_par_object( par, MVTDR );
169
170  /* check new parameter for generator */
171
172  /* store date */
173  PAR->bound_splitting = boundsplitting;
174
175  /* changelog */
176  par->set |= MVTDR_SET_BOUNDSPLITTING;
177
178  return UNUR_SUCCESS;
179
180} /* end of unur_mvtdr_set_boundsplitting() */
181
182/*---------------------------------------------------------------------------*/
183
184int
185unur_mvtdr_set_maxcones( struct unur_par *par, int maxcones )
186     /*----------------------------------------------------------------------*/
187     /* set maximum number of cones                                          */
188     /* (this number is always increased to 2^(dim+stepsmin) )               */
189     /*                                                                      */
190     /* parameters:                                                          */
191     /*   par      ... pointer to parameter object                           */
192     /*   maxcones ... maximum number of cones                               */
193     /*                                                                      */
194     /* return:                                                              */
195     /*   UNUR_SUCCESS ... on success                                        */
196     /*   error code   ... on error                                          */
197     /*----------------------------------------------------------------------*/
198{
199  /* check arguments */
200  _unur_check_NULL( GENTYPE, par, UNUR_ERR_NULL );
201  _unur_check_par_object( par, MVTDR );
202
203  /* check new parameter for generator */
204  /* none here: it is always increased to 2^(dim+stepsmin) during init */
205
206  /* store date */
207  PAR->max_cones = maxcones;
208
209  /* changelog */
210  par->set |= MVTDR_SET_MAXCONES;
211
212  return UNUR_SUCCESS;
213
214} /* end of unur_mvtdr_set_maxcones() */
215
216/*---------------------------------------------------------------------------*/
217
218int
219unur_mvtdr_get_ncones( const struct unur_gen *gen )
220     /*----------------------------------------------------------------------*/
221     /* get number of cones                                                  */
222     /*                                                                      */
223     /* parameters:                                                          */
224     /*   gen  ... pointer to generator object                               */
225     /*                                                                      */
226     /* return:                                                              */
227     /*   number of cones ... on success                                     */
228     /*   0               ... on error                                       */
229     /*----------------------------------------------------------------------*/
230{
231  /* check input */
232  _unur_check_NULL( GENTYPE, gen, 0 );
233  _unur_check_gen_object( gen, MVTDR, 0 );
234
235  return GEN->n_cone;
236} /* end of unur_mvtdr_get_ncones() */
237
238/*---------------------------------------------------------------------------*/
239
240double
241unur_mvtdr_get_hatvol( const struct unur_gen *gen )
242     /*----------------------------------------------------------------------*/
243     /* get volume below hat                                                 */
244     /*                                                                      */
245     /* parameters:                                                          */
246     /*   gen  ... pointer to generator object                               */
247     /*                                                                      */
248     /* return:                                                              */
249     /*   volume   ... on success                                            */
250     /*   INFINITY ... on error                                              */
251     /*----------------------------------------------------------------------*/
252{
253  /* check input */
254  _unur_check_NULL( GENTYPE, gen, INFINITY );
255  _unur_check_gen_object( gen, MVTDR, INFINITY );
256
257  return GEN->Htot;
258} /* end of unur_mvtdr_get_hatvol() */
259
260/*---------------------------------------------------------------------------*/
261
262int
263unur_mvtdr_set_verify( struct unur_par *par, int verify )
264     /*----------------------------------------------------------------------*/
265     /* turn verifying of algorithm while sampling on/off                    */
266     /*                                                                      */
267     /* parameters:                                                          */
268     /*   par    ... pointer to parameter for building generator object      */
269     /*   verify ... 0 = no verifying,  !0 = verifying                       */
270     /*                                                                      */
271     /* return:                                                              */
272     /*   UNUR_SUCCESS ... on success                                        */
273     /*   error code   ... on error                                          */
274     /*                                                                      */
275     /* comment:                                                             */
276     /*   no verifying is the default                                        */
277     /*----------------------------------------------------------------------*/
278{
279  /* check arguments */
280  _unur_check_NULL( GENTYPE, par, UNUR_ERR_NULL );
281
282  /* check input */
283  _unur_check_par_object( par, MVTDR );
284
285  /* we use a bit in variant */
286  par->variant = (verify) ? (par->variant | MVTDR_VARFLAG_VERIFY) : (par->variant & (~MVTDR_VARFLAG_VERIFY));
287
288  /* o.k. */
289  return UNUR_SUCCESS;
290
291} /* end of unur_mvtdr_set_verify() */
292
293/*---------------------------------------------------------------------------*/
294
295int
296unur_mvtdr_chg_verify( struct unur_gen *gen, int verify )
297     /*----------------------------------------------------------------------*/
298     /* turn verifying of algorithm while sampling on/off                    */
299     /*                                                                      */
300     /* parameters:                                                          */
301     /*   gen    ... pointer to generator object                             */
302     /*   verify ... 0 = no verifying,  !0 = verifying                       */
303     /*                                                                      */
304     /* return:                                                              */
305     /*   UNUR_SUCCESS ... on success                                        */
306     /*   error code   ... on error                                          */
307     /*                                                                      */
308     /* comment:                                                             */
309     /*   no verifying is the default                                        */
310     /*----------------------------------------------------------------------*/
311{
312  /* check input */
313  _unur_check_NULL( GENTYPE, gen, UNUR_ERR_NULL );
314  _unur_check_gen_object( gen, MVTDR, UNUR_ERR_GEN_INVALID );
315
316  /* we must not change this switch when sampling has been disabled by
317     using a pointer to the error producing routine                          */
318  if (SAMPLE == _unur_sample_cvec_error)
319    return UNUR_FAILURE;
320
321  /* we use a bit in variant */
322  gen->variant = (verify)
323    ? (gen->variant | MVTDR_VARFLAG_VERIFY)
324    : (gen->variant & (~MVTDR_VARFLAG_VERIFY));
325
326  /* o.k. */
327  return UNUR_SUCCESS;
328
329} /* end of unur_mvtdr_chg_verify() */
330
331/*---------------------------------------------------------------------------*/
332