Discussion:
[ROOT] TH2D::Integral()
Anil Singh
2009-06-02 13:22:47 UTC
Permalink
Dear Rooters,
I have a TH2D histo, filled with random numbers in range (0,1)
distributed flat in either of axes. The integral is ofcourse equal to
the number of entries filled. But if I divide this x-y plane into four
boxes (by cutting simultaneously on X and Y axis). Now I calculate
the integral for each box, and add those values. Contrary to my
expectations, the value does not turn out to be same as that
obtained by integrating full histo.
//==================
Full Integral: 10000
Box1: 2551
Box2: 2546
Box3: 5053
Box4: 2546
Sum of all Boxes: 12696
//====================

I am also appending my code below.
Anil Singh



//===========================================================

float BoxIntegral(TH2D* h1, float xmin, float xmax, float ymin, float ymax)
{
h1->GetXaxis()->SetRangeUser(xmin,xmax);
h1->GetYaxis()->SetRangeUser(ymin,ymax);
return h1->Integral();

}

void experiment(){

TH2D* h2=new TH2D("h2","test",100,0,1,100,0,1);
TRandom3 r(0);

for (int i=0;i<10000;i++) {
float r1 = r.Rndm();
float r2 = r.Rndm();
h2->Fill(r1,r2);
}
float all=h2->Integral();

float x_cut=0.5;
float y_cut=0.5;

// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);

//Box2
float box2=BoxIntegral(h2,0,x_cut,y_cut,1);

//Box3
float box3=BoxIntegral(h2,x_cut,1,0,y_cut);

//Box4
float box4=BoxIntegral(h2,x_cut,1,0,y_cut);

std::cout<<"Full Integral: "<<all<<endl;
std::cout<<"Box1: "<<box1<<endl;
std::cout<<"Box2: "<<box2<<endl;
std::cout<<"Box3: "<<box3<<endl;
std::cout<<"Box4: "<<box4<<endl;
std::cout<<"Sum of all Boxes: "<<box4+box3+box2+box1<<endl;
}

//========================================================
Mario Kadastik
2009-06-02 13:27:41 UTC
Permalink
Post by Anil Singh
the integral for each box, and add those values. Contrary to my
expectations, the value does not turn out to be same as that
obtained by integrating full histo.
<snip>
Post by Anil Singh
// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);
//Box2
float box2=BoxIntegral(h2,0,x_cut,y_cut,1);
//Box3
float box3=BoxIntegral(h2,x_cut,1,0,y_cut);
//Box4
float box4=BoxIntegral(h2,x_cut,1,0,y_cut);
Aren't you taking a small overlap in the region where x_cut and y_cut
lines overlap? I'd guess that if you exclude the overlap region you
could well end up with the right result. Though the 25% increase is a
bit more than I'd have expected from the overlap in case of 100 x 100
matrix.

Mario
Mario Kadastik
2009-06-02 13:29:12 UTC
Permalink
Post by Mario Kadastik
Post by Anil Singh
// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);
//Box2
float box2=BoxIntegral(h2,0,x_cut,y_cut,1);
//Box3
float box3=BoxIntegral(h2,x_cut,1,0,y_cut);
//Box4
float box4=BoxIntegral(h2,x_cut,1,0,y_cut);
Aren't you taking a small overlap in the region where x_cut and
y_cut lines overlap? I'd guess that if you exclude the overlap
region you could well end up with the right result. Though the 25%
increase is a bit more than I'd have expected from the overlap in
case of 100 x 100 matrix.
Ehh ... it's even simpler :) You have a typo. Your Box3 and Box4 are
identical regions. You should be integrating from y_cut to 1 in Box4
to cover the whole range.

Mario
Anil Singh
2009-06-02 13:36:01 UTC
Permalink
Mario,
yeah, there was a typo actually this was just a
dummy created to reproduce my problem. I corrected
and had a re run:
//-----
Full Integral: 10000
Box1: 2655
Box2: 2556
Box3: 2535
Box4: 2439
Sum of all Boxes: 10185
//----
So as you say, there still may be some double counting.
Is there some easy way to correct this ??
Anil



----- Original Message -----
From: Mario Kadastik <***@cern.ch>
Date: Tuesday, June 2, 2009 6:59 pm
Subject: Re: [ROOT] TH2D::Integral()
Post by Mario Kadastik
Post by Mario Kadastik
Post by Anil Singh
// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);
//Box2
float box2=BoxIntegral(h2,0,x_cut,y_cut,1);
//Box3
float box3=BoxIntegral(h2,x_cut,1,0,y_cut);
//Box4
float box4=BoxIntegral(h2,x_cut,1,0,y_cut);
Aren't you taking a small overlap in the region where x_cut and
y_cut lines overlap? I'd guess that if you exclude the overlap
region you could well end up with the right result. Though the 25%
increase is a bit more than I'd have expected from the overlap in
case of 100 x 100 matrix.
Ehh ... it's even simpler :) You have a typo. Your Box3 and Box4 are
identical regions. You should be integrating from y_cut to 1 in Box4
to cover the whole range.
Mario
Philip Rodrigues
2009-06-02 13:38:10 UTC
Permalink
SetRangeUser is inclusive - if you give it a bin edge, it includes that
bin. So when you ask for [0, 0.5] you get the bin with low edge at 0.5,
and when you ask for [0.5, 1] you also get that bin. One way round it is:

const double eps=1e-3;

// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);

//Box2
float box2=BoxIntegral(h2,0,x_cut-eps,y_cut+eps,1.1);

//Box3
float box3=BoxIntegral(h2,x_cut+eps,1.1,0,y_cut-eps);

//Box4

float box4=BoxIntegral(h2,x_cut+eps,1,y_cut+eps,1);


Regards,
Philip
Post by Anil Singh
Mario,
yeah, there was a typo actually this was just a
dummy created to reproduce my problem. I corrected
//-----
Full Integral: 10000
Box1: 2655
Box2: 2556
Box3: 2535
Box4: 2439
Sum of all Boxes: 10185
//----
So as you say, there still may be some double counting.
Is there some easy way to correct this ??
Anil
----- Original Message -----
Date: Tuesday, June 2, 2009 6:59 pm
Subject: Re: [ROOT] TH2D::Integral()
Post by Mario Kadastik
Post by Mario Kadastik
Post by Anil Singh
// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);
//Box2
float box2=BoxIntegral(h2,0,x_cut,y_cut,1);
//Box3
float box3=BoxIntegral(h2,x_cut,1,0,y_cut);
//Box4
float box4=BoxIntegral(h2,x_cut,1,0,y_cut);
Aren't you taking a small overlap in the region where x_cut and
y_cut lines overlap? I'd guess that if you exclude the overlap
region you could well end up with the right result. Though the 25%
increase is a bit more than I'd have expected from the overlap in
case of 100 x 100 matrix.
Ehh ... it's even simpler :) You have a typo. Your Box3 and Box4 are
identical regions. You should be integrating from y_cut to 1 in Box4
to cover the whole range.
Mario
m***@gmail.com
2009-06-02 13:42:50 UTC
Permalink
You had two problems - The double counting is for the reasons Mario
suggested.

The value 0.5 falls into the 0.50->0.51 bin, and so when you set to the
range 0,0.5 you are actually taking bins 1->51. If you plot the histogram
and try to scale the axis from 0 to 0.5, you will see it actually refuses
to cut off a bin and so instead draws 0->0.51.

To fix this, you either want to take the range 0->0.4999...., or, perhaps
better, calculate the integral on bin range ie
box2 = h2->Integral(0, 50, 51, 101);

which also takes into account the overflow bins (if you wanted!).

Nick
Post by Anil Singh
Mario,
yeah, there was a typo actually this was just a
dummy created to reproduce my problem. I corrected
//-----
Full Integral: 10000
Box1: 2655
Box2: 2556
Box3: 2535
Box4: 2439
Sum of all Boxes: 10185
//----
So as you say, there still may be some double counting.
Is there some easy way to correct this ??
Anil
----- Original Message -----
Date: Tuesday, June 2, 2009 6:59 pm
Subject: Re: [ROOT] TH2D::Integral()
Post by Mario Kadastik
Post by Mario Kadastik
Post by Anil Singh
// Box1
float box1=BoxIntegral(h2,0,x_cut,0,y_cut);
//Box2
float box2=BoxIntegral(h2,0,x_cut,y_cut,1);
//Box3
float box3=BoxIntegral(h2,x_cut,1,0,y_cut);
//Box4
float box4=BoxIntegral(h2,x_cut,1,0,y_cut);
Aren't you taking a small overlap in the region where x_cut and
y_cut lines overlap? I'd guess that if you exclude the overlap
region you could well end up with the right result. Though the 25%
increase is a bit more than I'd have expected from the overlap in
case of 100 x 100 matrix.
Ehh ... it's even simpler :) You have a typo. Your Box3 and Box4 are
identical regions. You should be integrating from y_cut to 1 in Box4
to cover the whole range.
Mario
Continue reading on narkive:
Loading...