Boost::math headers in ROOT

Dear all,

I’m having a load a problems trying to use some boost math libraries in ROOT.
I’ve been diving in the forums, and I have found several solutions, but I don’t
seem to be able to implement any of them. Basically, I would like to use
the inverse of the incomplete gamma function, which is defined in
boost::math::special_functions. I assumed it was enough by adding the include path

root [0] gSystem->AddIncludePath("-I$BOOSTROOT/include/boost/")                

and including the library

root [1] #include "boost/math/special_functions.hpp"

However, whereas the former works fine, the latter gives the following error

Error: G__getvariable: expression  /usr/include/boost/config.hpp:23:
Error: operator '/' divided by zero /usr/include/boost/config.hpp:23:
Error: operator '/' divided by zero /usr/include/boost/config.hpp:23:
Syntax Error: <boost/config/user.hpp> /usr/include/boost/config.hpp:23:
*** Interpreter error recovered ***

If I try to compile the macro instead, the file cwchar.h is not found, and the compilations
fails.

Writing a c++ program including the boost libraries will compile and work just fine.
However, I would like to be able to use some functions in root macros and/or the
root command line (as with the TMVA libraries)

I’m using root version 5.28.00c on a unix 64-bit machine.

Thanks in advance.
Cheers,
Alberto.

You don’t seem to try any workaround :wink: The important bits are

  • for most use-cases CINT cannot parse any Boost headers
  • any Boost code should be hidden from CINT with ifdefs or put into files not
    seen by CINT (i.e. the root interpreter or rootcint) and executed as
    compiled code.

For your problem you could use a wrapper function which does not use any Boost
types or functions which in turn returns the result of the Boost function seen
somewhere away from CINT, e.g. along the lines of

// erf.C

// declare visible for CINT
double erf(double x);

#ifndef __CINT__
// define hidden from CINT, visible to the compiler
#include <boost/math/special_functions.hpp>
double erf(double x) {
  return boost::math::erf(x);
}
#endif

In CINT you can load this as a compiled macro (assuming Boost headers are in
your include path).

root [0] .L erf.C+
Info in <TUnixSystem::ACLiC>: creating shared library /tmp/r/./erf_C.so
root [1] erf(-1)
(double)(-8.42700792949714894e-01)

That’s just CINT throwing a fit since it saw some complicated C++ code. Like I
wrote, you shouldn’t allow CINT to see any of that.

Hi,

Why would you need the inverse of incomplete gamma function from Boost ?

In ROOT we have it (using an implementation based on Cephes) which is

ROOT::Math::gamma_quantile(q, a, 1.) or ROOT::Math::gamma_quantile_c(p, a, 1.), depending if you are using the lower or upper integral for the definition of the tail probability.
If you find the boost implementation more accurate or faster, we could eventually switch in ROOT to use that one

Cheers

Lorenzo

@honk It works perfectly. Thank you very much.

@moneta You are right, there they are. I have been using ROOT for quite a long time now and I am shocked
of I have missed the namespace ROOT::Math for so long. I have always relied on ROOT::TMath (shame on me!)
Thanks a lot, this will save me a few headaches.