manpagez: man pages & more
info ginac
Home | html | info | man
[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]

5.15.3 Compiling expressions to C function pointers

Numerical evaluation of algebraic expressions is seamlessly integrated into GiNaC by help of the CLN library. While CLN allows for very fast arbitrary precision numerics, which is more than sufficient for most users, sometimes only the speed of built-in floating point numbers is fast enough, e.g. for Monte Carlo integration. The only viable option then is the following: print the expression in C syntax format, manually add necessary C code, compile that program and run is as a separate application. This is not only cumbersome and involves a lot of manual intervention, but it also separates the algebraic and the numerical evaluation into different execution stages.

GiNaC offers a couple of functions that help to avoid these inconveniences and problems. The functions automatically perform the printing of a GiNaC expression and the subsequent compiling of its associated C code. The created object code is then dynamically linked to the currently running program. A function pointer to the C function that performs the numerical evaluation is returned and can be used instantly. This all happens automatically, no user intervention is needed.

The following example demonstrates the use of compile_ex:

 
    // ...
    symbol x("x");
    ex myexpr = sin(x) / x;

    FUNCP_1P fp;
    compile_ex(myexpr, x, fp);

    cout << fp(3.2) << endl;
    // ...

The function compile_ex is called with the expression to be compiled and its only free variable x. Upon successful completion the third parameter contains a valid function pointer to the corresponding C code module. If called like in the last line only built-in double precision numerics is involved.

The function pointer has to be defined in advance. GiNaC offers three function pointer types at the moment:

 
    typedef double (*FUNCP_1P) (double);
    typedef double (*FUNCP_2P) (double, double);
    typedef void (*FUNCP_CUBA) (const int*, const double[], const int*, double[]);

FUNCP_2P allows for two variables in the expression. FUNCP_CUBA is the correct type to be used with the CUBA library (http://www.feynarts/cuba) for numerical integrations. The details for the parameters of FUNCP_CUBA are explained in the CUBA manual.

For every function pointer type there is a matching compile_ex available:

 
    void compile_ex(const ex& expr, const symbol& sym, FUNCP_1P& fp,
                    const std::string filename = "");
    void compile_ex(const ex& expr, const symbol& sym1, const symbol& sym2,
                    FUNCP_2P& fp, const std::string filename = "");
    void compile_ex(const lst& exprs, const lst& syms, FUNCP_CUBA& fp,
                    const std::string filename = "");

When the last parameter filename is not supplied, compile_ex will choose a unique random name for the intermediate source and object files it produces. On program termination these files will be deleted. If one wishes to keep the C code and the object files, one can supply the filename parameter. The intermediate files will use that filename and will not be deleted.

link_ex is a function that allows to dynamically link an existing object file and to make it available via a function pointer. This is useful if you have already used compile_ex on an expression and want to avoid the compilation step to be performed over and over again when you restart your program. The precondition for this is of course, that you have chosen a filename when you did call compile_ex. For every above mentioned function pointer type there exists a corresponding link_ex function:

 
    void link_ex(const std::string filename, FUNCP_1P& fp);
    void link_ex(const std::string filename, FUNCP_2P& fp);
    void link_ex(const std::string filename, FUNCP_CUBA& fp);

The complete filename (including the suffix .so) of the object file has to be supplied.

The function

 
    void unlink_ex(const std::string filename);

is supplied for the rare cases when one wishes to close the dynamically linked object files directly and have the intermediate files (only if filename has not been given) deleted. Normally one doesn't need this function, because all the clean-up will be done automatically upon (regular) program termination.

All the described functions will throw an exception in case they cannot perform correctly, like for example when writing the file or starting the compiler fails. Since internally the same printing methods as described in section csrc printing are used, only functions and objects that are available in standard C will compile successfully (that excludes polylogarithms for example at the moment). Another precondition for success is, of course, that it must be possible to evaluate the expression numerically. No free variables despite the ones supplied to compile_ex should appear in the expression.

compile_ex uses the shell script ginac-excompiler to start the C compiler and produce the object files. This shell script comes with GiNaC and will be installed together with GiNaC in the configured $PREFIX/bin directory.


[ < ] [ > ]   [ << ] [ Up ] [ >> ]         [Top] [Contents] [Index] [ ? ]
© manpagez.com 2000-2024
Individual documents may contain additional copyright information.