00001
00002
00003
00004
00005
00006
00007 #include "TStopwatch.h"
00008 #include "TUnuran.h"
00009 #include "TUnuranMultiContDist.h"
00010
00011 #include "TH2.h"
00012 #include "TF2.h"
00013 #include "TCanvas.h"
00014 #include "TMath.h"
00015
00016 #include "TRandom3.h"
00017 #include "TSystem.h"
00018 #include "TApplication.h"
00019 #include "TError.h"
00020
00021 #include "Math/Functor.h"
00022
00023
00024
00025
00026 #define _USE_MATH_DEFINES // for Windows
00027 #include <cmath>
00028 #include <iostream>
00029
00030
00031
00032 using std::cout;
00033 using std::endl;
00034
00035 int n = 1000000;
00036
00037 bool useRandomSeed = false;
00038
00039 double gaus2d(double *x, double *p) {
00040
00041 double sigma_x = p[0];
00042 double sigma_y = p[1];
00043 double rho = p[2];
00044 double u = x[0] / sigma_x ;
00045 double v = x[1] / sigma_y ;
00046 double c = 1 - rho*rho ;
00047 double result = (1 / (2 * TMath::Pi() * sigma_x * sigma_y * sqrt(c)))
00048 * exp (-(u * u - 2 * rho * u * v + v * v ) / (2 * c));
00049 return result;
00050 }
00051
00052 double log_gaus2d(double *x, double *p) {
00053
00054 return std::log( gaus2d(x,p) );
00055 }
00056
00057
00058
00059 int testUnuran(TUnuran & unr, const std::string & method, const TUnuranMultiContDist & dist, TH2 * h1, const TH2 * href ) {
00060
00061 #ifdef DEBUG
00062 n = 1000;
00063 #endif
00064
00065
00066
00067 bool ret = unr.Init(dist,method);
00068 if (!ret) {
00069 std::cerr << "Error initializing unuran with method " << unr.MethodName() << endl;
00070 return -1;
00071 }
00072
00073 h1->Reset();
00074
00075
00076 TStopwatch w;
00077
00078 w.Start();
00079 double x[2];
00080 for (int i = 0; i < n; ++i) {
00081 unr.SampleMulti(x);
00082 h1->Fill(x[0],x[1]);
00083 if (method == "gibbs" && i < 100)
00084 std::cout << x[0] << " , " << x[1] << std::endl;
00085 }
00086
00087 w.Stop();
00088 double time = w.CpuTime()*1.E9/n;
00089
00090 double prob = href->Chi2Test(h1,"UU");
00091 double ksprob = href->KolmogorovTest(h1);
00092 cout << "Time using Unuran " << unr.MethodName() << " \t=\t " << time << "\tns/call \t\tChi2 Prob = "
00093 << prob << "\tKS Prob = " << ksprob << std::endl;
00094 if (prob < 1E-06) {
00095 std::cout << "Chi2 Test failed ! " << std::endl;
00096 href->Chi2Test(h1,"UUP");
00097 return 1;
00098 }
00099 return 0;
00100 }
00101
00102 int testGetRandom(TF2 * f, TH1 * h1, const TH2 * href = 0) {
00103
00104
00105
00106 h1->Reset();
00107
00108 TStopwatch w;
00109 w.Start();
00110 double x[2] = {0,0};
00111 for (int i = 0; i < n; ++i) {
00112 f->GetRandom2(x[0],x[1]);
00113 h1->Fill(x[0],x[1]);
00114 }
00115
00116 w.Stop();
00117 double time = w.CpuTime()*1.E9/n;
00118
00119
00120 if (href != 0) {
00121 double prob = href->Chi2Test(h1,"UU");
00122 std::cout << "Time using TF1::GetRandom() \t=\t " << time << "\tns/call \t\tChi2 Prob = "<< prob << std::endl;
00123 if (prob < 1E-06) {
00124 std::cout << "Chi2 Test failed ! " << std::endl;
00125 href->Chi2Test(h1,"UUP");
00126 return 2;
00127 }
00128 }
00129 else
00130 std::cout << "Time using TF1::GetRandom() \t=\t " << time << "\tns/call\n";
00131 return 0;
00132 }
00133
00134
00135 int unuranMulti2D() {
00136
00137
00138 if (useRandomSeed) gRandom->SetSeed(0);
00139
00140
00141 gErrorIgnoreLevel = 1001;
00142
00143
00144 gSystem->Load("libMathCore");
00145 gSystem->Load("libUnuran");
00146
00147
00148
00149
00150
00151 TH2D * h1 = new TH2D("h1","UNURAN gaussian 2D distribution",100,-10,10,100,-10,10);
00152 TH2D * h2 = new TH2D("h2","TF1::GetRandom gaussian 2D distribution",100,-10,10,100,-10,10);
00153
00154 TH2D * h3 = new TH2D("h3","UNURAN truncated gaussian 2D distribution",100,-1,1,100,-1,1);
00155 TH2D * h4 = new TH2D("h4","TF1::GetRandom truncated gaussian 2D distribution",100,-1,1,100,-1,1);
00156
00157
00158 TF2 * f = new TF2("g2d",gaus2d,-10,10,-10,10,3);
00159 double par[3] = {1,1,0.5};
00160 f->SetParameters(par);
00161
00162 TF2 * flog = new TF2("logg2d",log_gaus2d,-10,10,-10,10,3);
00163 flog->SetParameters(par);
00164
00165
00166 f->SetNpx(100);
00167 f->SetNpy(100);
00168 std::cout << " Nimber of function points in TF1, Npx = " << f->GetNpx() << " Npy = " << f->GetNpy() << std::endl;
00169
00170
00171 std::cout << "Test using an undefined domain :\n\n";
00172
00173
00174 testGetRandom(f,h2);
00175
00176
00177 TUnuranMultiContDist dist(f);
00178
00179
00180
00181
00182
00183 TUnuran unr(gRandom,2);
00184
00185 int iret = 0;
00186 TH2 * href = h2;
00187
00188
00189 std::string method = "vnrou";
00190 iret |= testUnuran(unr, method, dist, h1, href);
00191
00192
00193
00194 method = "hitro";
00195 iret |= testUnuran(unr, method, dist, h1, href);
00196
00197
00198
00199 #ifdef USE_GIBBS
00200 method = "gibbs";
00201
00202 TUnuranMultiContDist logdist(flog,0,true);
00203 iret |= testUnuran(unr, method, logdist, h1, href);
00204 #endif
00205
00206
00207 cout << "\nTest setting the mode in Unuran distribution:\n\n";
00208 double m[2] = {0,0};
00209 dist.SetMode(m);
00210
00211 method = "vnrou";
00212 iret |= testUnuran(unr, method, dist, h1, href);
00213
00214 method = "hitro";
00215 iret |= testUnuran(unr, method, dist, h1, href);
00216
00217 #ifdef USE_GIBBS
00218 method = "gibbs";
00219 logdist.SetMode(m);
00220 iret |= testUnuran(unr, method, logdist, h1, href);
00221 #endif
00222
00223
00224
00225
00226
00227
00228
00229 double xmin[2] = { -1, -1 };
00230 double xmax[2] = { 1, 1 };
00231
00232 f->SetRange(xmin[0],xmin[1],xmax[0],xmax[1]);
00233
00234 dist.SetDomain(xmin,xmax);
00235
00236 const double *xlow = dist.GetLowerDomain();
00237 const double *xup = dist.GetUpperDomain();
00238 cout << "\nTest truncated distribution in domain [ " << xlow[0] << " : " << xup[0]
00239 << " , " << xlow[1] << " : " << xup[1] << " ] :\n\n";
00240
00241
00242 testGetRandom(f,h4);
00243
00244 method = "vnrou";
00245 iret |= testUnuran(unr, method, dist, h3, h4);
00246 method = "hitro";
00247 iret |= testUnuran(unr, method, dist, h3, h4);
00248 #ifdef USE_GIBBS
00249 logdist.SetDomain(xmin,xmax);
00250 method = "gibbs";
00251 iret |= testUnuran(unr, method, logdist, h3, h4);
00252 #endif
00253
00254
00255 TCanvas * c1 = new TCanvas("c1_unuran2D","Multidimensional distribution",10,10,900,900);
00256 c1->Divide(2,2);
00257 #ifdef NO_TRUNC
00258 TCanvas * c1 = new TCanvas("c1_unuran2D","Multidimensional distribution",10,10,500,500);
00259 c1->Divide(1,2);
00260 #endif
00261
00262
00263 c1->cd(1);
00264 h1->Draw("col");
00265
00266
00267 c1->cd(2);
00268 h2->Draw("col");
00269
00270 c1->cd(3);
00271 h3->Draw("col");
00272 c1->cd(4);
00273 h4->Draw("col");
00274
00275
00276 if (iret != 0)
00277 std::cerr <<"\n\nUnuRan 2D Continous Distribution Test:\t Failed !!!!!!!\n" << std::endl;
00278 else
00279 std::cerr << "\n\nUnuRan 2D Continous Distribution Test:\t OK\n" << std::endl;
00280
00281 return iret;
00282
00283 }
00284
00285 #ifndef __CINT__
00286 int main(int argc, char **argv)
00287 {
00288 int iret = 0;
00289 if (argc > 1) {
00290 TApplication theApp("App",&argc,argv);
00291 iret = unuranMulti2D();
00292 theApp.Run();
00293 }
00294 else
00295 iret = unuranMulti2D();
00296
00297 return iret;
00298 }
00299 #endif