[ < ] | [ > ] | [ << ] | [ 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] | [ ? ] |