Loop to get the average

hi :slight_smile: i wanted to get and plot the average of f1 after 100 tries of random numbers [3].

TF1 *f1 = new TF1("f1","(2.0*[0]*[0]*[1]*[1]*[2]*[2]*[3]*[3])/(x*x*sin([4]*[5]/360.0)*sin([4]*[5]/360.0)+2.0*[3]*[3]*x))", 0.0025, 1.0);
 f1->SetParameter(0,1.0);
 f1->SetParameter(1,1.0);
 f1->SetParameter(2,1.0/137.0);
 f1->SetParameter(3,gRandom->Gaus(0.938272081,0.000000023));
 f1->SetParameter(4,10.0);
 f1->SetParameter(5,vpi);
 f1->SetLineColor(kBlue);
 f1->SetLineWidth(2);

what should I do?
thanks for your helpā€¦

regards,
jaybee

do:

   double avr = 0 ;
   for (int i=1; i<=100; i++) avr = avr + gRandom->Gaus(0.938272081,0.000000023);
   avr = avr/100.;

and set the parameter to avr

do you mean it like this?

double avr = 0;

for (int i=1; i<=100; i++)
TF1 f1 = new TF1(ā€œf1ā€,"(2.0[0][0][1][1][2][2][3][3])/(xxsin([4][5]/360.0)sin([4][5]/360.0)+2.0*[3]*[3]*x))", 0.0025, 1.0);

f1->SetParameter(0,1.0);
f1->SetParameter(1,1.0);
f1->SetParameter(2,1.0/137.0);
f1->SetParameter(3,gRandom->Gaus(0.938272081,0.000000023));
f1->SetParameter(4,10.0);
f1->SetParameter(5,vpi);
f1->SetLineColor(kBlue);
f1->SetLineWidth(2);

avr = avr + f1;

avr->Draw();

i am not sureā€¦ :slight_smile:

No, like that:

double avr = 0 ;
   for (int i=1; i<=100; i++) avr = avr + gRandom->Gaus(0.938272081,0.000000023);
   avr = avr/100.;

[...]
f1->SetParameter(3,avr);

i am in the state of confusion because it is not the random number that i am going to average but the function f1ā€¦ but maybe it means the same for linear function but for quadratic or higher? (let me check) :slight_smile:

this means that i have to fill-in f1 with a random number 100 timesā€¦ add all of themā€¦ then get the averageā€¦

or maybe thisā€¦

do {
ā€œTF1 fn = new TF1(ā€œfnā€,"(2.0[0][0][1][1][2][2][3][3])/(xxsin([4][5]/360.0)sin([4][5]/360.0)+2.0*[3]*[3]x))",0.0025,1.0);
fn->SetParameter(0,1.0);
fn->SetParameter(1,1.0);
fn->SetParameter(2,1.0/137.0);
fn->SetParameter(3,gRandom->Gaus(0.938272081,0.000000023));
fn->SetParameter(4,10.0);
fn->SetParameter(5,vpi);
fn->SetLineColor(kBlue);
fn->SetLineWidth(2);
"TF1 f1 = new TF1(ā€œf1ā€,"(1/i)(f1
(i-1)+fn)ā€,0.0025,1.0);
} while (int i=1; i<=100; i++);
f1->Draw();

You donā€™t need a TF1 for this; just use a variable (say, f1) that is calculated with your formula using all the constant parametres that you have, and changing ā€œxā€ in the loop:

  Double_t p0=1.0, p1=1.0, p2=1.0/137, ...;
  Double_t x, f1;  // for each sample
  Double sum=0, avr=0;
  for (Int_t i=0; i<100; ++i) {
    x = gRandom->Gaus(0.938272081,0.000000023);
    f1 = 2.0*p0*p0*.../(x*x...);
    sum += f1;
  }
  avr = sum/100;

If you must use TF1, have a look at Eval(). Define the function and params outside the loop (like you did originally), and in the ā€˜forā€™ loop youā€™ll only need to generate ā€˜xā€™ and use it in f1->Eval(ā€¦ to get the value (as ā€˜yā€™).
Note that your last line, f1->Draw(), will draw f1 within the limits you specified at creation, and with a smooth line, independently of the sampling you do; not sure if this is what you want, but be aware of this :slight_smile:

Hi Dastudillo, thanksā€¦ but I have another variable x ranging from .0025 to 1.0 tooā€¦

x there is another variable while [3] is the random numberā€¦

It was not clear to me that you wanted the average of the function. I thought you wanted the average of the random number.

Look at the code @dastudillo suggested. It computes the average of a function f1. You do no need a TF1 for that. Where does this ā€œother variableā€ appears ? can you elaborate @dastudillo example to show what you mean ?

Ok, I think I understand a bit better. Generate param[3] randomly and use it (as well as the other params) to create a function f1 from 0.0025 to 1.0 (x, ā€˜filled inā€™ by ROOT); then, generate another param[3] to create another f1, and repeat 100 times. So this creates 100 functions. In this case the question is: what is the ā€œaverageā€ we need to obtain? How do you define the ā€œaverageā€ of all these 100 functions?
This will create 100 functions (f0 to f99):

  TF1 *f[100];
  Char_t fname[10];
  for (Int_t i=0; i<100; ++i) {
    sprintf(fname,"%s%d","f",i);
    f[i] = new TF1(fname,"(2.0*[0]*[0]*[1]*[1]*[2]*[2]*[3]*[3])/(x*x*sin([4]*[5]/360.0)*sin([4]*[5]/360.0)+2.0*[3]*[3]*x))", 0.0025, 1.0);
    f[i]->SetParameter(0,1.0);
    f[i]->SetParameter(1,1.0);
    f[i]->SetParameter(2,1.0/137.0);
    f[i]->SetParameter(3,gRandom->Gaus(0.938272081,0.000000023));
    f[i]->SetParameter(4,10.0);
    f[i]->SetParameter(5,vpi);
    f[i]->SetLineColor(kBlue);
    f[i]->SetLineWidth(2);
  }

but then, what to average?

yeah, iā€™ll take a look of the code that @dastudillo just sent :slight_smile: thanksā€¦

thanks @dastudillo :slight_smile:
here, we now have 100 functions and for each of them we can generate a plot but i only need one curve that is the average of the 100 plots.

regards,
jaybee

Hi,
jbmagallanes wants to plot the average of the 100 functions,
so at every point x one needs the mean(f(x))
Now the question is (given parameters a: variable, b: fixed)
Does the following hold:
For any x:

mean(f(x, a, b)) = f(x, mean(a), b)

If f(x) does not depend linearly on a this is obviously wrong
(try with f(x) = a * x*x)
So the only way I see is construct a TGraph with appropriate
number of points and fill with mean(f(x, a, b))

Otto

thanks @OSchaile :slight_smile: can you help me take a look at the code if I can do it like that? thanks in advance also for your helpā€¦ :slight_smile:

do {
ā€œTF1 fn = new TF1(ā€œfnā€,"(2.0 [0] [0] [1] [1] [2] [2] [3] [3])/(x x sin([4] [5]/360.0) sin([4] [5]/360.0)+2.0*[3]*[3] x))",0.0025,1.0);
fn->SetParameter(0,1.0);
fn->SetParameter(1,1.0);
fn->SetParameter(2,1.0/137.0);
fn->SetParameter(3,gRandom->Gaus(0.938272081,0.000000023));
fn->SetParameter(4,10.0);
fn->SetParameter(5,vpi);
fn->SetLineColor(kBlue);
fn->SetLineWidth(2);
"TF1 f1 = new TF1(ā€œf1ā€,"(1/i) (f1
(i-1)+fn)ā€,0.0025,1.0);
} while (int i=1; i<=100; i++);
f1->Draw();

I am afraid there is a basic misunderstanding here:
f1 or fn is a pointer to a TF1 (function object) and n o t the result
i.e a real number of an evaluated formula.
By the way it should be TF1 *f1=new..

What is ā€œvpiā€ in parameter 5, is it TMath::Pi() = 3.14ā€¦?

Why do you use 5 parameters if only 1 (3) is variable?

Otto

yeahā€¦ vpi=TMath::Pi().
also, is TF1 *fn=new... and TF1 *fn=new...
the asterisk did not show earlier.
those parameters are ā€œconstantsā€ except for [3] which have to be a random number in addition to the variable x ranging from 0.0025 to 1.0)

do {
ā€œTF1 *fn = new TF1(ā€œfnā€,"(2.0*[0]*[0]*[1]*[1]*[2]*[2]*[3]*[3])/(x*x*sin([4]*[5]/360.0)*sin([4]*[5]/360.0)+2.0*[3]*[3]*x))",0.0025,1.0);
fn->SetParameter(0,1.0);
fn->SetParameter(1,1.0);
fn->SetParameter(2,1.0/137.0);
fn->SetParameter(3,gRandom->Gaus(0.938272081,0.000000023));
fn->SetParameter(4,10.0);
fn->SetParameter(5,TMath::Pi());
fn->SetLineColor(kBlue);
fn->SetLineWidth(2);
"TF1 *f1 = new TF1(ā€œf1ā€,"(1/i) (f1 (i-1)+fn)ā€,0.0025,1.0);
} while (int i=1; i<=100; i++);
f1->Draw();

Hi
before doing the averaging effort one should check if plotting
the possible result makes sense.
Attached your function plotted with parameter 3 at center of the proton mass
(in whatever units) and with 100 standard deviations (second argument of Gaus) away
Even then the curves overlap, so plotting doesnt show anything interesting
(if your function is correct)
Otto

f1.C (926 Bytes)

hi @OSchaile :slight_smile:

it is not the whole function.
i purposely cut it because that function is very long.
what i just wanted was the procedural code on getting the an average curve of 100 plots.
i hope you can help me.
thanks :slight_smile: