Evaluating a vector of Chi2Function

Hi Rooters,

I’m trying to simultaneously fit a set of graphs and to do this I would like to use STL vectors. The issue is when I attempt to evaluate the Chi2Function I am getting segmentation faults. My code is similar to the following

#include ....

using namespace std;

int main() { 
   TFile f("graphs.root");
  char Tfilename[50];
  int exp_n = 25;
  double T_max = 10.0;
  double T_min = 0.0;
  int n_min = 1000;
  int n_runs = 1001;
  
   
 //set the initial parameters
 double par[34], par_init[34];
 ....
  
 //declare graphs and functions 
  vector< boost::shared_ptr < TGraphErrors > > gr_ptr(exp_n);
  vector< boost::shared_ptr < TF1 > > my_func_ptr;
  vector< boost::shared_ptr < ModelA > > exp_data_ptr;
  
 
  for(int exp_i=0; exp_i<exp_n; exp_i++){   
	 exp_data_ptr.push_back( boost::make_shared < ModelA > (par_i[exp_i]));
	 my_func_ptr.push_back(boost::make_shared<TF1>("f1", exp_data_ptr[exp_i], &ModelA::expectation_value, 0, T_max, 34));
  }
  
 // get graphs from root file 
  for(int i_runs=n_min; i_runs<n_runs; i_runs++){
	// Get graphs from root file.
       for(int exp_i=0;exp_i<exp_n;exp_i++){ 
	  sprintf(Tfilename, "gr%d_%d", exp_i,i_runs);
	  gr_ptr[exp_i].reset((TGraphErrors*)f.Get(Tfilename));
	}  

        //set up chi2 function to pass to minimizer
	ROOT::Fit::DataOptions opt;
	ROOT::Fit::DataRange range;
	
	T_min = 0.0;
	T_max = 10.0;
	
	range.SetRange(T_min,T_max);
	
	vector< ROOT::Fit::BinData > data;
	vector< ROOT::Math::WrappedMultiTF1 > wf;
	vector< boost::shared_ptr < ROOT::Math::IMultiGenFunction > > chi2;
	
	for(int i=0; i<exp_n;i++){
	  data.push_back(ROOT::Fit::BinData(opt,range));
	  ROOT::Fit::FillData(data[i],gr_ptr[i].get());
	  wf.push_back(ROOT::Math::WrappedMultiTF1(*(my_func_ptr[i].get()),1));
	  chi2.push_back(boost::make_shared<ROOT::Fit::Chi2Function>(data[i], wf[i]));
	}

        //evaluate chi2 function
	(*chi2[0])(par);
  }
  return 0;
}

I have tried debugging but everything before the call to the chi2 function seems to be working fine.
Any help would be very much appreciated I have been struggling with this for far too long.

cheers

Mark

Can you make this a complete example of your problem (e.g. including the data and the complete source code)?

Sure, I’ve attached a cut down version of my code which appears to be giving the same error.
cheers

Mark
graphs.root (180 KB)
Experiment.h (877 Bytes)
Experiment.cpp (817 Bytes)
test.cpp (4.55 KB)

Hi,

This has nothing to do with shared_ptr.

The unfortunate issue is that the ROOT::Fit::Chi2Function’s in your chi2 vector store references to your fit functions “wf” and the data in the “data” vector. Since these are stored in vectors many operations on said vectors might cause the containers to reallocate the contained objects. This will invalidate iterators, pointers or references to members.

You create Chi2Function objects with references to vector members while you still modify these vectors (which might invalidate iterators). Sane solutions to this could be to
[ul]

  • complete filling the data and wf vectors before using any references to contained objects,
  • call reserve with e.g. exp_n on the vectors after creating them to avoid
    them needing to reallocate
  • or since you don’t depend on data and wf elements to be consecutive in memory, switch to a container like deque which doesn’t invalidate iterators on insert
    [/ul]