Use of functors in 2D and above (see newest post)

Hi,

I’ve defined an array of TF1’s, and would like to sum a function of these to create another TF1, but I seem to be having issues with this.
The program compiles fine under ACLiC (.L tf1arr.C++, using the Visual Studio compiler) but when run, complains about bad numerical expressions for each one.

I’ve attached a sample script (the original function and parameter definitions have been simplified, but still have exactly the same problem). I assume the issue here is that whenever something in square brackets is seen the constructor is expecting it to be a parameter definition, but there is no way of calling a TF1 as a parameter, only a Double_t. The original functions compile fine, but the functions calling the originals do not.

Is there something I am doing wrong here, or an alternative way of doing this? I’ve seen a method elsewhere for adding two functions, but my original program has an array of 10000 of these, which would be impractical to code line-by-line.
(Side-note: the array dimension is only called dynamically as in the original program it is dependent on the number of lines in an input file - this bit works fine)

Thanks in advance,

–Jeremy
tf1arr.C (916 Bytes)

Anyone have any ideas what to do about this? I’m still rather stumped here. I tried using escape characters (putting a backslash in front of each of the square brackets) on the off chance that it would change how the constructor was seeing the expression, but no dice… Any advice would be very much appreciated, i’ve moved onto other things for a couple of days but have been scratching my head over this throughout…
(Just realised as well that I hadn’t put any tech details in - this is with version 5.30/02 running under Windows 7, if the version makes any difference here)
Cheers,

–J

Hi,

If you want to make a TF1 depending on many other TF1 objects, I would suggest you to create a Functor class based on the other TF1 objects and then create your final TF1 based from the functor as described in
root.cern.ch/root/htmldoc/TF1.html#F4

Best Regards

Lorenzo

Thanks very much for the info, it seems to work now. This is how it looks:

struct NegLogSum { //Struct to create negative log sum of an array of TF1's //This is known as a "functor", can be passed to a TF1 constructor NegLogSum(TF1 **f, Int_t size): fFunc(f), fsize(size) {} //takes as input an array of TF1's f, and an integer "size" (size of array) double operator() (double *x, double * ) const { //When a tf1 is defined this operator is used to generate y values from given x double result = 0; for (Int_t i = 0; i< fsize ; i++) { result -= log(fFunc[i]->Eval(*x));} return result; } TF1 ** fFunc; Int_t fsize; };

I’m now having a slight issue defining this in two dimensions, however. I’m trying to do the same thing with an array of TF2’s but there doesn’t seem to be a way of properly defining a functor in 2d (or indeed 3d) - unless I’m misinterpreting the documentation on this.

I thought something along these lines would make sense: struct NegLogSum2D { //Struct for negative log sum of an array of TF2's NegLogSum2D(TF2 **f, Int_t size): fFunc(f), fsize(size) {} double operator() (double *x, double *y, double * ) const { double result = 0; for (Int_t i = 0; i < fsize ; i++) { result -= log(fFunc[i]->Eval(*x,*y));} return result; } TF2 ** fFunc; Int_t fsize; };
but when this is compiled I get an error saying that the struct doesn’t define a two-parameter bracket operator. For these purposes, however, two parameters wouldn’t make much sense to me (indeed it seems that it’s the same requirement for a 3d functor, but I don’t understand how that can be used to define something based on three variables)
Thanks,

–J

Hi,

The syntax of the functor operator()(double *x, double *par) used for a TF2 (or TF3) is the same. What changes is that for a TF2 the size of the array x is 2 instead of 1.

Lorenzo

Ah, x being an array makes a lot more sense.
Many thanks for the help, everything is in order now =)

–J