Template:ROOT/Exercises/Interpreted ROOT Macros

From Wikibooks, open books for an open world
Jump to: navigation, search

Exercise[edit]

  1. Consider the problem solved in the previous exercise. Now write a script that does the same thing and execute it as interpreted macro. Does it run faster?
  2. Modify the script in a way that the user can pass the amount of random numbers to be created as a parameter.
  3. Overload the macro such that the amount of numbers can still be passed but if no parameter is given, 100 000 000 numbers will be generated.

Solution[edit]

Part 1[edit]

Create the following file and name it random_mean.cc

void random_mean()
{
  Int_t nums = 100000000;  // random numbers to generate
  TRandom *R = new TRandom(time(0));
  Double_t *seed = new Double_t[nums];
  for (Int_t i = 0; i < nums; i++)
  {
    seed[i] = R->Rndm();
  }
  Double_t mean = 0.0;
  for (Int_t i = 0; i < nums; i++)
  {
    mean += seed[i];
  }
  mean /= nums;
  cout << "mean = " << mean << endl;
}

Now open a ROOT session in this directory and say

root [0] .x random_mean.cc

Between a half and one minute later you shall get:

mean = 0.499952

The script isn't any faster than the code entered directly to the ROOT command line because in either case it is run as interpreted code by CINT.

Part 2[edit]

This takes only a minor change of the script file:

void random_mean(Int_t nums)
{
  TRandom *R = new TRandom(time(0));
  Double_t *seed = new Double_t[nums];
  for (Int_t i = 0; i < nums; i++)
  {
    seed[i] = R->Rndm();
  }
  Double_t mean = 0.0;
  for (Int_t i = 0; i < nums; i++)
  {
    mean += seed[i];
  }
  mean /= nums;
  cout << "mean = " << mean << endl;
}

Now you can compute the mean of—for example—20 numbers:

root [1] .x random_mean.cc(20)
mean = 0.539992

Note that calling without a parameter will fail:

root [2] .x random_mean.cc
Error: Function random_mean() is not defined in current scope  :0:
*** Interpreter error recovered ***

Part 3[edit]

To allow calling with and without parameter, we overload the function with one that takes no parameter and does nothing than calling the other one with the default parameter of 100 millions.

void random_mean(Int_t nums)
{
  TRandom *R = new TRandom(time(0));
  Double_t *seed = new Double_t[nums];
  for (Int_t i = 0; i < nums; i++)
  {
    seed[i] = R->Rndm();
  }
  Double_t mean = 0.0;
  for (Int_t i = 0; i < nums; i++)
  {
    mean += seed[i];
  }
  mean /= nums;
  cout << "mean = " << mean << endl;
}
 
void random_mean()
{
  random_mean(100000000); // on default, take 1E8 numbers
}

Now both calls work:

root [3] .x random_mean.cc
mean = 0.499998
root [4] .x random_mean.cc(3000)
mean = 0.499366

Actually, this shouldn't be very exciting. It's just the C++ language. But it's a nice thing to see that it works just as expected inside the ROOT framework.