1 /** @file excompiler.cpp
3 * Class to facilitate the conversion of a ex to a function pointer suited for
4 * fast numerical integration. */
7 * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany
9 * This program is free software; you can redistribute it and/or modify
10 * it under the terms of the GNU General Public License as published by
11 * the Free Software Foundation; either version 2 of the License, or
12 * (at your option) any later version.
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, write to the Free Software
21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
24 #include "excompiler.h"
36 #include "operators.h"
37 #include "relational.h"
55 for (std::vector<filedesc>::const_iterator it = filelist.begin(); it != filelist.end(); ++it) {
57 std::string strremove = "rm " + it->name;
58 system(strremove.c_str());
61 void add(void* module, std::string name)
66 filelist.push_back(fd);
68 std::vector<filedesc> filelist;
73 FP_dim1 compile(const ex& expr, const symbol& sym)
76 ex expr_with_x = expr.subs(lst(sym==argx));
78 char filename[] = "/tmp/GiNaCXXXXXX";
80 int fno = mkstemp(filename);
82 std::ofstream ofs(filename);
84 ofs << "#include <stddef.h> " << std::endl;
85 ofs << "#include <stdlib.h> " << std::endl;
86 ofs << "#include <math.h> " << std::endl;
88 ofs << "double compiled_ex(double argx)" << std::endl;
89 ofs << "{" << std::endl;
90 ofs << "double res = ";
91 expr_with_x.print(GiNaC::print_csrc_double(ofs));
92 ofs << ";" << std::endl;
93 ofs << "return(res); " << std::endl;
94 ofs << "}" << std::endl;
98 std::string strcompile = "ginac-excompiler " + std::string(filename);
99 system(strcompile.c_str());
101 std::string strremove = "rm " + std::string(filename) + " " + std::string(filename) + ".o";
102 system(strremove.c_str());
104 std::string strsofile = std::string(filename) + ".so";
106 module = dlopen(strsofile.c_str(), RTLD_NOW);
107 if (module == NULL) {
108 throw std::runtime_error("excompiler: could not open compiled module!");
111 _exc.add(module, strsofile);
113 return (FP_dim1) dlsym(module, "compiled_ex");
116 FP_cuba compile(const lst& exprs, const lst& syms)
119 for (int count=0; count<syms.nops(); ++count) {
120 std::ostringstream s;
121 s << "a[" << count << "]";
122 replacements.append(syms.op(count) == symbol(s.str()));
125 std::vector<ex> expr_with_cname;
126 for (int count=0; count<exprs.nops(); ++count) {
127 expr_with_cname.push_back(exprs.op(count).subs(replacements));
130 char filename[] = "/tmp/GiNaCXXXXXX";
132 int fno = mkstemp(filename);
134 std::ofstream ofs(filename);
136 ofs << "#include <stddef.h> " << std::endl;
137 ofs << "#include <stdlib.h> " << std::endl;
138 ofs << "#include <math.h> " << std::endl;
140 ofs << "void compiled_ex(const int* an, const double a[], const int* fn, double f[])" << std::endl;
141 ofs << "{" << std::endl;
142 for (int count=0; count<exprs.nops(); ++count) {
143 ofs << "f[" << count << "] = ";
144 expr_with_cname[count].print(GiNaC::print_csrc_double(ofs));
145 ofs << ";" << std::endl;
147 ofs << "}" << std::endl;
151 std::string strcompile = "ginac-excompiler " + std::string(filename);
152 system(strcompile.c_str());
154 std::string strremove = "rm " + std::string(filename) + " " + std::string(filename) + ".o";
155 system(strremove.c_str());
157 std::string strsofile = std::string(filename) + ".so";
159 module = dlopen(strsofile.c_str(), RTLD_NOW);
160 if (module == NULL) {
161 throw std::runtime_error("excompiler: could not open compiled module!");
164 _exc.add(module, strsofile);
166 return (FP_cuba) dlsym(module, "compiled_ex");
171 FP_dim1 compile(const ex& expr, const symbol& sym)
173 throw std::runtime_error("compile has been disabled because of missing libdl!");
177 FP_cuba compile(const lst& exprs, const lst& syms)
179 throw std::runtime_error("compile has been disabled because of missing libdl!");