说明
采用root 作对数坐标图,通常会出现横坐标不是均等宽度分布,这是由于在定义historgram,在设置bin的个数和上下限时默认时均有分割,而不是按对数宽度均匀分割。为此,需要自定义bin的分割位置。
具体代码如下
//--------对数坐标变化--------
double low=1.e-8;
double up=1e4;
double nbin=192;
Double_t xAxis[193];
for ( int i=0; i <= nbin; i++) {
double val_bin=low * std::pow(10., i * std::log10(up/low)/nbin);
double exp_10=4.-int(std::log10(val_bin));
double factor =std::pow(10., exp_10);
val_bin=int(factor*val_bin)/factor;
xAxis[i] = val_bin;
}
TH1D* h1 = new TH1D("h1","h1",192,xAxis);
蒙卡模拟
对这样的histogram 又该如何做随机蒙卡模拟呢?采用求逆的方法
//求和和归一化
double sum=0;
// vals.clear();
for(int ii=0;ii<192;ii++)
{
// value=vals[ii]*(bins[ii]-bins[ii-1]);
// sum = sum+value;
// value=vals[ii];
//*(bins[ii]-bins[ii-1]);
sum = sum+vals[ii];
// cout<<" Sum"<<sum<<endl;
// cout<<""<<vals[ii]<<endl;
}
nvals.clear();
//
double norm=0.;
for(int iii=0;iii<192;iii++)
{
norm = vals[iii]/sum+norm;
cout<<" norm "<<norm<<endl;
// cout<<" vals"<<vals[iii]<<endl;
nvals.push_back(norm);
}
//--------------------------
// 求逆
for(int j=0;j<1000000;j++){
int numberOfBin=nvals.size();
int nmin=0;
int nmid=numberOfBin/2;
int nmax=numberOfBin-1;
double a=rndm.Uniform();
while(nmin!=nmax-1)
{
if(a>nvals[nmid])
nmin=nmid;
else
nmax=nmid;
nmid=nmin+(nmax-nmin+1)/2;
}
double weight=(bins[nmid]-bins[nmid-1])/(nvals[nmid]-nvals[nmid-1]);
double rand=bins[nmid-1]+weight*(a-nvals[nmid-1]);
h1->Fill(rand);
}