X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Ffunction.pl;h=b8f7ea7d9f79b630371e39b6c5aeacb7a2af9fdb;hp=aadc3bccf34458477fd44d26eaf0ed7057d51bc4;hb=aa1afbbdb118846cfc266a1d7a8d5188ac214e0e;hpb=217bee1d939abf7f9ed3fe75928a62f7fdc3abcf diff --git a/ginac/function.pl b/ginac/function.pl old mode 100755 new mode 100644 index aadc3bcc..b8f7ea7d --- a/ginac/function.pl +++ b/ginac/function.pl @@ -2,7 +2,7 @@ # function.pl options: \$maxargs=${maxargs} # -# GiNaC Copyright (C) 1999-2006 Johannes Gutenberg University Mainz, Germany +# GiNaC Copyright (C) 1999-2009 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 @@ -79,6 +79,14 @@ $typedef_conjugate_funcp=generate( 'typedef ex (* conjugate_funcp_${N})(${SEQ1});'."\n", 'const ex &','',''); +$typedef_real_part_funcp=generate( +'typedef ex (* real_part_funcp_${N})(${SEQ1});'."\n", +'const ex &','',''); + +$typedef_imag_part_funcp=generate( +'typedef ex (* imag_part_funcp_${N})(${SEQ1});'."\n", +'const ex &','',''); + $typedef_derivative_funcp=generate( 'typedef ex (* derivative_funcp_${N})(${SEQ1}, unsigned);'."\n", 'const ex &','',''); @@ -101,6 +109,10 @@ $evalf_func_interface=generate(' function_options & evalf_func(evalf_funcp_${ $conjugate_func_interface=generate(' function_options & conjugate_func(conjugate_funcp_${N} d);'."\n",'','',''); +$real_part_func_interface=generate(' function_options & real_part_func(real_part_funcp_${N} d);'."\n",'','',''); + +$imag_part_func_interface=generate(' function_options & imag_part_func(imag_part_funcp_${N} d);'."\n",'','',''); + $derivative_func_interface=generate(' function_options & derivative_func(derivative_funcp_${N} d);'."\n",'','',''); $power_func_interface=generate(' function_options & power_func(power_funcp_${N} d);'."\n",'','',''); @@ -126,7 +138,6 @@ $constructors_implementation=generate( function::function(unsigned ser, ${SEQ1}) : exprseq(${SEQ2}), serial(ser) { - tinfo_key = &function::tinfo_static; } END_OF_CONSTRUCTORS_IMPLEMENTATION @@ -149,6 +160,18 @@ $conjugate_switch_statement=generate( return ((conjugate_funcp_${N})(opt.conjugate_f))(${SEQ1}); END_OF_DIFF_SWITCH_STATEMENT +$real_part_switch_statement=generate( + <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','',''); + case ${N}: + return ((real_part_funcp_${N})(opt.real_part_f))(${SEQ1}); +END_OF_DIFF_SWITCH_STATEMENT + +$imag_part_switch_statement=generate( + <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','',''); + case ${N}: + return ((imag_part_funcp_${N})(opt.imag_part_f))(${SEQ1}); +END_OF_DIFF_SWITCH_STATEMENT + $diff_switch_statement=generate( <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','',''); case ${N}: @@ -209,6 +232,26 @@ function_options & function_options::conjugate_func(conjugate_funcp_${N} c) } END_OF_CONJUGATE_FUNC_IMPLEMENTATION +$real_part_func_implementation=generate( + <<'END_OF_REAL_PART_FUNC_IMPLEMENTATION','','',''); +function_options & function_options::real_part_func(real_part_funcp_${N} c) +{ + test_and_set_nparams(${N}); + real_part_f = real_part_funcp(c); + return *this; +} +END_OF_REAL_PART_FUNC_IMPLEMENTATION + +$imag_part_func_implementation=generate( + <<'END_OF_IMAG_PART_FUNC_IMPLEMENTATION','','',''); +function_options & function_options::imag_part_func(imag_part_funcp_${N} c) +{ + test_and_set_nparams(${N}); + imag_part_f = imag_part_funcp(c); + return *this; +} +END_OF_IMAG_PART_FUNC_IMPLEMENTATION + $derivative_func_implementation=generate( <<'END_OF_DERIVATIVE_FUNC_IMPLEMENTATION','','',''); function_options & function_options::derivative_func(derivative_funcp_${N} d) @@ -249,7 +292,7 @@ $interface=< -#include +#include "exprseq.h" // CINT needs to work properly with #include - -#include "exprseq.h" +#include +#include // the following lines have been generated for max. ${maxargs} parameters $declare_function_macro @@ -293,6 +335,8 @@ class symmetry; typedef ex (* eval_funcp)(); typedef ex (* evalf_funcp)(); typedef ex (* conjugate_funcp)(); +typedef ex (* real_part_funcp)(); +typedef ex (* imag_part_funcp)(); typedef ex (* derivative_funcp)(); typedef ex (* power_funcp)(); typedef ex (* series_funcp)(); @@ -302,6 +346,8 @@ typedef void (* print_funcp)(); $typedef_eval_funcp $typedef_evalf_funcp $typedef_conjugate_funcp +$typedef_real_part_funcp +$typedef_imag_part_funcp $typedef_derivative_funcp $typedef_power_funcp $typedef_series_funcp @@ -313,6 +359,8 @@ $typedef_print_funcp typedef ex (* eval_funcp_exvector)(const exvector &); typedef ex (* evalf_funcp_exvector)(const exvector &); typedef ex (* conjugate_funcp_exvector)(const exvector &); +typedef ex (* real_part_funcp_exvector)(const exvector &); +typedef ex (* imag_part_funcp_exvector)(const exvector &); typedef ex (* derivative_funcp_exvector)(const exvector &, unsigned); typedef ex (* power_funcp_exvector)(const exvector &, const ex &); typedef ex (* series_funcp_exvector)(const exvector &, const relational &, int, unsigned); @@ -337,6 +385,8 @@ public: $eval_func_interface $evalf_func_interface $conjugate_func_interface +$real_part_func_interface +$imag_part_func_interface $derivative_func_interface $power_func_interface $series_func_interface @@ -345,6 +395,8 @@ $print_func_interface function_options & eval_func(eval_funcp_exvector e); function_options & evalf_func(evalf_funcp_exvector ef); function_options & conjugate_func(conjugate_funcp_exvector d); + function_options & real_part_func(real_part_funcp_exvector d); + function_options & imag_part_func(imag_part_funcp_exvector d); function_options & derivative_func(derivative_funcp_exvector d); function_options & power_func(power_funcp_exvector d); function_options & series_func(series_funcp_exvector s); @@ -356,7 +408,7 @@ $print_func_interface return *this; } - function_options & set_return_type(unsigned rt); + function_options & set_return_type(unsigned rt, const return_type_t* rtt = 0); function_options & do_not_evalf_params(); function_options & remember(unsigned size, unsigned assoc_size=0, unsigned strategy=remember_strategies::delete_never); @@ -380,6 +432,8 @@ protected: eval_funcp eval_f; evalf_funcp evalf_f; conjugate_funcp conjugate_f; + real_part_funcp real_part_f; + imag_part_funcp imag_part_f; derivative_funcp derivative_f; power_funcp power_f; series_funcp series_f; @@ -389,7 +443,7 @@ protected: bool use_return_type; unsigned return_type; - const basic* return_type_tinfo; + return_type_t return_type_tinfo; bool use_remember; unsigned remember_size; @@ -399,6 +453,8 @@ protected: bool eval_use_exvector_args; bool evalf_use_exvector_args; bool conjugate_use_exvector_args; + bool real_part_use_exvector_args; + bool imag_part_use_exvector_args; bool derivative_use_exvector_args; bool power_use_exvector_args; bool series_use_exvector_args; @@ -449,17 +505,22 @@ public: ex expand(unsigned options=0) const; ex eval(int level=0) const; ex evalf(int level=0) const; + ex eval_ncmul(const exvector & v) const; unsigned calchash() const; ex series(const relational & r, int order, unsigned options = 0) const; ex thiscontainer(const exvector & v) const; ex thiscontainer(std::auto_ptr vp) const; ex conjugate() const; + ex real_part() const; + ex imag_part() const; + void archive(archive_node& n) const; + void read_archive(const archive_node& n, lst& syms); protected: ex derivative(const symbol & s) const; bool is_equal_same_type(const basic & other) const; bool match_same_type(const basic & other) const; unsigned return_type() const; - const basic* return_type_tinfo() const; + return_type_t return_type_tinfo() const; // new virtual functions which can be overridden by derived classes // none @@ -483,6 +544,7 @@ public: protected: unsigned serial; }; +GINAC_DECLARE_UNARCHIVER(function); // utility functions/macros @@ -498,7 +560,7 @@ inline bool is_the_function(const ex & x) } // namespace GiNaC -#endif // ndef __GINAC_FUNCTION_H__ +#endif // ndef GINAC_FUNCTION_H END_OF_INTERFACE @@ -512,7 +574,7 @@ $implementation=< -#include -#include -#include - #include "function.h" #include "operators.h" #include "fderivative.h" @@ -546,8 +603,15 @@ $implementation=< +#include +#include +#include +#include + namespace GiNaC { ////////// @@ -581,12 +645,15 @@ void function_options::initialize() { set_name("unnamed_function", "\\\\mbox{unnamed}"); nparams = 0; - eval_f = evalf_f = conjugate_f = derivative_f = power_f = series_f = 0; + eval_f = evalf_f = real_part_f = imag_part_f = conjugate_f = derivative_f + = power_f = series_f = 0; evalf_params_first = true; use_return_type = false; eval_use_exvector_args = false; evalf_use_exvector_args = false; conjugate_use_exvector_args = false; + real_part_use_exvector_args = false; + imag_part_use_exvector_args = false; derivative_use_exvector_args = false; power_use_exvector_args = false; series_use_exvector_args = false; @@ -617,6 +684,8 @@ function_options & function_options::latex_name(std::string const & tn) $eval_func_implementation $evalf_func_implementation $conjugate_func_implementation +$real_part_func_implementation +$imag_part_func_implementation $derivative_func_implementation $power_func_implementation $series_func_implementation @@ -640,6 +709,19 @@ function_options& function_options::conjugate_func(conjugate_funcp_exvector c) conjugate_f = conjugate_funcp(c); return *this; } +function_options& function_options::real_part_func(real_part_funcp_exvector c) +{ + real_part_use_exvector_args = true; + real_part_f = real_part_funcp(c); + return *this; +} +function_options& function_options::imag_part_func(imag_part_funcp_exvector c) +{ + imag_part_use_exvector_args = true; + imag_part_f = imag_part_funcp(c); + return *this; +} + function_options& function_options::derivative_func(derivative_funcp_exvector d) { derivative_use_exvector_args = true; @@ -659,10 +741,14 @@ function_options& function_options::series_func(series_funcp_exvector s) return *this; } -function_options & function_options::set_return_type(unsigned rt) +function_options & function_options::set_return_type(unsigned rt, const return_type_t* rtt) { use_return_type = true; return_type = rt; + if (rtt != 0) + return_type_tinfo = *rtt; + else + return_type_tinfo = make_return_type_t(); return *this; } @@ -730,7 +816,6 @@ GINAC_IMPLEMENT_REGISTERED_CLASS(function, exprseq) function::function() : serial(0) { - tinfo_key = &function::tinfo_static; } ////////// @@ -741,7 +826,6 @@ function::function() : serial(0) function::function(unsigned ser) : serial(ser) { - tinfo_key = &function::tinfo_static; } // the following lines have been generated for max. ${maxargs} parameters @@ -750,7 +834,6 @@ $constructors_implementation function::function(unsigned ser, const exprseq & es) : exprseq(es), serial(ser) { - tinfo_key = &function::tinfo_static; // Force re-evaluation even if the exprseq was already evaluated // (the exprseq copy constructor copies the flags) @@ -760,13 +843,14 @@ function::function(unsigned ser, const exprseq & es) : exprseq(es), serial(ser) function::function(unsigned ser, const exvector & v, bool discardable) : exprseq(v,discardable), serial(ser) { - tinfo_key = &function::tinfo_static; + if ( ser >= registered_functions().size() ) { + throw std::runtime_error("function does not exist"); + } } function::function(unsigned ser, std::auto_ptr vp) : exprseq(vp), serial(ser) { - tinfo_key = &function::tinfo_static; } ////////// @@ -774,8 +858,9 @@ function::function(unsigned ser, std::auto_ptr vp) ////////// /** Construct object from archive_node. */ -function::function(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) +void function::read_archive(const archive_node& n, lst& sym_lst) { + inherited::read_archive(n, sym_lst); // Find serial number by function name std::string s; if (n.find_string("name", s)) { @@ -793,12 +878,6 @@ function::function(const archive_node &n, lst &sym_lst) : inherited(n, sym_lst) throw (std::runtime_error("unnamed function in archive")); } -/** Unarchive the object. */ -ex function::unarchive(const archive_node &n, lst &sym_lst) -{ - return (new function(n, sym_lst))->setflag(status_flags::dynallocated); -} - /** Archive the object. */ void function::archive(archive_node &n) const { @@ -807,6 +886,8 @@ void function::archive(archive_node &n) const n.add_string("name", registered_functions()[serial].name); } +GINAC_BIND_UNARCHIVER(function); + ////////// // functions overriding virtual functions from base classes ////////// @@ -904,7 +985,7 @@ ex function::eval(int level) const exvector v = seq; GINAC_ASSERT(is_a(opt.symtree)); int sig = canonicalize(v.begin(), ex_to(opt.symtree)); - if (sig != INT_MAX) { + if (sig != std::numeric_limits::max()) { // Something has changed while sorting arguments, more evaluations later if (sig == 0) return _ex0; @@ -973,9 +1054,19 @@ ${evalf_switch_statement} throw(std::logic_error("function::evalf(): invalid nparams")); } +/** + * This method is defined to be in line with behaviour of function::return_type() + */ +ex function::eval_ncmul(const exvector & v) const +{ + // If this function is called then the list of arguments is non-empty + // and the first argument is non-commutative, see function::return_type() + return seq.begin()->eval_ncmul(v); +} + unsigned function::calchash() const { - unsigned v = golden_ratio_hash(golden_ratio_hash((p_int)tinfo()) ^ serial); + unsigned v = golden_ratio_hash(make_hash_seed(typeid(*this)) ^ serial); for (size_t i=0; iop(i).gethash(); @@ -1048,6 +1139,46 @@ ${conjugate_switch_statement} throw(std::logic_error("function::conjugate(): invalid nparams")); } +/** Implementation of ex::real_part for functions. */ +ex function::real_part() const +{ + GINAC_ASSERT(serial(); else return seq.begin()->return_type_tinfo(); } @@ -1199,8 +1330,8 @@ ${power_switch_statement} std::vector & function::registered_functions() { - static std::vector * rf = new std::vector; - return *rf; + static std::vector rf = std::vector(); + return rf; } bool function::lookup_remember_table(ex & result) const @@ -1260,7 +1391,9 @@ unsigned function::find_function(const std::string &name, unsigned nparams) /** Return the print name of the function. */ std::string function::get_name() const { - GINAC_ASSERT(serial= registered_functions().size() ) { + throw std::runtime_error("unknown function"); + } return registered_functions()[serial].name; }