/** @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 "config.h" #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