Parameter errors with TF1

Hello,

I am running into a problem when I try using TF1 and call another method. My code is as follows:

TF1 *f2 = new TF1( “f2”, “PionCTH([0], x)”, -1, 1);
f2->SetParameters( 0, ke);

and I have PionCTH defined as its own method:

Double_t PionCTH(Double_t a, Double_t b)
{
return(a*b); //the simplest formula to help with the debugging process
}

My file is an executable (.cxx file) and when I compile it, everything works fine. But, as soon as I try to run it, I get the following errors:

Error in TFormula::Compile: Bad numerical expression : PionCTH([0],x)"
Error in TF1::TF1: function: f2/PionCTH( [0], x) has 0 parameters instead of 1

I am using the following version of Root:


  •                                     *
    
  •    W E L C O M E  to  R O O T       *
    
  •                                     *
    
  • Version 5.14/00e 29 March 2007 *
  •                                     *
    
  • You are welcome to visit our Web site *
  •      [root.cern.ch](http://root.cern.ch)            *
    
  •                                     *
    

FreeType Engine v2.1.9 used to render TrueType fonts.
Compiled on 24 May 2007 for linux with thread support.

CINT/ROOT C/C++ Interpreter version 5.16.16, November 24, 2006

Hopefully someone knows of what I’m doing wrong, or what I need to fix to get this working.

Thanks in Advance,

Alex L

This part of the TF1 manual page explains how to use custom C functions:

root.cern.ch/root/html/TF1.html#F3

The important thing is that TF1 knows nothing (in general) of functions defined in C. You need to pass it the function itself, and not the function’s name as a string.

  • Peter

Hi Peter,

Thanks for being so diligent with your response, unfortunately my problems are still not all resolved. I have in the past used a similar format when I have created the TF1 and defined it as follows:

TF1 *f1 = new TF1(“f1”, “”, 0, 10);
f1->SetParameters(0, x);

where I have also defined x in my macro, and it worked fine.

I took your advice and looked at the website you provided and even tried copying some of the examples, but to no avail. The one that confused me the most was:

// Macro myfunc.C
Double_t myfunction(Double_t *x, Double_t *par)
{
Float_t xx =x[0];
Double_t f = TMath::Abs(par[0]*sin(par[1]*xx)/xx);
return f;
}
void myfunc()
{
TF1 *f1 = new TF1(“myfunc”,myfunction,0,10,2);
f1->SetParameters(2,1);
f1->SetParNames(“constant”,“coefficient”);
f1->Draw();
}
void myfit()
{
TH1F *h1=new TH1F(“h1”,“test”,100,0,10);
h1->FillRandom(“myfunc”,20000);
TF1 *f1=gROOT->GetFunction(“myfunc”);
f1->SetParameters(800,1);
h1.Fit(“myfunc”);
}

Since it appeared that myfunction was defined as a function and within myfunc() it was called. There are no quotations around myfunction and there are 2 variables (the first being automatically set to the variable x in the range of 0 to 10 and the second being defined as 1). Everything I tried gave me errors when compiling. One of the strangest things was that in this code, for myfunction, 2 pointers are used as input (Double_t *x, Double_t *par) and when I tried the same I would get errors that it was not allowed.

Sorry for being a bother, but I am still quite new to ROOT, so if anyone at all could help I would appreciate.

Alex L.

Yes, that example is very confusing.

Here is my own example. For some reason it crashes for me on ROOT 5.18 unless I compile it.

Important things to note:[ul]
[li] MyFunction must have the exact function prototype.[/li]
[li] The last three parameters of the TF1 constructor are (xmin, xmax, number of parameters)[/li]
[li] Beware the difference between ‘SetParameter’ and ‘SetParameters’[/li][/ul]

[code]#include <TF1.h>

Double_t MyFunction( Double_t *coord, Double_t *par )
{
Double_t &x = coord[0];

return x * par[0];

}

void SimpleFormula()
{
TF1 *f = new TF1( “f”, MyFunction, -10, 10, 1 );
f->SetParameter( 0, 1 );

Double_t x = 5;
cout << "(x = " << x << ", y = " << f->Eval(x) << ")" << endl;

}[/code]

In your code above you have a C++ mistake. Replace the line

Double_t &x = coord[0]; by

Double_t x = coord[0];
Rene

[quote=“brun”]In your code above you have a C++ mistake. Replace the line

Double_t &x = coord[0]; by

Double_t x = coord[0];
Rene[/quote]

Hmm, not a mistake, but maybe misguided? Double_t& is a reference datatype, my thought was that I might in a sense `rename’ coord[0] to x with this mechanism, rather than copy the data? Not that it really matters for a Double_t.