The problem is that the code needs to compute every element of a 400-element array simultaneously (because the elements of the array are inter-related) - but to my understanding, to fit it using a TF1->fit requires the function to only return a double, rather than a whole array.
This means that to calculate the TF1 over its range means that a self-same array is calculated once for every array of the element which is returned.
In retrospect, I could rewrite the program flow so as not to recalculate the entire matrix at every call of the TF1
This is the main function, the remaining several hundred lines of code are within the array-generating function instEmiss which calculates the instantaneous flux from a source
The function instEmiss which is in the TF1 spect creates this 400 element array
void Mrk501fit()
{
TCanvas* c1[3];
TF1* spect;
spect = new TF1("spect",instEmiss,pow(10,7), pow(10,25),8 );
TGraphErrors* datagraph[3];
ifstream fin;
double nu, nuFnu;
int count;
int limit;
for( int i= 0; i < 3; i++)
{
c1[i] = new TCanvas("C1","Observed Spectrum",1200,800);
count = 0;
if(i==0)
{
fin.open("2005high.dat");
limit = 14;
}
if(i==1)
{
fin.open("2005low.dat");
limit = 10;
}
if(i==2)
{
limit = 16;
fin.open("2008a.dat");
}
datagraph[i] = new TGraphErrors(limit);
while(count < limit)
{
fin >> nu >> nuFnu;
nu = pow(10, nu);
nuFnu = pow(10, nuFnu);
datagraph[i]->SetPoint(count,nu,nuFnu);
datagraph[i]->SetPointError(count,0,nuFnu*0.50 ); //set an arbitrary error of 50%
count++;
}
fin.close();
gPad->SetLogx(1);
gPad->SetLogy(1);
datagraph[i]->GetXaxis()->SetRangeUser(1E10,1E29);
datagraph[i]->GetYaxis()->SetRangeUser(1E-13,1E-8);
datagraph[i]->Draw("A*");
c1[i]->Modified();
c1[i]->Update();
// redshift - fixed
spect->FixParameter(0, 0.033663);
// break in spectrum
spect->SetParameter(1, 6);
spect->SetParLimits(1, 1, 9 );
// slope 1
spect->SetParameter(2, 0.3);
spect->SetParLimits(2, 0, 1 );
//slope 2
spect->SetParameter(3, 0.5);
spect->SetParLimits(3, 0, 1 );
//magnetic field, microGauss
spect->SetParameter(4, 5.5 );
spect->SetParLimits(4, 4, 8 );
// number density /cm^3
spect->SetParameter(5, 6);
spect->SetParLimits(5, 1, 10 );
// region radius, /cm
spect->SetParameter(6, 15);
spect->SetParLimits(6, 10, 20 );
//doppler
spect->SetParameter(7, 1.5);
spect->SetParLimits(7, 0, 2 );
spect->SetParNames("z","break","n1","n2","B (uG)","K (cm^-3)","R (cm)","doppler ");
datagraph[i]->Fit("spect");
spect->Draw("sameC");
c1[i]->Modified();
c1[i]->Update();
}
}