void mcmc(double *chi, double *a, double *b, double *c, double *d, double *x, double *t, int numT, int iterMCMC){ /*Inicializa el RNG gausiano y el uniforme*/ const gsl_rng_type * T; gsl_rng * r; gsl_rng_env_setup(); T = gsl_rng_default; r = gsl_rng_alloc (T); srand48(time(NULL)); //Corremos ran_gaussian un numero aleatorio de veces para cumplir la funcion de la semilla int semillaGauss; semillaGauss=(int) floor(drand48()*100); int n; for (n=0;n<semillaGauss;n++){ gsl_ran_gaussian(r,1); } /*Otras variables*/ double aNew,bNew,cNew,dNew, chiNew; double step=0.7; int i; for(i=0;i<iterMCMC-1;i++){ aNew=a[i]+gsl_ran_gaussian(r, step); bNew=b[i]+gsl_ran_gaussian(r, step); cNew=c[i]+gsl_ran_gaussian(r, step); dNew=d[i]+gsl_ran_gaussian(r, step); chi[i]=chi2(a[i],b[i],c[i],d[i],x,t,numT); chiNew=chi2(aNew,bNew,cNew,dNew,x,t,numT); if(chiNew<chi[i]){ a[i+1]=aNew; b[i+1]=bNew; c[i+1]=cNew; d[i+1]=dNew; } else{ double p=exp(chi[i]-chiNew); if(p>drand48()){ a[i+1]=aNew; b[i+1]=bNew; c[i+1]=cNew; d[i+1]=dNew; } else{ a[i+1]=a[i]; b[i+1]=b[i]; c[i+1]=c[i]; d[i+1]=d[i]; } } } chi[i]=chi2(a[i],b[i],c[i],d[i],x,t,numT); }
void fitSimAnneal::init(chi2type chi2f, double* initParams, unsigned int pcount, double* lBounds, double* uBounds) { lowerBounds=lBounds; upperBounds=uBounds; // reset function evaluation and iteration counters chi2EvalCount=0; iterations=0; chi2=chi2f; fitParamCount=pcount; // init random number generator randSeed(); param=(double*)realloc(param, fitParamCount*sizeof(double)); memcpy(param, initParams, fitParamCount*sizeof(double)); x0=(double*)realloc(x0, fitParamCount*sizeof(double)); memcpy(x0, initParams, fitParamCount*sizeof(double)); currentChi2=chi2(x0, fitParamCount); bestChi2=currentChi2; // init step vector v v=(double*)realloc(v, fitParamCount*sizeof(double)); for (unsigned int i=0; i<fitParamCount; i++) { v[i]=fabs(upperBounds[i]-lowerBounds[i])/10.0; } }
//============================================================================ // Print some debug info //============================================================================ void TbKalmanTrack::print() const { std::cout << "This is a kalman fitted tracks with chi2/ndof=" << chi2() << "/" << ndof() << std::endl; // compute forward/backward chi2 LHCb::ChiSquare forwardchi2, backwardchi2; double chi2X(0), chi2Y(0); std::cout << "These are the nodes, with some residuals: " << std::endl; for (const LHCb::TbKalmanNode * node : m_nodes) { std::cout << node->index() << " " << node->z() << " "; //<< node->hasInfoUpstream( LHCb::TbKalmanNode::Forward) << " " //<< node->hasInfoUpstream( LHCb::TbKalmanNode::Backward) << " " ; printState(node->state(), std::cout); //std::cout << node->filterStatus( LHCb::TbKalmanNode::Forward) << " " //<< node->filterStatus( LHCb::TbKalmanNode::Backward) << " " ; const TbKalmanPixelMeasurement* pixelhit = dynamic_cast<const TbKalmanPixelMeasurement*>(node); if (pixelhit) { std::cout << "residual x = " << pixelhit->residualX() << " +/- " << std::sqrt(pixelhit->residualCovX()) << " " << "residual y = " << pixelhit->residualY() << " +/- " << std::sqrt(pixelhit->residualCovY()) << " "; chi2X += pixelhit->residualX() * pixelhit->residualX() / pixelhit->covX(); chi2Y += pixelhit->residualY() * pixelhit->residualY() / pixelhit->covY(); } std::cout << std::endl; forwardchi2 += node->deltaChi2(LHCb::TbKalmanNode::Forward); backwardchi2 += node->deltaChi2(LHCb::TbKalmanNode::Backward); } std::cout << "Forward/backward chi2: " << forwardchi2.chi2() << "/" << backwardchi2.chi2() << std::endl; std::cout << "X/Y chi2: " << chi2X << "/" << chi2Y << std::endl; }
int main() { typedef funct::Product<funct::Parameter, funct::BreitWigner>::type FitFunction; typedef fit::HistoChiSquare<FitFunction> ChiSquared; try { funct::Parameter yield("Yield", 1000); funct::Parameter mass("Mass", 91.2); funct::Parameter gamma("Gamma", 2.50); funct::BreitWigner bw(mass, gamma); FitFunction f = yield * bw; TF1 startFun = root::tf1("startFun", f, 0, 200, yield, mass, gamma); TH1D histo("histo", "Z mass (GeV/c)", 200, 0, 200); histo.FillRandom("startFun", yield); ChiSquared chi2(f, &histo, 80, 120); fit::RootMinuit<ChiSquared> minuit(chi2, true); minuit.addParameter(yield, 100, 0, 10000); minuit.addParameter(mass, 2, 70, 120); minuit.addParameter(gamma, 1, 0, 5); minuit.minimize(); minuit.migrad(); } catch(std::exception & err){ std::cerr << "Exception caught:\n" << err.what() << std::endl; return 1; } return 0; }
static PyObject * func_sat(PyObject *self, PyObject *args) { /* Saturation recovery experiment target function for calculating and returning the chi-squared value. * * Firstly the back calculated intensities are generated, then the chi-squared statistic is * calculated. */ /* Declarations. */ PyObject *params_arg; /* Parse the function arguments, the only argument should be the parameter array. */ if (!PyArg_ParseTuple(args, "O", ¶ms_arg)) return NULL; /* Convert the parameters Python list to a C array. */ param_to_c(params_arg); /* Back calculated the peak intensities. */ exponential_sat(params[index_Iinf], params[index_R], relax_times, back_calc, num_times); /* Calculate and return the chi-squared value. */ return PyFloat_FromDouble(chi2(values, variance, back_calc, num_times)); }
void test_staggered() { mdp << "START TESTING STAGGERED ACTIONS\n"; int box[]={64,6,6,6}, nc=3; generic_lattice lattice(4,box,default_partitioning<0>, torus_topology, 0, 3); gauge_field U(lattice,nc); gauge_field V(lattice,nc); staggered_field psi(lattice, nc); staggered_field chi1(lattice, nc); staggered_field chi2(lattice, nc); coefficients coeff; coeff["mass"]=1.0; double t0, t1; inversion_stats stats; set_hot(U); set_random(psi); mdp << "ATTENTION: need to adjust asqtad coefficnets\n"; default_staggered_action=StaggeredAsqtadActionFast::mul_Q; default_staggered_inverter=MinimumResidueInverter<staggered_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Staggered Min Res TIME=" << t1 << endl; default_staggered_inverter=BiConjugateGradientStabilizedInverter<staggered_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Staggered BiCGStab TIME=" << t1 << endl; default_staggered_inverter=StaggeredBiCGUML::inverter; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Staggered SSE BiCGStabUML TIME=" << t1 << endl; default_staggered_action=StaggeredAsqtadActionSSE2::mul_Q; default_staggered_inverter=MinimumResidueInverter<staggered_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Staggered SSE Min Res TIME=" << t1 << endl; default_staggered_inverter=BiConjugateGradientStabilizedInverter<staggered_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Staggered SSE BiCGStab TIME=" << t1 << endl; default_staggered_inverter=StaggeredBiCGUML::inverter; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Staggered SSE BiCGStabUML TIME=" << t1 << endl; }
Double_t getShiftChi2(const Double_t* thetaPhi) { Double_t chi2(0), c(0); TVector3 norm; norm.SetMagThetaPhi(1.0, thetaPhi[0], thetaPhi[1]); for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) { for (Int_t xc=0; xc<ch; ++xc) { Double_t dtcor=0; for (Int_t i=(ch-xc); i>0; --i) { dtcor += dtCorrs[ch-i]; } const TVector3& posCh = getStnPos(ch); const TVector3& posXc = getStnPos(xc); const Double_t disCh = -(posCh.Dot(norm)); const Double_t disXc = -(posXc.Dot(norm)); // !!! check sign of delta(distance) and dtcor! const Double_t dt = kSmpRate * ( // from ns to samples ( (disCh-disXc) * kNgTopFern / kC_m_ns ) // from m to ns + dtcor ); // correct dt offset (ns) // FIXME: dt in samples, maxdt in ns if (TMath::Abs(dt)>maxdt) { // really don't like being out of bounds c = TMath::Exp(dt*dt); if (c>kReallyBig) { c = kReallyBig; } } else { // get the correlation coefficient for this dt (in num samples) c = gspc[ch][xc]->Eval(dt) - 1.0; } chi2 += c*c; } } return chi2; }
inline RealType rng_dist_chi2( const vsmc::Vector<RealType> &r, const vsmc::Vector<RealType> &partition) { vsmc::Vector<std::size_t> count(partition.size() + 1); vsmc::Vector<RealType> rval(r); std::sort(rval.begin(), rval.end()); std::size_t j = 0; for (std::size_t i = 0; i != partition.size(); ++i) { std::size_t n = 0; while (j != rval.size() && rval[j] <= partition[i]) { ++n; ++j; } count[i] = n; } count.back() = rval.size() - j; RealType e = static_cast<RealType>(1.0 / partition.size() * rval.size()); RealType p = 0; for (std::size_t i = 0; i != partition.size(); ++i) p += (count[i] - e) * (count[i] - e) / e; boost::math::chi_squared_distribution<RealType> chi2( static_cast<RealType>(partition.size() - 1)); return boost::math::cdf(chi2, p); }
//============================================================================ // Perform the fit //============================================================================ void TbKalmanTrack::fit() { // remove existing states clearStates(); // do the fit if (!m_nodes.empty()) { // initialize the seed: very simple for now. later we may want // to run some iterations and then this becomes more // complicated. LHCb::TbState seedstate(firstState()); Gaudi::SymMatrix4x4 seedcov; seedcov(0, 0) = seedcov(1, 1) = 1e4; seedcov(2, 2) = seedcov(3, 3) = 1; seedstate.covariance() = seedcov; m_nodes.front()->setSeed(seedstate); m_nodes.back()->setSeed(seedstate); // everything happens on demand, I hope. so all we need to do is copy the // smoothed states back. LHCb::ChiSquare chi2(0, -4); for (LHCb::TbKalmanNode* node : m_nodes) { // get the smoothed state addToStates(node->state()); // add to the chi2 chi2 += node->deltaChi2(0); } setNdof(chi2.nDoF()); if (chi2.nDoF() > 0) { setChi2PerNdof(chi2.chi2() / chi2.nDoF()); } else { setChi2PerNdof(0); } } }
void fit(boot &A,boot &B,boot &C,bvec &X,bvec &Y) { //copy X X_fit=new double[nens]; for(int iens=0;iens<nens;iens++) X_fit[iens]=X[iens].med(); Y_fit=new double[nens]; err_Y_fit=new double[nens]; TMinuit minu; minu.SetPrintLevel(-1); minu.DefineParameter(0,"A",0.0,0.0001,0,0); minu.DefineParameter(1,"B",0.0,0.0001,0,0); minu.DefineParameter(2,"C",0.0,0.0001,0,0); minu.SetFCN(chi2_wr); double C2; for(int iboot=0;iboot<nboot+1;iboot++) { if(iboot>0) minu.SetPrintLevel(-1); minu.DefineParameter(3,"a380",lat[0][iboot],0.0001,0,0); minu.DefineParameter(4,"a390",lat[1][iboot],0.0001,0,0); minu.DefineParameter(5,"a405",lat[2][iboot],0.0001,0,0); minu.DefineParameter(6,"a420",lat[3][iboot],0.0001,0,0); minu.FixParameter(3); minu.FixParameter(4); minu.FixParameter(5); minu.FixParameter(6); for(int iens=0;iens<nens;iens++) { Y_fit[iens]=Y.data[iens].data[iboot]; err_Y_fit[iens]=Y.data[iens].err(); } //minimize minu.Migrad(); //get back parameters double dum; minu.GetParameter(0,A.data[iboot],dum); minu.GetParameter(1,B.data[iboot],dum); minu.GetParameter(2,C.data[iboot],dum); double lat_med[4]={lat[0].med(),lat[1].med(),lat[2].med(),lat[3].med()}; if(iboot==0) C2=chi2(A.data[iboot],B[iboot],C[iboot],lat_med); } //calculate the chi2 cout<<"A = ("<<A<<"), B=("<<B<<"), C=("<<C<<")"<<endl; cout<<"Chi2 = "<<C2<<" / "<<nens-3<<" = "<<C2/(nens-3)<<endl; delete[] X_fit; delete[] Y_fit; delete[] err_Y_fit; }
// Computes the p-value of X for a chi^2 distribution with a given df double pvalue_chi2 (double X, int df) { if (boost::math::isinf(X)) { return 0.; } else { boost::math::chi_squared chi2(df); return 1 - boost::math::cdf(chi2, X); } }
static double obs_vector_chi2__(const obs_vector_type * obs_vector , int report_step , const enkf_node_type * node, node_id_type node_id) { void * obs_node = vector_iget( obs_vector->nodes , report_step ); if ( obs_node != NULL) return obs_vector->chi2( obs_node , enkf_node_value_ptr( node ), node_id); else return 0.0; /* Observation not active for this report step. */ }
Double_t getShiftLL(const Double_t* thetaPhi) { Double_t chi2(1), c(0), oo(0); TVector3 norm; norm.SetMagThetaPhi(1.0, thetaPhi[0], thetaPhi[1]); for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) { for (Int_t xc=0; xc<ch; ++xc) { Double_t dtcor=0; for (Int_t i=(ch-xc); i>0; --i) { dtcor += dtCorrs[ch-i]; } const TVector3& posCh = getStnPos(ch); const TVector3& posXc = getStnPos(xc); const Double_t disCh = -(posCh.Dot(norm)); const Double_t disXc = -(posXc.Dot(norm)); // !!! check sign of delta(distance) and dtcor! Double_t dt = ( (disCh-disXc) * kNgTopFern / kC_m_ns ) // from m to ns + dtcor; // correct dt offset (ns) const Double_t odt = dt; Bool_t oob=kFALSE; if (dt<-maxdt) { dt = -maxdt; oob = kTRUE; } else if (dt>maxdt) { dt = maxdt; oob = kTRUE; } dt *= kSmpRate; c = getProbFromCorrCoef(gspl[ch][xc]->Eval(dt)); if (oob) { const Double_t wa = TMath::Abs(odt) - maxdt; oo += wa*wa; } /* if (TMath::Abs(dt)>maxdt) { // really don't like being out of bounds c = TMath::Exp(-dt*dt); } else { // get the correlation coefficient for this dt (in num samples) const Double_t corco = gspl[ch][xc]->Eval(dt); c = getProbFromCorrCoef(corco); } if (c>1.0) { Fatal("getShiftLL","Got ll term > 1 (%g)",c); } */ chi2 *= c; } } chi2 = -TMath::Log(chi2); chi2 += oo; return chi2; }
void applypvalue(std::string iName="BDTOutput.root") { TFile *lFile = new TFile(iName.c_str()); TTree *lTree = (TTree*) lFile->FindObjectAny("Result"); fMVA = 0; lTree->SetBranchAddress("bdt" ,&fMVA); fPFType = 0; lTree->SetBranchAddress("pftype",&fPFType); fGenPt = 0; lTree->SetBranchAddress("genpt" ,&fGenPt); fPt = 0; lTree->SetBranchAddress("pt" ,&fPt); float *lMean = new float[6]; float *lRMS = new float[6]; computeMeanRMS(lMean,lRMS,lTree); TFile *lOFile = new TFile("Output.root","RECREATE"); TTree *lOTree = (TTree*) lTree->CloneTree(0); float lChi2PV = 0; lOTree->Branch("chi2pv",&lChi2PV,"lChi2PV/F"); float lChi2PU = 0; lOTree->Branch("chi2pu",&lChi2PU,"lChi2PU/F"); float lProb = 0; lOTree->Branch("prob" ,&lProb ,"lProb/F" ); for(int i0 = 0; i0 < lTree->GetEntries(); i0++) { lTree->GetEntry(i0); lChi2PV = chi2(0,lMean,lRMS); lChi2PU = chi2(1,lMean,lRMS); float pP1 = TMath::Prob(lChi2PV,1.); float pP2 = TMath::Prob(lChi2PU,1.); lProb = pP1*(1-pP2); lProb *= 2.; if(lProb > 1) lProb = 1; //if(fPFType == 1) std::cout << " --> " << lChi2PV << " -- " << pP1 << " -- " << lChi2PU << " -- " << pP2 << " -- " << -2*log(pP1/pP2) << " -- " << lProb << std::endl; if(fPFType > 5) { lProb = 1; } lOTree->Fill(); } lOTree->Write(); }
static PyObject *chi2_chi2(PyObject *self, PyObject *args) { double m, b; PyObject *x_obj, *y_obj, *yerr_obj; /* Parse the input tuple */ if (!PyArg_ParseTuple(args, "ddOOO", &m, &b, &x_obj, &y_obj, &yerr_obj)) return NULL; /* Interpret the input objects as numpy arrays. */ PyObject *x_array = PyArray_FROM_OTF(x_obj, NPY_DOUBLE, NPY_IN_ARRAY); PyObject *y_array = PyArray_FROM_OTF(y_obj, NPY_DOUBLE, NPY_IN_ARRAY); PyObject *yerr_array = PyArray_FROM_OTF(yerr_obj, NPY_DOUBLE, NPY_IN_ARRAY); /* If that didn't work, throw an exception. */ if (x_array == NULL || y_array == NULL || yerr_array == NULL) { Py_XDECREF(x_array); Py_XDECREF(y_array); Py_XDECREF(yerr_array); return NULL; } /* How many data points are there? */ int N = (int)PyArray_DIM(x_array, 0); /* Get pointers to the data as C-types. */ double *x = (double*)PyArray_DATA(x_array); double *y = (double*)PyArray_DATA(y_array); double *yerr = (double*)PyArray_DATA(yerr_array); /* Call the external C function to compute the chi-squared. */ double value = chi2(m, b, x, y, yerr, N); /* Clean up. */ Py_DECREF(x_array); Py_DECREF(y_array); Py_DECREF(yerr_array); if (value < 0.0) { PyErr_SetString(PyExc_RuntimeError, "Chi-squared returned an impossible value."); return NULL; } /* Build the output tuple */ PyObject *ret = Py_BuildValue("d", value); return ret; }
void test_clover() { mdp << "START TESTING CLOVER ACTIONS\n"; int box[]={64,6,6,6}, nc=3; generic_lattice lattice(4,box); gauge_field U(lattice,nc); fermi_field psi(lattice, nc); fermi_field chi2(lattice, nc); coefficients coeff; coeff["kappa_s"]=0.1; coeff["kappa_t"]=0.1; coeff["c_{sw}"]=1.00; set_hot(U); compute_em_field(U); set_random(psi); double t0,t1; inversion_stats stats; default_fermi_action=FermiCloverActionFast::mul_Q; default_fermi_inverter=MinimumResidueInverter<fermi_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Clover Min Res TIME=" << t1 << endl; default_fermi_inverter=BiConjugateGradientStabilizedInverter<fermi_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Clover BiCGStab TIME=" << t1 << endl; default_fermi_action=FermiCloverActionSSE2::mul_Q; default_fermi_inverter=MinimumResidueInverter<fermi_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Clover SSE Min Res TIME=" << t1 << endl; default_fermi_inverter=BiConjugateGradientStabilizedInverter<fermi_field,gauge_field>; t0=mpi.time(); stats=mul_invQ(chi2,psi,U,coeff); t1=(mpi.time()-t0)/lattice.nvol_gl/stats.steps; cout << "Clover SSE BiCGStab TIME=" << t1 << endl; }
void plotter::draw_chi2(TF1 * fit_, std::vector<double> masses_, std::vector<double> chi2_, double mass, double uncert, TString file_name){ TF1 * fit = (TF1*)fit_->Clone("fit"); TVectorD masses(masses_.size()); TVectorD chi2(chi2_.size()); for(int i=0; i<masses_.size(); i++) masses[i] = masses_[i]; for(int i=0; i<chi2_.size(); i++) chi2[i] = chi2_[i]; TGraph* chi_hist = new TGraph(masses,chi2); TCanvas *c = new TCanvas("Chi2", "", 600, 600); gPad->SetLeftMargin(0.15); TGaxis::SetMaxDigits(3); chi_hist->SetTitle(" "); chi_hist->GetXaxis()->SetTitle("m_{top}^{MC} [GeV]"); chi_hist->GetYaxis()->SetTitle("#chi^{2}"); chi_hist->GetYaxis()->SetTitleOffset(1.1); chi_hist->GetXaxis()->SetTitleOffset(0.9); chi_hist->GetYaxis()->SetTitleSize(0.05); chi_hist->GetXaxis()->SetTitleSize(0.05); chi_hist->GetXaxis()->SetNdivisions(505); chi_hist->GetYaxis()->SetNdivisions(505); chi_hist->SetMarkerStyle(20); chi_hist->SetMarkerSize(1.5); chi_hist->SetLineColor(1); chi_hist->Draw("AP"); fit->Draw("SAME"); // write extracted mass value into plot TLatex text; text.SetNDC(kTRUE); text.SetTextFont(43); text.SetTextSize(18); char mass_text[32]; sprintf(mass_text, "%.5g", mass); char uncert_text[32]; if(uncert < 1) sprintf(uncert_text, "%.3g", uncert); else sprintf(uncert_text, "%.4g", uncert); TString masstext = "m_{top}^{MC} = "; masstext += mass_text; masstext += " #pm "; masstext += uncert_text; text.DrawLatex(.4,.6, masstext); c->SaveAs(directory + file_name + ".pdf"); delete c; return; }
static PyObject* chi2_chi2(PyObject* self, PyObject* args) { double m, b; npyarray<double> x, y, yerr; if (!parse_tuple(args, m, b, x, y, yerr)) { return NULL; } double value = chi2(m, b, x.data(), y.data(), yerr.data(), x.size()); if (value < 0.0) { PyErr_SetString(PyExc_RuntimeError, "Chi-squared returned an impossible value."); return NULL; } return Py_BuildValue("d", value); }
Double_t getAngleChi2(const Double_t* thetaPhi) { Double_t chi2(0), c(0); TVector3 norm; norm.SetMagThetaPhi(1.0, thetaPhi[0], thetaPhi[1]); for (Int_t ch=0; ch<NSnConstants::kNchans; ++ch) { for (Int_t xc=0; xc<ch; ++xc) { const TVector3& posCh = getStnPos(ch); const TVector3& posXc = getStnPos(xc); const Double_t disCh = -(posCh.Dot(norm)); const Double_t disXc = -(posXc.Dot(norm)); // !!! check sign of delta(distance) and dtcor! const Double_t dt = (disCh-disXc) * kNgTopFern / kC_m_ns; // from m to ns const Double_t bdt = thetaPhi[2+ch] - thetaPhi[2+xc]; c = (dt-bdt); chi2 += c*c; /* Printf("(%g,%g) d[%d]=%g, d[%d]=%g, bdt=%g, sch=%g, sxc=%g, dt=%g, c=%g", thetaPhi[0]*TMath::RadToDeg(), thetaPhi[1]*TMath::RadToDeg(), ch, thetaPhi[2+ch], xc, thetaPhi[2+xc], bdt, disCh, disXc, dt, c); */ } } #ifdef DEBUG_ANGLE if (dbgth!=0) { dbgth->SetPoint(dbgth->GetN(), thetaPhi[0]*TMath::RadToDeg(), chi2); dbgphi->SetPoint(dbgphi->GetN(), thetaPhi[1]*TMath::RadToDeg(), chi2); } #endif return chi2; }
void fit(boot &A,boot &B,boot &C,boot &D) { //copy ml ml_fit=new double[nens]; for(int iens=0;iens<nens;iens++) ml_fit[iens]=ml[iens].med(); //alloc dM2Pi and dM2K dM2Pi_fit=new double[nens]; err_dM2Pi_fit=new double[nens]; dM2K_fit=new double[nens]; err_dM2K_fit=new double[nens]; TMinuit minu; minu.SetPrintLevel(-1); int npars=4; minu.DefineParameter(0,"A",0.0,0.0001,0,0); minu.DefineParameter(1,"B",0.0,0.0001,0,0); minu.DefineParameter(2,"C",0.0,0.0001,0,0); minu.DefineParameter(3,"D",0.0,0.0001,0,0); minu.SetFCN(chi2_wr); double C2; for(int iboot=0;iboot<nboot+1;iboot++) { if(iboot>0) minu.SetPrintLevel(-1); minu.DefineParameter(4,"a380",lat[0][iboot],0.0001,0,0); minu.DefineParameter(5,"a390",lat[1][iboot],0.0001,0,0); minu.DefineParameter(6,"a405",lat[2][iboot],0.0001,0,0); minu.DefineParameter(7,"a420",lat[3][iboot],0.0001,0,0); minu.FixParameter(4); minu.FixParameter(5); minu.FixParameter(6); minu.FixParameter(7); for(int iens=0;iens<nens;iens++) { dM2Pi_fit[iens]=dM2Pi.data[iens].data[iboot]; err_dM2Pi_fit[iens]=dM2Pi.data[iens].err(); dM2K_fit[iens]=dM2K.data[iens].data[iboot]; err_dM2K_fit[iens]=dM2K.data[iens].err(); } //minimize minu.Migrad(); //get back parameters double dum; minu.GetParameter(0,A.data[iboot],dum); minu.GetParameter(1,B.data[iboot],dum); minu.GetParameter(2,C.data[iboot],dum); minu.GetParameter(3,D.data[iboot],dum); double lat_med[4]={lat[0].med(),lat[1].med(),lat[2].med(),lat[3].med()}; if(iboot==nboot) C2=chi2(A.data[iboot],B[iboot],C[iboot],D[iboot],lat_med,true); } //calculate the chi2 cout<<"A=("<<A<<"), B=("<<B<<"), C=("<<C<<"), D=("<<D<<")"<<endl; cout<<"Chi2 = "<<C2<<" / "<<2*nens-npars<<" = "<<C2/(2*nens-npars)<<endl; delete[] ml_fit; delete[] dM2Pi_fit; delete[] err_dM2Pi_fit; delete[] dM2K_fit; delete[] err_dM2K_fit; }
//wrapper for the calculation of the chi2 void chi2_wr(int &npar,double *fuf,double &ch,double *p,int flag) { double A=p[0],B=p[1],C=p[2],D=p[3]; double *a=p+4; ch=chi2(A,B,C,D,a); }
void LUTUnb ( bool conjugate, const Matrix<Real>& U, const Matrix<Complex<Real>>& shifts, Matrix<Real>& XReal, Matrix<Real>& XImag ) { DEBUG_CSE typedef Complex<Real> C; const Int m = XReal.Height(); const Int n = XReal.Width(); if( conjugate ) XImag *= -1; const Real* UBuf = U.LockedBuffer(); Real* XRealBuf = XReal.Buffer(); Real* XImagBuf = XImag.Buffer(); const Int ldU = U.LDim(); const Int ldXReal = XReal.LDim(); const Int ldXImag = XImag.LDim(); Int k=0; while( k < m ) { const bool in2x2 = ( k+1<m && UBuf[(k+1)+k*ldU] != Real(0) ); if( in2x2 ) { // Solve the 2x2 linear systems via 2x2 QR decompositions produced // by the Givens rotation // | c s | | U(k, k)-shift | = | gamma11 | // | -conj(s) c | | U(k+1,k) | | 0 | // // and by also forming the right two entries of the 2x2 resulting // upper-triangular matrix, say gamma12 and gamma22 // // Extract the constant part of the 2x2 diagonal block, D const Real delta12 = UBuf[ k +(k+1)*ldU]; const Real delta21 = UBuf[(k+1)+ k *ldU]; for( Int j=0; j<n; ++j ) { const C delta11 = UBuf[ k + k *ldU] - shifts.Get(j,0); const C delta22 = UBuf[(k+1)+(k+1)*ldU] - shifts.Get(j,0); // Decompose D = Q R Real c; C s; const C gamma11 = Givens( delta11, C(delta21), c, s ); const C gamma12 = c*delta12 + s*delta22; const C gamma22 = -Conj(s)*delta12 + c*delta22; Real* xRealBuf = &XRealBuf[j*ldXReal]; Real* xImagBuf = &XImagBuf[j*ldXImag]; // Solve against R^T C chi1(xRealBuf[k ],xImagBuf[k ]); C chi2(xRealBuf[k+1],xImagBuf[k+1]); chi1 /= gamma11; chi2 -= gamma12*chi1; chi2 /= gamma22; // Solve against Q^T const C eta1 = c*chi1 - Conj(s)*chi2; const C eta2 = s*chi1 + c*chi2; xRealBuf[k ] = eta1.real(); xImagBuf[k ] = eta1.imag(); xRealBuf[k+1] = eta2.real(); xImagBuf[k+1] = eta2.imag(); // Update x2 := x2 - U12^T x1 blas::Axpy ( m-(k+2), -xRealBuf[k ], &UBuf[ k +(k+2)*ldU], ldU, &xRealBuf[k+2], 1 ); blas::Axpy ( m-(k+2), -xImagBuf[k ], &UBuf[ k +(k+2)*ldU], ldU, &xImagBuf[k+2], 1 ); blas::Axpy ( m-(k+2), -xRealBuf[k+1], &UBuf[(k+1)+(k+2)*ldU], ldU, &xRealBuf[k+2], 1 ); blas::Axpy ( m-(k+2), -xImagBuf[k+1], &UBuf[(k+1)+(k+2)*ldU], ldU, &xImagBuf[k+2], 1 ); } k += 2; } else { for( Int j=0; j<n; ++j ) { Real* xRealBuf = &XRealBuf[j*ldXReal]; Real* xImagBuf = &XImagBuf[j*ldXImag]; C eta1( xRealBuf[k], xImagBuf[k] ); eta1 /= UBuf[k+k*ldU] - shifts.Get(j,0); xRealBuf[k] = eta1.real(); xImagBuf[k] = eta1.imag(); blas::Axpy ( m-(k+1), -xRealBuf[k], &UBuf[k+(k+1)*ldU], ldU, &xRealBuf[k+1], 1 ); blas::Axpy ( m-(k+1), -xImagBuf[k], &UBuf[k+(k+1)*ldU], ldU, &xImagBuf[k+1], 1 ); } k += 1; } } if( conjugate ) XImag *= -1; }
Double_t getDeltaTsLL(const Double_t* dts) { // dts must be indexed like so: // [0] = 1-0 // [1] = 2-1 // [2] = 3-2 // ... // // dt's are then calculated by: // 1-0 = dts[0] = dts[ch-(ch-xc)] = dts[1-(1-0)] // 2-1 = dts[1] = dts[2-(2-1)] // 3-0 = dts[3-(3-0)] + dts[3-(3-0-1)] + dts[3-(3-0-2)] // = dts[0] + dts[1] + dts[2] // = 1-0 + 2-1 + 3-2 = 3-0 Double_t chi2(1), c(0), oo(0); for (Int_t ch=1; ch<NSnConstants::kNchans; ++ch) { for (Int_t xc=0; xc<ch; ++xc) { Double_t dt=0; for (Int_t i=(ch-xc); i>0; --i) { dt += dts[ch-i]; } const Double_t odt = dt; Bool_t oob=kFALSE; if (dt<-maxdt) { dt = -maxdt; oob = kTRUE; } else if (dt>maxdt) { dt = maxdt; oob = kTRUE; } dt *= kSmpRate; // convert to samples c = getProbFromCorrCoef(gspl[ch][xc]->Eval(dt)); if (oob) { const Double_t wa = TMath::Abs(odt) - maxdt; oo += wa*wa; } /* if (TMath::Abs(dt)>maxdt) { // really don't like being out of bounds c = TMath::Power(dt, -2.0); } else { // how acceptable is this dt? const Double_t corco = gspl[ch][xc]->Eval(dt); c = getProbFromCorrCoef(corco); } */ if (isnan(c)) { Printf("d[%g, %g, %g], dt=%g, c=%g", dts[0], dts[1], dts[2], dt, c); Printf("ch=%d, xc=%d, gspl[ch][xc]=%p",ch,xc,gspl[ch][xc]); for (Int_t i=-63; i<63; ++i) { printf("(%d, %g), ", i, gspl[ch][xc]->Eval(i)); } printf("\n"); gspl[ch][xc]->Draw("apl"); if (gPad!=0) { gPad->Update(); gPad->WaitPrimitive(); } } chi2 *= c; } // xc } // ch chi2 = -TMath::Log(chi2); chi2 += oo; return chi2; }
void test1(double N) { Uniform U; double sum = 0.0, sumsq = 0.0, ar1 = 0.0, last = 0.0; double j; Array<double> chi0(0,15); Array<double> chi1(0,255); Array<double> chi1x(0,255); Array<double> chi2(0,65535); Array<double> chi2x(0,65535); chi0 = 0; chi1 = 0; chi1x = 0; chi2 = 0; chi2x = 0; Array<double> crawl7(0,127); Array<double> crawl8(0,255); Array<double> crawl15(0,32767); Array<double> crawl16(0,65535); crawl7 = 0; crawl8 = 0; crawl15 = 0; crawl16 = 0; unsigned long crawler = 0; int m_bits = (int)(log(N) / 0.693 - 0.471); // number of bits in sparse monkey test unsigned long M = 1; M <<= (m_bits - 3); // 2**m_bits / 8 String Seen(M, (char)0); // to accumulate results unsigned long mask1 = (M - 1); for (j = 0; j < N; ++j) { double u = U.Next(); if (u == 1.0) { cout << "Reject value == 1" << endl; continue; } double v = u - 0.5; sum += v; sumsq += v * v; ar1 += v * (last - 0.5); int k = (int)floor(u * 256); ++chi1(k); int m = (int)floor(u * 65536); ++chi2(m); int a = (int)floor(u * 16); ++chi0(a); if (j > 0) { int b = (int)floor(last * 16); ++chi1x(a + 16 * b); int l = (int)floor(last * 256); ++chi2x(k + 256 * l); } last = u; crawler <<= 1; if (v >= 0) ++crawler; if (j >= 6) ++crawl7(crawler & 0x7F); if (j >= 7) ++crawl8(crawler & 0xFF); if (j >= 14) ++crawl15(crawler & 0x7FFF); if (j >= 15) ++crawl16(crawler & 0xFFFF); if ( j >= (unsigned int)(m_bits-1) ) { unsigned char mask2 = 1; mask2 <<= crawler & 7; Seen[(crawler >> 3) & mask1] |= mask2; } }
//============================================================================= /// Fill Histograms for TbKalmanTracks //============================================================================= void TbTracking::fill_khists(std::vector<LHCb::TbKalmanTrack*>& ktracks) { std::vector<LHCb::TbKalmanTrack*>::iterator icktra; for (icktra = ktracks.begin(); icktra != ktracks.end(); icktra++) { // Fill the track histos m_Kfit_chi2->Fill((*icktra)->chi2()); m_Kfit_prob->Fill( TMath::Prob((*icktra)->chi2(), (*icktra)->ndof()) ); // Get the nodes of this TbKalmanTrack //const std::vector<LHCb::TbKalmanNode*>& knodes = (*icktra)->nodes(); // Loop through the nodes of this TbKalmanTrack for( auto node : (*icktra)->nodes() ) { auto pixnode = dynamic_cast< LHCb::TbKalmanPixelMeasurement*>( node) ; if( pixnode ) { int ichip = pixnode->cluster().plane(); // Fill unbiased residuals m_XunresKfit[ichip]->Fill( pixnode->residualX() * pixnode->covX() / pixnode->residualCovX() ); m_YunresKfit[ichip]->Fill( pixnode->residualY() * pixnode->covY() / pixnode->residualCovY() ); // Fill biased residuals m_XresKfit[ichip]->Fill( pixnode->residualX() ); m_YresKfit[ichip]->Fill( pixnode->residualY() ); // Fill biased residuals on X,Y m_XresKfitOnX[ichip]->Fill( pixnode->cluster().x() , pixnode->residualX() ); m_XresKfitOnY[ichip]->Fill( pixnode->cluster().y(), pixnode->residualX() ); m_YresKfitOnY[ichip]->Fill( pixnode->cluster().y() , pixnode->residualY() ); m_YresKfitOnX[ichip]->Fill( pixnode->cluster().x(), pixnode->residualY() ); // Fill biased residuals on X,Y slopes m_XresKfitOnTX[ichip]->Fill( pixnode->state().tx() , pixnode->residualX() ); m_XresKfitOnTY[ichip]->Fill( pixnode->state().ty() , pixnode->residualX() ); m_YresKfitOnTY[ichip]->Fill( pixnode->state().ty() , pixnode->residualY() ); m_YresKfitOnTX[ichip]->Fill( pixnode->state().tx() , pixnode->residualY() ); // Fill residual errors m_XreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovX()) ); m_YreserrKfit[ichip]->Fill( std::sqrt(pixnode->residualCovY()) ); // Fill residual pulls m_XrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) ); m_YrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) ); // Fill chi2 quality histos : // take the chi2 of the track.. LHCb::ChiSquare chi2 ( (*icktra)->chi2(), (*icktra)->ndof() ) ; // we should add a proper function to KalmanTrack, or store it // ..now calculate and subtract the chi2 of this hit: should become a function of node as well double resX = pixnode->residualX() ; double resY = pixnode->residualY() ; int nd = 2 * ( (*icktra)->nodes().size() -1 ) - 4; LHCb::ChiSquare chi2hit ( resX*resX / pixnode->residualCovX() + resY*resY / pixnode->residualCovY() , nd ); chi2 -= chi2hit; // apply quality check if (chi2.chi2()/chi2.nDoF()<4) { // Fill quality biased residuals for this hit m_qXresKfit[ichip]->Fill( pixnode->residualX() ); m_qYresKfit[ichip]->Fill( pixnode->residualY() ); // Fill quality residual pulls for this hit m_qXrespullKfit[ichip]->Fill( pixnode->residualX() / std::sqrt(pixnode->residualCovX() ) ); m_qYrespullKfit[ichip]->Fill( pixnode->residualY() / std::sqrt(pixnode->residualCovY() ) ); } } // end of node check } // end of node loop } // end of Ktrack loop }
void searchByPair(int eventId, vector<GpuTrack>& tracks_vector) { int lastSensor = sens_num - 1; int firstSensor = 2; GpuTrack m_track; bool* hit_isUseds = (bool*) calloc(hits_num, sizeof(bool)); // helper variables int event_sensor_displ = eventId * sens_num; int event_hit_displ = eventId * hits_num; int sens0, sens1, first1, hit0_no, hit1_no; SensorInfo sensor0, sensor1, extra_sensor; double dxMax, dyMax; debug << "-- searchByPair --" << endl << "Number of sensors: " << sens_num << endl << "Number of hits: " << hits_num << endl; debug << "Starting hits processing..." << endl; // Iterate from the last until the first+1 (including it) for ( sens0 = lastSensor; firstSensor <= sens0; sens0 -= 1 ) { // sens1 is next sensor on the same side sens1 = sens0 - 2; sensor0.startPosition = sensor_hitStarts [event_sensor_displ + sens0]; sensor0.hitsNum = sensor_hitNums [event_sensor_displ + sens0]; sensor0.z = sensor_Zs [event_sensor_displ + sens0]; sensor1.startPosition = sensor_hitStarts [event_sensor_displ + sens1]; sensor1.hitsNum = sensor_hitNums [event_sensor_displ + sens1]; sensor1.z = sensor_Zs [event_sensor_displ + sens1]; /* debug << "sensor 0: " << endl << " Z: " << sensor0.z << endl << " sP: " << sensor0.startPosition << endl << " hitsNum: " << sensor0.hitsNum << endl; */ // Indicator of max dx, dy permissible over next hit dxMax = m_maxXSlope * fabs( sensor1.z - sensor0.z ); dyMax = m_maxYSlope * fabs( sensor1.z - sensor0.z ); first1 = 0; for (hit0_no = 0; hit0_no < sensor0.hitsNum; hit0_no++) { int hit0_offset = event_hit_displ + sensor0.startPosition + hit0_no; if ( hit_isUseds[hit0_offset - event_hit_displ] ) { continue; } double x0 = hit_Xs[hit0_offset]; double y0 = hit_Ys[hit0_offset]; // Min and max x permissible over next hit double xMin = x0 - dxMax; double xMax = x0 + dxMax; // Iterate hits in s1 for (hit1_no = first1; hit1_no < sensor1.hitsNum; hit1_no++) { int hit1_offset = event_hit_displ + sensor1.startPosition + hit1_no; double x1 = hit_Xs[hit1_offset]; // debug << " hit " << hit_IDs[hit0_offset] << " against: " << hit_IDs[hit1_offset] << endl; // Require second hit not to be used, and to be within x limits if ( x1 < xMin ) { first1 = hit1_no + 1; // Start on the item (hit1_no+1) for next iteration continue; } if ( x1 > xMax ) { break; // hits are ordered by x (clever) } if ( hit_isUseds[hit1_offset - event_hit_displ] ) { continue; } // Check hit is within y limits double y1 = hit_Ys[hit1_offset]; if ( fabs( y1 - y0 ) > dyMax ) { continue; } // Creates a GpuTrack starting at itH0 (first hit) and containing itH1 (second hit - addHit) m_track.hits.clear(); setTrack(&m_track, hit0_offset, hit1_offset); debug << endl << "hit" << hit_IDs[hit0_offset] << " and hit" << hit_IDs[hit1_offset] << " are compatible, creating GpuTrack" << endl; //== Cut on R2Beam if needed : backward tracks, i.e zBeam > first hit if (sensor0.z < m_maxZForRBeamCut) { double z_beam = zBeam(&m_track); if ( z_beam > sensor0.z ) { double r2Beam = r2AtZ(z_beam, &m_track); if ( r2Beam > m_maxR2Beam ) { continue; } } } //== Extend downstream, on both sides of the detector as soon as one hit is missed int extraStep = 2; int extraSens = sens1-extraStep; int nbMissed = 0; double lastZ = sensor1.z; while ( extraSens >= 0 ) { extra_sensor.startPosition = sensor_hitStarts[event_sensor_displ + extraSens]; extra_sensor.hitsNum = sensor_hitNums[event_sensor_displ + extraSens]; extra_sensor.z = sensor_Zs[event_sensor_displ + extraSens]; double tol = m_extraTol; double maxChi2 = m_maxChi2ToAdd; if ( extra_sensor.z < lastZ - 100.0 ) { tol = 2 * tol; maxChi2 = 2 * maxChi2; } debug << "s" << extraSens << " "; bool added = addHitsOnSensor(&extra_sensor, tol, maxChi2, &m_track, eventId); if ( added ) { nbMissed = 0; lastZ = extra_sensor.z; } else { nbMissed += extraStep; extraStep = 1; } if ( m_maxMissed < nbMissed ) { break; } extraSens -= extraStep; } debug << endl; //== Try upstream if almost forward tracks if ( sensor0.z > m_maxZForRBeamCut ) { int extraStep = 1; int extraSens = sens0 + 3; // + 2 already tried... nbMissed = 2; while ( extraSens <= lastSensor ) { extra_sensor.startPosition = sensor_hitStarts[event_sensor_displ + extraSens]; extra_sensor.hitsNum = sensor_hitNums[event_sensor_displ + extraSens]; extra_sensor.z = sensor_Zs[event_sensor_displ + extraSens]; bool added = addHitsOnSensor(&extra_sensor, m_extraTol, m_maxChi2ToAdd, &m_track, eventId); if ( added ) { nbMissed = 0; } else { nbMissed += extraStep; } if ( m_maxMissed < nbMissed ) { break; } extraSens += extraStep; } } removeWorstHit(&m_track); if ( m_track.trackHitsNum < 3 ) { debug << "Track only has " << m_track.trackHitsNum << " hits!" << endl; continue; } //== Add compatible hits in sens0 and sens1. int next_hit = hit0_no + 1 + sensor0.startPosition; if ( next_hit != sensor0.startPosition + sensor0.hitsNum ) { if ( chi2Track(&m_track, event_hit_displ + next_hit) < m_maxChi2SameSensor ) { hit0_no++; addHit(&m_track, event_hit_displ + next_hit); } } next_hit = hit1_no + 1 + sensor1.startPosition; if ( next_hit != sensor1.startPosition + sensor1.hitsNum ) { if ( chi2Track(&m_track, event_hit_displ + next_hit) < m_maxChi2SameSensor ) { hit1_no++; addHit(&m_track, event_hit_displ + next_hit); } } //== Final check: if only 3 hits, all should be unused and chi2 good. if ( m_track.trackHitsNum == 3 ) { /*if ( !all3SensorsAreDifferent(&m_track) ) { // debug << "Not all three sensors are different" << endl; continue; } */ if( nbUnused(&m_track, hit_isUseds, event_hit_displ) != 3) { // debug << "There is less than 3 non-used hits" << endl; continue; } if( chi2(&m_track) > m_maxChi2Short) { // debug << "Chi2 test not passed" << endl; continue; } } else { if ( nbUnused(&m_track, hit_isUseds, event_hit_displ) < .6 * m_track.trackHitsNum ) { // debug << "More than 60% of the hits are used already" << endl; continue; } } // debug << endl << "++ Writing GpuTrack" << endl; tracks_vector.push_back(m_track); addHitIDs(m_track.hits); // Tag used hits IF the GpuTrack is bigger than 3!! if (m_track.trackHitsNum > 3) { for (size_t i = 0; i < m_track.hits.size(); i++) { hit_isUseds[m_track.hits[i] - event_hit_displ] = 1; } break; } } // itH1 } // itH0 } // sens0 // return tracks; free(hit_isUseds); }
bool fitSimAnneal::fit() { int error=0; bool finished=false; //double newChi2; double T=T0*pow(10.0,floor(log10(chi2(param, fitParamCount)))); int* dirVariations=(int*)calloc(fitParamCount, sizeof(int)); double* fast=(double*)calloc(Nepsilon, sizeof(double)); for (int i=0; i<Nepsilon; i++) { fast[i]=currentChi2; } int k=0; std::cout<<" initial temperature: "<<T<<std::endl; do { for (unsigned int tempSteps=0; tempSteps<NT; tempSteps++) { // clear variations counter /*for (unsigned int i=0; i<fitParamCount; i++) { dirVariations[i]=0; }*/ for (register unsigned int stepVariations=0; stepVariations<NS; stepVariations++) { iterations++; for (register unsigned int h=0; h<fitParamCount; h++) { //std::cout<<h<<" "; // x' = x + r*v[h] * eh // where eh is the unit vector in direction h // for this ensure that a_h <= x'_h <= b_h register double new_xh=0; register double old_xh=x0[h]; do { // r=random number from flat distribution between -1..1 new_xh=x0[h]+(ran(2.0)-1.0)*v[h]; } while (new_xh<lowerBounds[h] || new_xh>upperBounds[h]); x0[h]=new_xh; register double testChi2=chi2(x0, fitParamCount); if (testChi2<currentChi2) { // accept trial step currentChi2=testChi2; dirVariations[h]++; //std::cout<<" downhill trial accepted: "<<doublevectortostr(x0, fitParamCount)<<" <"<<currentChi2<<">"; // save best fits if (currentChi2<bestChi2) { //std::cout<<" as optimal"; memcpy(param, x0, fitParamCount*sizeof(double)); bestChi2=testChi2; } //std::cout<<std::endl; } else { // Metropolis-Monte-Carlo step if (ran()<exp((currentChi2-testChi2)/T)) { // accept trial step //memcpy(param, x0, fitParamCount*sizeof(double)); currentChi2=testChi2; dirVariations[h]++; //std::cout<<" metropolis trial accepted: "<<doublevectortostr(x0, fitParamCount)<<" <"<<currentChi2<<">\n"; } else { // reset to former value (old_xh) x0[h]=old_xh; } } } } // update the step vector //std::cout<<" NS = "<<NS<<" dirVariations = ("; for (register unsigned int h=0; h<fitParamCount; h++) { //if (h>0) std::cout<<", "; //std::cout<<dirVariations[h]; if (dirVariations[h]>0.6*(double)NS) { v[h]=v[h]*(1.0+c*(dirVariations[h]/(double)NS-0.6)/0.4); if (v[h]>fabs(upperBounds[h]-lowerBounds[h])/2.0) v[h]=fabs(upperBounds[h]-lowerBounds[h])/2.0; } else if (dirVariations[h]<0.4*(double)NS) { v[h]=v[h]/(1.0+c*(0.4-dirVariations[h]/(double)NS)/0.4); if (v[h]>fabs(upperBounds[h]-lowerBounds[h])/2.0) v[h]=fabs(upperBounds[h]-lowerBounds[h])/2.0; } dirVariations[h]=0; } //std::cout<<")\n"; //std::cout<<" new step vector("<<tempSteps<<"/"<<NT<<"): "<<doublevectortostr(v, fitParamCount)<<std::endl; } // temperature update T=T*rT; std::cout<<" new temperature: "<<T;//<<std::endl; // stop criterion fast[k]=currentChi2; finished=true; //std::cout<<" fmax="<<fmax<<" "; for (unsigned int u=0; (u<Nepsilon) && (finished); u++) { finished=finished && (fabs(currentChi2-fast[u])<=fmax); //std::cout<<" |"<<currentChi2<<" - "<<fast[u]<<"|="<<fabs(currentChi2-fast[u]); } //std::cout<<std::endl; /*if (finished) { finished=(fast[k]-bestChi2)<=fmax; }*/ k++; if (k>=Nepsilon) k=0; memcpy(x0, param, fitParamCount*sizeof(double)); currentChi2=bestChi2; //std::cout<<" current f*="<<doublevectortostr(fast, Nepsilon)<<std::endl; std::cout<<" bestChi2="<<bestChi2<<" bestParam="<<doublevectortostr(param, fitParamCount)<<" iterations="<<iterations<<std::endl; } while (!finished && error==0 && iterations<iterationsMax); free(dirVariations); std::cout<<"best fit: ( "; for (int i=0; i<fitParamCount; i++) { if (i>0) std::cout<<", "; std::cout<<param[i]; } std::cout<<" )\n"; if (iterations>=iterationsMax) std::cout<<" stopped by maximum iterations.\n"; if (finished) std::cout<<" stopped by abortion criterion f<sub>max</sub>.\n"; if (error==-1) std::cout<<"ERROR: Not a Number (NaN) occured during chi2() function evaluation\n"; if (error==-2) std::cout<<"ERROR: Infinity occured (Inf) during chi2() function evaluation\n"; return (error==0); }
void fit(boot &A,boot &B,boot &C,boot &D,bvec &X,bvec &Y) { //copy X X_fit=new double[nens]; for(int iens=0;iens<nens;iens++) X_fit[iens]=X[iens].med(); Y_fit=new double[nens]; err_Y_fit=new double[nens]; TMinuit minu; minu.SetPrintLevel(-1); int npars=4; minu.DefineParameter(0,"A",0.0,0.0001,0,0); minu.DefineParameter(1,"B",0.0,0.0001,0,0); minu.DefineParameter(2,"C",0.0,0.0001,0,0); minu.DefineParameter(3,"D",0.0,0.0001,0,0); if(!include_a4) { minu.FixParameter(3); npars--; } if(!include_ml_term) { minu.FixParameter(1); npars--; } minu.SetFCN(chi2_wr); double C2; for(int iboot=0;iboot<nboot+1;iboot++) { if(iboot>0) minu.SetPrintLevel(-1); minu.DefineParameter(4,"a380",lat[0][iboot],0.0001,0,0); minu.DefineParameter(5,"a390",lat[1][iboot],0.0001,0,0); minu.DefineParameter(6,"a405",lat[2][iboot],0.0001,0,0); minu.DefineParameter(7,"a420",lat[3][iboot],0.0001,0,0); minu.FixParameter(4); minu.FixParameter(5); minu.FixParameter(6); minu.FixParameter(7); for(int iens=0;iens<nens;iens++) { Y_fit[iens]=Y.data[iens].data[iboot]; err_Y_fit[iens]=Y.data[iens].err(); } //minimize minu.Migrad(); //get back parameters double dum; minu.GetParameter(0,A.data[iboot],dum); minu.GetParameter(1,B.data[iboot],dum); minu.GetParameter(2,C.data[iboot],dum); minu.GetParameter(3,D.data[iboot],dum); double lat_med[4]={lat[0].med(),lat[1].med(),lat[2].med(),lat[3].med()}; if(iboot==nboot) { contr_flag=1; C2=chi2(A.data[iboot],B[iboot],C[iboot],D[iboot],lat_med); contr_flag=0; } } int ninc_ens=0; for(int iens=0;iens<nens;iens++) if(ibeta[iens]!=0 || include_380) ninc_ens++; //calculate the chi2 cout<<"A=("<<A<<"), B=("<<B<<"), C=("<<C<<"), D=("<<D<<")"<<endl; cout<<"Chi2 = "<<C2<<" / "<<ninc_ens-npars<<" = "<<C2/(ninc_ens-npars)<<endl; delete[] X_fit; delete[] Y_fit; delete[] err_Y_fit; }