27#ifndef GINAC_FUNCTIONS_H_
28#define GINAC_FUNCTIONS_H_
30#include <ginac/ginac.h>
31#include <ginac/power.h>
45#define MKTEMP(path,n) _mktemp_s(path, n)
46#elif defined(__MINGW32__)
48#define MKTEMP(path,n) _mktemp(path)
51extern "C" int mkstemps (
char *path,
int len);
52#define MKTEMP(path,n) mkstemps(path,n)
58using namespace GiNaC ;
70 static map<string, realsymbol> symbol_list;
71 map<string, realsymbol>::iterator it = symbol_list.find(sym_name);
72 if (it != symbol_list.end())
75 return symbol_list.insert(pair<string, realsymbol>(sym_name, realsymbol(sym_name))).first->second;
111static ex sinc_evalf(
const ex & x){
113 double d = (ex_to<numeric>(x)).to_double();
114 return ( d==0.0 ? 1 : sin(d)/d );
120static ex sinc_deriv(
const ex & x,
unsigned diff_param) {
124 return cos(x)/x - sin(x)/(x*x);
128static ex sinc_real_part(
const ex & x)
133 return ( ( ( real_part(x)*cosh(imag_part(x))*sin(real_part(x)) ) +
134 ( imag_part(x)*sinh(imag_part(x))*cos(real_part(x)) ) ) /
135 ( pow(real_part(x),2) + pow(imag_part(x),2) ) );
139static ex sinc_imag_part(
const ex & x)
144 return ( ( ( real_part(x)*sinh(imag_part(x))*cos(real_part(x)) ) -
145 ( imag_part(x)*cosh(imag_part(x))*sin(real_part(x)) ) ) /
146 ( pow(real_part(x),2) + pow(imag_part(x),2) ) );
149static ex sinc_conjugate(
const ex & x) {
153 return sin(x.conjugate())/x.conjugate();
156DECLARE_FUNCTION_1P(sinc)
158 evalf_func (sinc_evalf ).
159 derivative_func(sinc_deriv ).
160 real_part_func (sinc_real_part).
161 imag_part_func (sinc_imag_part).
162 conjugate_func (sinc_conjugate))
170static ex floor_evalf(const ex &x){
171 if (!is_a<numeric>(x) )
return x;
172 ex xn = ex_to<numeric>(x);
173 return ((
int) ex_to<numeric>(xn).to_double() );
175DECLARE_FUNCTION_1P(floor)
184 if (!is_a<numeric>(x) || !is_a<numeric>(y))
return 0;
185 ex xn = ex_to<numeric>(x);
186 ex yn = ex_to<numeric>(y);
187 return (xn - floor_evalf(xn/yn)*yn);
189DECLARE_FUNCTION_2P(mod)
198 if (!is_a<numeric>(x) || !is_a<numeric>(y))
return 0;
199 ex xn = ex_to<numeric>(x);
200 ex yn = ex_to<numeric>(y);
201 int b = ((int) ( ex_to<numeric>(xn).to_double()
202 == ex_to<numeric>(yn).to_double() ) );
205DECLARE_FUNCTION_2P(equal)
214 if (!is_a<numeric>(x) || !is_a<numeric>(y))
return 0;
215 ex xn = ex_to<numeric>(x);
216 ex yn = ex_to<numeric>(y);
217 int b = ((int) ( ex_to<numeric>(xn).to_double()
218 > ex_to<numeric>(yn).to_double() ) );
221DECLARE_FUNCTION_2P(gt)
230 if (!is_a<numeric>(x) || !is_a<numeric>(y))
return 0;
231 ex xn = ex_to<numeric>(x);
232 ex yn = ex_to<numeric>(y);
233 int b = ((int) ( ex_to<numeric>(xn).to_double()
234 < ex_to<numeric>(yn).to_double() ) );
237DECLARE_FUNCTION_2P(lt)
245static ex
ite_evalf(const ex &a, const ex &b, const ex &x, const ex &y){
246 if (!is_a<numeric>(x) || !is_a<numeric>(y))
return 0;
247 ex xn = ex_to<numeric>(x);
248 ex yn = ex_to<numeric>(y);
252DECLARE_FUNCTION_4P(ite)
262static ex Vector_evalf(const ex &i){
263 if (!is_a<numeric>(i) )
return 0;
264 unsigned int in = ((int) ex_to<numeric>(i).to_double() );
265 if ( (*m_static_vector).size() > in )
266 return (*m_static_vector).at(in);
270DECLARE_FUNCTION_1P(Vector)
288 std::vector<filedesc> filelist;
292 for (std::vector<filedesc>::const_iterator it = filelist.begin(); it != filelist.end(); ++it) {
296 void add_opened_module(
void* module,
const std::string& name,
bool clean_up)
301 fd.clean_up = clean_up;
302 filelist.push_back(fd);
304 void clean_up(
const std::vector<filedesc>::const_iterator it)
310 remove(it->name.c_str());
313 void create_src_file(std::string& filename, std::ofstream& ofs)
316 if (filename.empty()) {
317 const char* filename_pattern =
"./GiNaCXXXXXX";
318 char* new_filename =
new char[strlen(filename_pattern)+1];
319 strcpy(new_filename, filename_pattern);
320 #ifndef HAVE_MKSTEMPS
321 if (!mkstemp(new_filename)) {
322 delete[] new_filename;
323 throw std::runtime_error(
"mktemp failed");
326 if (!MKTEMP(new_filename, 0)) {
327 delete[] new_filename;
328 throw std::runtime_error(
"mktemps failed");
331 filename = std::string(new_filename);
332 ofs.open(new_filename, std::ios::out);
333 delete[] new_filename;
335 ofs.open(filename.c_str(), std::ios::out);
339 throw std::runtime_error(
"could not create source code file for compilation");
342 ofs <<
"#include <stddef.h> " << std::endl;
343 ofs <<
"#include <stdlib.h> " << std::endl;
344 ofs <<
"#include <math.h> " << std::endl;
348 void compile_src_file(
const std::string filename,
bool clean_up)
350 std::string strcompile =
"ginac-excompiler " + filename;
351 if (system(strcompile.c_str())) {
352 throw std::runtime_error(
"excompiler::compile_src_file: error compiling source file!");
355 remove(filename.c_str());
358 void* link_so_file(
const std::string filename,
bool clean_up)
362 module = dlopen(filename.c_str(), RTLD_NOW);
364 if (module == NULL) {
365 throw std::runtime_error(
"excompiler::link_so_file: could not open compiled module!");
368 add_opened_module(module, filename, clean_up);
371 return dlsym(module,
"compiled_ex");
374 void unlink(
const std::string filename)
376 for (std::vector<filedesc>::iterator it = filelist.begin(); it != filelist.end();) {
377 if (it->name == filename) {
379 it = filelist.erase(it);
387typedef double (*FUNCP_4P) (double, double, double, double);
388static excompiler global_excompiler;
389void compile_ex(
const ex& expr,
const symbol& sym1,
const symbol& sym2,
const symbol& sym3,
const symbol& sym4,
390 FUNCP_4P& fp,
const std::string filename =
"") {
392 symbol x(
"x"), y(
"y"), z(
"z"), g(
"g");
393 std::initializer_list<ex> vec = {sym1==x, sym2==y, sym3==z, sym4==g};
394 ex expr_with_xyzg = expr.subs(lst(vec));
397 std::string unique_filename = filename;
398 global_excompiler.create_src_file(unique_filename, ofs);
400 ofs <<
"double compiled_ex(double x, double y, double z, double g)" << std::endl;
401 ofs <<
"{" << std::endl;
402 ofs <<
"double res = ";
403 expr_with_xyzg.print(GiNaC::print_csrc_double(ofs));
404 ofs <<
";" << std::endl;
405 ofs <<
"return(res); " << std::endl;
406 ofs <<
"}" << std::endl;
410 global_excompiler.compile_src_file(unique_filename, filename.empty());
411 fp = (FUNCP_4P) global_excompiler.link_so_file(unique_filename+
".so", filename.empty());
static ex lt_evalf(const ex &x, const ex &y)
less_than routine.
Definition ginac_functions.h:229
const symbol & get_symbol(const string &sym_name)
Get a unique GiNaC symbol.
Definition ginac_functions.h:68
static vector< double > * m_static_vector
Vector element.
Definition ginac_functions.h:261
static ex gt_evalf(const ex &x, const ex &y)
greater_than routine.
Definition ginac_functions.h:213
REGISTER_FUNCTION(sinc, eval_func(sinc_eval). evalf_func(sinc_evalf). derivative_func(sinc_deriv). real_part_func(sinc_real_part). imag_part_func(sinc_imag_part). conjugate_func(sinc_conjugate)) static ex floor_evalf(const ex &x)
floor routine.
Definition ginac_functions.h:157
static ex sinc_eval(const ex &x)
sqrt-function. (problem on mac: libc++abi.dylib throws exception: "sqrt" function is not recognized i...
Definition ginac_functions.h:104
static ex ite_evalf(const ex &a, const ex &b, const ex &x, const ex &y)
IfThenElse routine.
Definition ginac_functions.h:245
static ex equal_evalf(const ex &x, const ex &y)
equal routine.
Definition ginac_functions.h:197
static ex mod_evalf(const ex &x, const ex &y)
Mod routine.
Definition ginac_functions.h:183