Using NAG C libraries with ROOT

Hello
I have been trying to follow the howto found here: http://root.cern.ch/root/HowtoCERNLIB.html

I want to get one of the NAG numerical integration functions (d01amc) to work in ROOT. I am following the first method and have managed to complete the first two steps however I am completely confused on the third step:

[quote]3. Compile and link
Modify your Makefile to include the files above and reference the libraries. Below is an example valid on HPUX with the CC compiler. Examples of linking a Root application are given for your platform in ${ROOTSYS}/test/Makefile.

CC +a1 +z -I$(ROOTSYS)/include rootCERN.cxx CERN.cxx -o rootCERN \
      /cern/pro/lib/libmathlib.a \
     -L$(ROOTSYS)/lib -lCore -lCint \
     -lGraf -lGraf3d -lHist -lHtml -lMatrix -lMinuit \
     -lPostscript -lProof -lTree \
     -lGpad -lGui -lGX11 -lRint \
     -L/usr/lib/X11R5 -lXpm  -lX11 -lm -ldld[/quote]

The examples didn’t really help me either. Would anybody be able to explain to a beginner what should be done here? I am trying to run this on lxplus which is running root version 5.16. The NAG libraries are located:
/afs/cern.ch/sw/lhcxx/@sys/Nag_C/5.0

You would need to set the include PATH and the linking PATH to the nag location of the include and library files.

However, I have doubts it will work on lxplus, since this Nag version has been compiled for a very old Linux (I think RedHad 7). You probably nneed to get more recent binaries for Nag, I think you can download directly from their web site.

Have you tried to use the numerical integration in MathMore ?
It is based on GSL and as Nag implements the same alghorithms from QUADPACK.
It is documented in
cern.ch/mathlibs/sw/MathMore … ation.html

An example is provided here:

root.cern.ch/viewcvs/mathmore/te … cvs-markup

Please let me know in case you find something missing in the ROOT::Math::Integrator,

Best Regards

Lorenzo

Thanks for the suggestion Lornezo it looks like the Mathmore libraries should do everything I need.

Unfortunately I ran into a problem with the example code you linked me too. It seems that in the version of ROOT I have the functor.h file does not exist. What version of ROOT is required I am running 5.12 currently.

If you are using 5.12, look at the same program with the 5.12 tag

root.cern.ch/viewcvs/mathmore/te … cvs-markup

I have changed in the mean time the way the functions are passed to the integrator algorithm.
With 5.12 you need to pass a function of a type used by GSL (signature like struct gsl_function) or implementing the ROOT::Math::IGenFunction interface,

root.cern.ch/viewcvs/mathmore/in … cvs-markup

Best Regards

Lorenzo

I seem to be having problems implementing my own function as an IGenFunction. I have not been able to find any examples in the code either. I was able to comment out the line #include “Math/WrappedFunction.h” and the (5.12) example code will still run without problems!

For example if I have

double timesTwo( double x) {
     return 2*x;
}

void testIntegration(){

    ROOT::Math::WrappedFunction<FreeFunc> wf(&timesTwo);

}

I get an error:
Syntax error Math/WrappedFunction.h:47:
Error: abstract class object ‘WrappedFunction wf’ declared testIntegration.cxx

I am probably making some terribly obvious mistake but I can’t seem to figure out what to do myself.

Can you send me please the script that reproduces this error ?
Thank you

Lorenzo

Well I basically just added the lines I posted above to the testIntegration.cxx macro you linked me too but I have attached it here.

This is on root 5.12 and I used the command:
root -b -q testIntegration.cxx ¦ tee output.log
to run it.

If this is some version problem I can upgrade to the latest version of root if its easier?
testIntegration.cxx (2.35 KB)

Hi,

Tes test has a an error and
you need to run the test in compiled mode, using Aclic.

Do from the ROOT prompt:

gSystem->Load(“libMathMore”)
.x testIntegration.cxx+

Attached is the correct code,

Best Regards,

Lorenzo
testIntegration.cxx (2.35 KB)

Thanks Lorenzo that example code is now working. Unfortunately I have now realised that although I only need to integrate over 1 dimension I would like to be able to set the values of some constants in my functions.

I assume the best way to do this is to create an object and then use the WrappedMemFunction command however I am unable to get this to work!

I created a test class.

[code]class formula
{
public:
formula();
formula(double newY);
~formula();
double Operator(double x){ return x*y; };
protected:
double x, y;
};

formula::formula(){
y = 1;
}

formula::formula(double newY){
y = newY;
}

formula::~formula(){}
[/code]

Then in my code I tried:

ROOT::Math::WrappedMemFunction<formula, double (formula::Operator()*) (double)> wmf;

I am assuming I am simply using the incorrect syntax but I have so far been unable to figure out what I should put in. Is this the recommended way of doing this? In my actual problem I will have 6 or so constants that I would like to be able to change if required but then I will be integrating over just one dimension still.

You should use the template class

ROOT::Math::WrappedFunction and just do

ROOT::Math::WrappedFunction<formula> wf

The WrappedMemFunction is not available in 5.12 and is for member functions with different name than operator().
It is however recommended (in 5.14) to use the ROOT::Math::Functor class since the syntax for using WrappedMemFunction is ugly to to the complex way of defining types of member functions in C++.

Cheers,
Lorenzo

I seem to be having some trouble getting this to run still.

If I try

ROOT::Math::WrappedFunction<formula> wf;

I get an error, however if do

ROOT::Math::WrappedFunction<formula> *wf;

It does compile however it says that wf is unused. If I try and use wf (by passing it to the integrator) it gives:
/home/atlas/ad/Fitter/convFitter/./testIntegration.cxx:46: warning: ‘wf’ might be used uninitialized in this function
and then a segmenation error.

If I try

formula test(2);
ROOT::Math::WrappedFunction<formula> *wf(test);

or any variation with /& it doesn’t compile giving this kind of error:
/home/atlas/ad/Fitter/convFitter/./testIntegration.cxx:46: error: cannot convert formula' toROOT::Math::WrappedFunction
’ in initialization

So I am still unable to use my class with the integrator.

I think you had a problem in your formula class. Your class, in order to be used by the WrappedFunction class needs to be a callable object, i.e. to implement the operator()(double ).
You defined instead a method call Operator(double x).

You can see in the attached code an example on how to use the Integrator with your formula class. I have tested that the code works with 5.12 (remember to compile it using Aclic).

I showed you the possibility two use the WrappedFunction in two different ways: by wrapping the callable object by value or by reference.

I hope this fixes your problem,

Cheers,
Lorenzo
testIntegration.C (1.17 KB)

As far as I am aware the word “operator” is a reserved word in C++ but not in C. Does this mean I will have to compile everything as C rather than C++? Is this not likely to cause problems?

operator is in did a reserver word in C++.
It is used to define special methods in a class
such as operator+, operator=, operator().

In your case, the formula class, which needs to be wrapped by a WrappedFunction class, must define as a public method the operator().

By defining such a method, you can use like a free function:

formula f; 
f(x);    //  uses operator()(x) 

You can find more info on this at:

en.wikipedia.org/wiki/Function_object

This is only a C++ feature and you need to compile your program which uses ROOT and MathMore with a C++ compiler.

Lorenzo