From 541c2950a84f2e0a19edae0da44ad2d317824ec4 Mon Sep 17 00:00:00 2001 From: Jens Vollinga Date: Wed, 7 Dec 2005 18:19:44 +0000 Subject: [PATCH] Added compile function. --- configure.ac | 11 ++ doc/examples/compile1.cpp | 45 ++++++++ doc/examples/ginac-examples.texi | 7 ++ ginac/Makefile.am | 10 +- ginac/excompiler.cpp | 170 +++++++++++++++++++++++++++++++ ginac/excompiler.h | 47 +++++++++ ginac/ginac.h | 2 + tools/Makefile.am | 4 + tools/ginac-excompiler.in | 3 + 9 files changed, 294 insertions(+), 5 deletions(-) create mode 100644 doc/examples/compile1.cpp create mode 100644 ginac/excompiler.cpp create mode 100644 ginac/excompiler.h create mode 100644 tools/ginac-excompiler.in diff --git a/configure.ac b/configure.ac index 7005c946..47dcfdde 100644 --- a/configure.ac +++ b/configure.ac @@ -116,6 +116,16 @@ if test "x$CONFIG_RUSAGE" = "xno"; then AC_CHECK_HEADER(ctime, , GINAC_ERROR([The standard header file could not be found.])) fi +dnl Check for dl library (needed for GiNaC::compile). +AC_CHECK_LIB(dl, dlopen, + [ + DL_LIBS="-ldl" + AC_SUBST(DL_LIBS) + AC_DEFINE(HAVE_LIBDL, 1, [set to 1 if you have a working libdl installed.]) + ], + GINAC_WARNING([libdl not found. GiNaC::compile will be disabled.])) +LIBS="$LIBS $DL_LIBS" + dnl We need to have Bruno Haible's CLN installed. dnl (CLN versions >= 1.1.0 must have installed cln.m4 at a visible place, dnl which provides this macro): @@ -154,6 +164,7 @@ ginsh/Makefile ginsh/ginsh.1 tools/Makefile tools/viewgar.1 +tools/ginac-excompiler doc/Makefile doc/examples/Makefile doc/tutorial/Makefile diff --git a/doc/examples/compile1.cpp b/doc/examples/compile1.cpp new file mode 100644 index 00000000..e2fa8e02 --- /dev/null +++ b/doc/examples/compile1.cpp @@ -0,0 +1,45 @@ +#include +using namespace std; +#include +using namespace GiNaC; +// Yes, we are using CUBA (should be installed on the system!) +#include "cuba.h" + +int main() +{ + // Let the user enter a expression + symbol x("x"), y("y"); + string s; + cout << "Enter an expression containing 'x' and/or 'y': "; + cin >> s; + // Expression now in expr + ex expr(s, lst(x,y)); + + cout << "start integration of " << expr << " ..." << endl; + + // Some definitions for VEGAS + #define NDIM 2 + #define NCOMP 1 + #define EPSREL 1e-3 + #define EPSABS 1e-12 + #define VERBOSE 0 + #define MINEVAL 0 + #define MAXEVAL 50000 + #define NSTART 1000 + #define NINCREASE 500 + + // Some variables for VEGAS + int comp, nregions, neval, fail; + double integral[NCOMP], error[NCOMP], prob[NCOMP]; + + // Starting VEGAS + // By invocation of compile() the expression in expr is converted into the + // appropriate function pointer + Vegas(NDIM, NCOMP, compile(lst(expr), lst(x,y)), EPSREL, EPSABS, VERBOSE, + MINEVAL, MAXEVAL, NSTART, NINCREASE, &neval, &fail, integral, error, prob); + + // Show the result + cout << "result: " << integral[0] << endl; + + return 0; +} diff --git a/doc/examples/ginac-examples.texi b/doc/examples/ginac-examples.texi index 200c81e7..bd14dab9 100644 --- a/doc/examples/ginac-examples.texi +++ b/doc/examples/ginac-examples.texi @@ -30,4 +30,11 @@ This is a collection of code examples using GiNaC. Two expression are stored in an archive on the disk and are restored again. +@chapter Monte Carlo Integration + +@section Using VEGAS from CUBA @uref{compile1.cpp, (source)} + +An expression in two variables is integrated by using VEGAS from the +@uref{http://www.feynarts.de/cuba/, CUBA library}. + @bye diff --git a/ginac/Makefile.am b/ginac/Makefile.am index 0236f9b2..7ae84550 100644 --- a/ginac/Makefile.am +++ b/ginac/Makefile.am @@ -2,8 +2,8 @@ lib_LTLIBRARIES = libginac.la libginac_la_SOURCES = add.cpp archive.cpp basic.cpp clifford.cpp color.cpp \ - constant.cpp ex.cpp expair.cpp expairseq.cpp exprseq.cpp fail.cpp \ - fderivative.cpp function.cpp idx.cpp indexed.cpp inifcns.cpp \ + constant.cpp ex.cpp excompiler.cpp expair.cpp expairseq.cpp exprseq.cpp \ + fail.cpp fderivative.cpp function.cpp idx.cpp indexed.cpp inifcns.cpp \ inifcns_trans.cpp inifcns_gamma.cpp inifcns_nstdsums.cpp \ integral.cpp lst.cpp matrix.cpp mul.cpp ncmul.cpp normal.cpp numeric.cpp \ operators.cpp power.cpp registrar.cpp relational.cpp remember.cpp \ @@ -13,9 +13,9 @@ libginac_la_SOURCES = add.cpp archive.cpp basic.cpp clifford.cpp color.cpp \ libginac_la_LDFLAGS = -version-info $(LT_VERSION_INFO) -release $(LT_RELEASE) ginacincludedir = $(includedir)/ginac ginacinclude_HEADERS = ginac.h add.h archive.h assertion.h basic.h class_info.h \ - clifford.h color.h constant.h container.h ex.h expair.h expairseq.h exprseq.h \ - fail.h fderivative.h flags.h function.h hash_map.h idx.h indexed.h inifcns.h \ - integral.h lst.h matrix.h mul.h ncmul.h normal.h numeric.h operators.h \ + clifford.h color.h constant.h container.h ex.h excompiler.h expair.h expairseq.h \ + exprseq.h fail.h fderivative.h flags.h function.h hash_map.h idx.h indexed.h \ + inifcns.h integral.h lst.h matrix.h mul.h ncmul.h normal.h numeric.h operators.h \ power.h print.h pseries.h ptr.h registrar.h relational.h structure.h \ symbol.h symmetry.h tensor.h tinfos.h version.h wildcard.h AM_LFLAGS = -Pginac_yy -olex.yy.c diff --git a/ginac/excompiler.cpp b/ginac/excompiler.cpp new file mode 100644 index 00000000..4f121d7a --- /dev/null +++ b/ginac/excompiler.cpp @@ -0,0 +1,170 @@ +/** @file excompiler.cpp + * + * Class to facilitate the conversion of a ex to a function pointer suited for + * fast numerical integration. */ + +/* + * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "excompiler.h" + +#include +#include +#include +#include +#include +#include + +#include "ex.h" +#include "lst.h" +#include "operators.h" +#include "relational.h" +#include "symbol.h" + +namespace GiNaC { + +#ifdef HAVE_LIBDL + +class excompiler +{ + struct filedesc + { + void* module; + std::string name; + }; +public: + excompiler() {}; + ~excompiler() + { + for (std::vector::const_iterator it = filelist.begin(); it != filelist.end(); ++it) { + dlclose(it->module); + std::string strremove = "rm " + it->name; + system(strremove.c_str()); + } + } + void add(void* module, std::string name) + { + filedesc fd; + fd.module = module; + fd.name = name; + filelist.push_back(fd); + } + std::vector filelist; +}; + +excompiler _exc; + +FP_dim1 compile(const ex& expr, const symbol& sym) +{ + symbol argx("argx"); + ex expr_with_x = expr.subs(lst(sym==argx)); + + char filename[] = "/tmp/GiNaCXXXXXX"; + + int fno = mkstemp(filename); + + std::ofstream ofs(filename); + + ofs << "#include " << std::endl; + ofs << "#include " << std::endl; + ofs << "#include " << std::endl; + ofs << std::endl; + ofs << "double compiled_ex(double argx)" << std::endl; + ofs << "{" << std::endl; + ofs << "double res = "; + expr_with_x.print(GiNaC::print_csrc_double(ofs)); + ofs << ";" << std::endl; + ofs << "return(res); " << std::endl; + ofs << "}" << std::endl; + + ofs.close(); + + std::string strcompile = "ginac-excompiler " + std::string(filename); + system(strcompile.c_str()); + + std::string strremove = "rm " + std::string(filename) + " " + std::string(filename) + ".o"; + system(strremove.c_str()); + + std::string strsofile = std::string(filename) + ".so"; + void* module = NULL; + module = dlopen(strsofile.c_str(), RTLD_NOW); + if (module == NULL) { + throw std::runtime_error("excompiler: could not open compiled module!"); + } + + _exc.add(module, strsofile); + + return (FP_dim1) dlsym(module, "compiled_ex"); +} + +FP_cuba compile(const lst& exprs, const lst& syms) +{ + lst replacements; + for (int count=0; count expr_with_cname; + for (int count=0; count " << std::endl; + ofs << "#include " << std::endl; + ofs << "#include " << std::endl; + ofs << std::endl; + ofs << "void compiled_ex(const int* an, const double a[], const int* fn, double f[])" << std::endl; + ofs << "{" << std::endl; + for (int count=0; count