36 TUnuran::TUnuran(TRandom * r,
unsigned int debugLevel) :
44 if (fRng == 0) fRng = gRandom;
48 unur_set_default_debug(UNUR_DEBUG_ALL);
49 else if (debugLevel == 1)
50 unur_set_default_debug(UNUR_DEBUG_INIT);
52 unur_set_default_debug(UNUR_DEBUG_OFF);
60 if (fGen != 0) unur_free(fGen);
61 if (fUrng != 0) unur_urng_free(fUrng);
63 if (fUdistr != 0) unur_distr_free(fUdistr);
67 TUnuran::TUnuran(
const TUnuran &)
72 TUnuran & TUnuran::operator = (
const TUnuran &rhs)
75 if (
this == &rhs)
return *
this;
79 bool TUnuran::Init(
const std::string & dist,
const std::string & method)
82 std::string s = dist +
" & " + method;
83 fGen = unur_str2gen(s.c_str() );
85 Error(
"Init",
"Cannot create generator object");
88 if (! SetRandomGenerator() )
return false;
93 bool TUnuran::Init(
const TUnuranContDist & distr,
const std::string & method)
98 TUnuranContDist * distNew = distr.Clone();
102 if (! SetContDistribution(*distNew) )
return false;
103 if (! SetMethodAndInit() )
return false;
104 if (! SetRandomGenerator() )
return false;
109 bool TUnuran::Init(
const TUnuranMultiContDist & distr,
const std::string & method)
114 TUnuranMultiContDist * distNew = distr.Clone();
115 fDist.reset(distNew);
118 if (! SetMultiDistribution(*distNew) )
return false;
119 if (! SetMethodAndInit() )
return false;
120 if (! SetRandomGenerator() )
return false;
125 bool TUnuran::Init(
const TUnuranDiscrDist & distr,
const std::string & method ) {
129 TUnuranDiscrDist * distNew = distr.Clone();
130 fDist.reset(distNew);
133 if (! SetDiscreteDistribution(*distNew) )
return false;
134 if (! SetMethodAndInit() )
return false;
135 if (! SetRandomGenerator() )
return false;
139 bool TUnuran::Init(
const TUnuranEmpDist & distr,
const std::string & method ) {
143 TUnuranEmpDist * distNew = distr.Clone();
144 fDist.reset(distNew);
147 if (distr.IsBinned()) fMethod =
"hist";
148 else if (distr.NDim() > 1) fMethod =
"vempk";
149 if (! SetEmpiricalDistribution(*distNew) )
return false;
150 if (! SetMethodAndInit() )
return false;
151 if (! SetRandomGenerator() )
return false;
156 bool TUnuran::SetRandomGenerator()
159 if (fRng == 0)
return false;
160 if (fGen == 0)
return false;
162 fUrng = unur_urng_new(&UnuranRng<TRandom>::Rndm, fRng );
163 if (fUrng == 0)
return false;
164 unsigned int ret = 0;
165 ret |= unur_urng_set_delete(fUrng, &UnuranRng<TRandom>::Delete);
166 ret |= unur_urng_set_seed(fUrng, &UnuranRng<TRandom>::Seed);
167 if (ret != 0)
return false;
169 unur_chg_urng( fGen, fUrng);
173 bool TUnuran::SetContDistribution(
const TUnuranContDist & dist )
176 if (fUdistr != 0) unur_distr_free(fUdistr);
177 fUdistr = unur_distr_cont_new();
178 if (fUdistr == 0)
return false;
179 unsigned int ret = 0;
180 ret = unur_distr_set_extobj(fUdistr, &dist);
181 if ( ! dist.IsLogPdf() ) {
182 ret |= unur_distr_cont_set_pdf(fUdistr, &ContDist::Pdf);
183 ret |= unur_distr_cont_set_dpdf(fUdistr, &ContDist::Dpdf);
184 if (dist.HasCdf() ) ret |= unur_distr_cont_set_cdf(fUdistr, &ContDist::Cdf);
188 ret |= unur_distr_cont_set_logpdf(fUdistr, &ContDist::Pdf);
189 ret |= unur_distr_cont_set_dlogpdf(fUdistr, &ContDist::Dpdf);
192 double xmin, xmax = 0;
193 if (dist.GetDomain(xmin,xmax) ) {
194 ret = unur_distr_cont_set_domain(fUdistr,xmin,xmax);
196 Error(
"SetContDistribution",
"invalid domain xmin = %g xmax = %g ",xmin,xmax);
200 if (dist.HasMode() ) {
201 ret = unur_distr_cont_set_mode(fUdistr, dist.Mode());
203 Error(
"SetContDistribution",
"invalid mode given, mode = %g ",dist.Mode());
207 if (dist.HasPdfArea() ) {
208 ret = unur_distr_cont_set_pdfarea(fUdistr, dist.PdfArea());
210 Error(
"SetContDistribution",
"invalid area given, area = %g ",dist.PdfArea());
215 return (ret ==0) ?
true :
false;
219 bool TUnuran::SetMultiDistribution(
const TUnuranMultiContDist & dist )
222 if (fUdistr != 0) unur_distr_free(fUdistr);
223 fUdistr = unur_distr_cvec_new(dist.NDim() );
224 if (fUdistr == 0)
return false;
225 unsigned int ret = 0;
226 ret |= unur_distr_set_extobj(fUdistr, &dist );
227 if ( ! dist.IsLogPdf() ) {
228 ret |= unur_distr_cvec_set_pdf(fUdistr, &MultiDist::Pdf);
229 ret |= unur_distr_cvec_set_dpdf(fUdistr, &MultiDist::Dpdf);
230 ret |= unur_distr_cvec_set_pdpdf(fUdistr, &MultiDist::Pdpdf);
233 ret |= unur_distr_cvec_set_logpdf(fUdistr, &MultiDist::Pdf);
234 ret |= unur_distr_cvec_set_dlogpdf(fUdistr, &MultiDist::Dpdf);
235 ret |= unur_distr_cvec_set_pdlogpdf(fUdistr, &MultiDist::Pdpdf);
238 const double * xmin = dist.GetLowerDomain();
239 const double * xmax = dist.GetUpperDomain();
240 if ( xmin != 0 || xmax != 0 ) {
241 ret = unur_distr_cvec_set_domain_rect(fUdistr,xmin,xmax);
243 Error(
"SetMultiDistribution",
"invalid domain");
247 Error(
"SetMultiDistribution",
"domain setting not available in UNURAN 0.8.1");
252 const double * xmode = dist.GetMode();
254 ret = unur_distr_cvec_set_mode(fUdistr, xmode);
256 Error(
"SetMultiDistribution",
"invalid mode");
260 return (ret ==0) ?
true :
false;
263 bool TUnuran::SetEmpiricalDistribution(
const TUnuranEmpDist & dist) {
266 if (fUdistr != 0) unur_distr_free(fUdistr);
267 if (dist.NDim() == 1)
268 fUdistr = unur_distr_cemp_new();
270 fUdistr = unur_distr_cvemp_new(dist.NDim() );
272 if (fUdistr == 0)
return false;
273 unsigned int ret = 0;
277 if (dist.IsBinned() ) {
278 int nbins = dist.Data().size();
279 double min = dist.LowerBin();
280 double max = dist.UpperBin();
281 const double * pv = &(dist.Data().front());
282 ret |= unur_distr_cemp_set_hist(fUdistr, pv, nbins, min, max);
284 Error(
"SetEmpiricalDistribution",
"hist method not available in UNURAN 0.8.1");
288 const double * pv = &dist.Data().front();
290 int n = dist.Data().size()/dist.NDim();
291 if (dist.NDim() == 1)
292 ret |= unur_distr_cemp_set_data(fUdistr, pv, n);
294 ret |= unur_distr_cvemp_set_data(fUdistr, pv, n);
297 Error(
"SetEmpiricalDistribution",
"invalid distribution object");
304 bool TUnuran::SetDiscreteDistribution(
const TUnuranDiscrDist & dist)
307 if (fUdistr != 0) unur_distr_free(fUdistr);
308 fUdistr = unur_distr_discr_new();
309 if (fUdistr == 0)
return false;
310 unsigned int ret = 0;
312 if (dist.ProbVec().size() == 0) {
313 ret = unur_distr_set_extobj(fUdistr, &dist );
314 ret |= unur_distr_discr_set_pmf(fUdistr, &DiscrDist::Pmf);
315 if (dist.HasCdf() ) ret |= unur_distr_discr_set_cdf(fUdistr, &DiscrDist::Cdf);
320 ret |= unur_distr_discr_set_pv(fUdistr, &dist.ProbVec().front(), dist.ProbVec().size() );
324 if (dist.GetDomain(xmin,xmax) ) {
325 ret = unur_distr_discr_set_domain(fUdistr,xmin,xmax);
327 Error(
"SetDiscrDistribution",
"invalid domain xmin = %d xmax = %d ",xmin,xmax);
331 if (dist.HasMode() ) {
332 ret = unur_distr_discr_set_mode(fUdistr, dist.Mode());
334 Error(
"SetContDistribution",
"invalid mode given, mode = %d ",dist.Mode());
338 if (dist.HasProbSum() ) {
339 ret = unur_distr_discr_set_pmfsum(fUdistr, dist.ProbSum());
341 Error(
"SetContDistribution",
"invalid sum given, mode = %g ",dist.ProbSum());
346 return (ret ==0) ?
true :
false;
351 bool TUnuran::SetMethodAndInit() {
355 if (fUdistr == 0)
return false;
357 struct unur_slist *mlist = NULL;
359 UNUR_PAR * par = _unur_str2par(fUdistr, fMethod.c_str(), &mlist);
361 Error(
"SetMethod",
"missing distribution information or syntax error");
362 if (mlist != 0) _unur_slist_free(mlist);
368 unur_set_use_distr_privatecopy (par,
false);
371 if (fGen != 0 ) unur_free(fGen);
372 fGen = unur_init(par);
373 _unur_slist_free(mlist);
375 Error(
"SetMethod",
"initializing Unuran: condition for method violated");
382 int TUnuran::SampleDiscr()
386 return unur_sample_discr(fGen);
389 double TUnuran::Sample()
393 return unur_sample_cont(fGen);
396 bool TUnuran::SampleMulti(
double * x)
399 if (fGen == 0)
return false;
400 unur_sample_vec(fGen,x);
404 void TUnuran::SetSeed(
unsigned int seed) {
405 return fRng->SetSeed(seed);
408 bool TUnuran::SetLogLevel(
unsigned int debugLevel)
410 if (fGen == 0)
return false;
413 ret |= unur_chg_debug(fGen, UNUR_DEBUG_ALL);
414 else if (debugLevel == 1)
415 ret |= unur_chg_debug(fGen, UNUR_DEBUG_ALL);
417 ret |= unur_chg_debug(fGen, UNUR_DEBUG_OFF);
419 return (ret ==0) ?
true :
false;
423 bool TUnuran::InitPoisson(
double mu,
const std::string & method) {
428 fUdistr = unur_distr_poisson(p,1);
431 if (fUdistr == 0)
return false;
432 if (! SetMethodAndInit() )
return false;
433 if (! SetRandomGenerator() )
return false;
438 bool TUnuran::InitBinomial(
unsigned int ntot,
double prob,
const std::string & method ) {
443 fUdistr = unur_distr_binomial(par,2);
446 if (fUdistr == 0)
return false;
447 if (! SetMethodAndInit() )
return false;
448 if (! SetRandomGenerator() )
return false;
453 bool TUnuran::ReInitDiscrDist(
unsigned int npar,
double * par) {
456 if (!fGen )
return false;
457 if (!fUdistr)
return false;
458 unur_distr_discr_set_pmfparams(fUdistr,par,npar);
459 int iret = unur_reinit(fGen);
460 if (iret) Warning(
"ReInitDiscrDist",
"re-init failed - a full initizialization must be performed");