X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Ffunction.pl;h=565b0f91c4b9f98ac58874a19a3b659393689dfd;hb=b11c30cf00d90113c924e4a96e8fed0341c246c6;hp=6854638b82fdb372c6b99c15fc7fc73780921c30;hpb=591b85b0697370f2f5f25a29a1e94ff831a02c12;p=ginac.git diff --git a/ginac/function.pl b/ginac/function.pl index 6854638b..565b0f91 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -34,25 +34,11 @@ sub generate { return generate_from_to($template,$seq_template1,$seq_template2,1,$maxargs); } -$declare_function_macro = <<'END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO'; -#define DECLARE_FUNCTION_1P(NAME) \ -extern const unsigned function_index_##NAME; \ -inline GiNaC::function NAME(const GiNaC::ex & p1) { \ - return GiNaC::function(function_index_##NAME, p1); \ -} -#define DECLARE_FUNCTION_2P(NAME) \ -extern const unsigned function_index_##NAME; \ -inline GiNaC::function NAME(const GiNaC::ex & p1, const GiNaC::ex & p2) { \ - return GiNaC::function(function_index_##NAME, p1, p2); \ -} - -END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO - -$declare_function_macro .= generate_from_to( - <<'END_OF_DECLARE_FUNCTION_MACRO','const GiNaC::ex & p${N}','p${N}',3,$maxargs); +$declare_function_macro = generate_from_to( + <<'END_OF_DECLARE_FUNCTION_MACRO','const GiNaC::ex & p${N}','p${N}',1,$maxargs); #define DECLARE_FUNCTION_${N}P(NAME) \\ extern const unsigned function_index_##NAME; \\ -inline GiNaC::function NAME(${SEQ1}) { \\ +inline const GiNaC::function NAME(${SEQ1}) { \\ return GiNaC::function(function_index_##NAME, ${SEQ2}); \\ } @@ -99,7 +85,7 @@ END_OF_CONSTRUCTORS_IMPLEMENTATION $eval_switch_statement=generate( <<'END_OF_EVAL_SWITCH_STATEMENT','seq[${N}-1]',''); case ${N}: - eval_result=((eval_funcp_${N})(registered_functions()[serial].eval_f))(${SEQ1}); + eval_result = ((eval_funcp_${N})(registered_functions()[serial].eval_f))(${SEQ1}); break; END_OF_EVAL_SWITCH_STATEMENT @@ -131,9 +117,9 @@ $eval_func_implementation=generate( function_options & function_options::eval_func(eval_funcp_${N} e) { test_and_set_nparams(${N}); - eval_f=eval_funcp(e); + eval_f = eval_funcp(e); return *this; -} +} END_OF_EVAL_FUNC_IMPLEMENTATION $evalf_func_implementation=generate( @@ -141,9 +127,9 @@ $evalf_func_implementation=generate( function_options & function_options::evalf_func(evalf_funcp_${N} ef) { test_and_set_nparams(${N}); - evalf_f=evalf_funcp(ef); + evalf_f = evalf_funcp(ef); return *this; -} +} END_OF_EVALF_FUNC_IMPLEMENTATION $derivative_func_implementation=generate( @@ -151,9 +137,9 @@ $derivative_func_implementation=generate( function_options & function_options::derivative_func(derivative_funcp_${N} d) { test_and_set_nparams(${N}); - derivative_f=derivative_funcp(d); + derivative_f = derivative_funcp(d); return *this; -} +} END_OF_DERIVATIVE_FUNC_IMPLEMENTATION $series_func_implementation=generate( @@ -161,9 +147,9 @@ $series_func_implementation=generate( function_options & function_options::series_func(series_funcp_${N} s) { test_and_set_nparams(${N}); - series_f=series_funcp(s); + series_f = series_funcp(s); return *this; -} +} END_OF_SERIES_FUNC_IMPLEMENTATION $interface=< #include -// CINT needs to work properly with +// CINT needs to work properly with #include #include "exprseq.h" @@ -212,14 +198,6 @@ $declare_function_macro const unsigned function_index_##NAME= \\ GiNaC::function::register_new(GiNaC::function_options(#NAME).OPT); -#define REGISTER_FUNCTION_OLD(NAME,E,EF,D,S) \\ -const unsigned function_index_##NAME= \\ - GiNaC::function::register_new(GiNaC::function_options(#NAME). \\ - eval_func(E). \\ - evalf_func(EF). \\ - derivative_func(D). \\ - series_func(S)); - #define BEGIN_TYPECHECK \\ bool automatic_typecheck=true; @@ -281,6 +259,7 @@ $series_func_interface void test_and_set_nparams(unsigned n); std::string get_name(void) const { return name; } unsigned get_nparams(void) const { return nparams; } + bool has_derivative(void) const { return derivative_f != NULL; } protected: std::string name; @@ -323,6 +302,7 @@ class function : public exprseq friend class remember_table_entry; // friend class remember_table_list; // friend class remember_table; + friend ex Derivative_eval(const ex &, const ex &); // member functions @@ -333,7 +313,7 @@ public: $constructors_interface // end of generated lines function(unsigned ser, const exprseq & es); - function(unsigned ser, const exvector & v, bool discardable=0); + function(unsigned ser, const exvector & v, bool discardable = false); function(unsigned ser, exvector * vp); // vp will be deleted // functions overriding virtual functions from bases classes @@ -348,12 +328,12 @@ public: ex evalf(int level=0) const; unsigned calchash(void) const; ex series(const relational & r, int order, unsigned options = 0) const; - bool match(const ex & pattern, lst & repl_lst) const; ex thisexprseq(const exvector & v) const; ex thisexprseq(exvector * vp) const; 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(void) const; unsigned return_type_tinfo(void) const; @@ -468,12 +448,12 @@ function_options::~function_options() void function_options::initialize(void) { set_name("unnamed_function","\\\\mbox{unnamed}"); - nparams=0; - eval_f=evalf_f=derivative_f=series_f=0; - evalf_params_first=true; - use_return_type=false; - use_remember=false; - functions_with_same_name=1; + nparams = 0; + eval_f = evalf_f = derivative_f = series_f = 0; + evalf_params_first = true; + use_return_type = false; + use_remember = false; + functions_with_same_name = 1; symtree = 0; } @@ -481,11 +461,10 @@ function_options & function_options::set_name(std::string const & n, std::string const & tn) { name=n; - if (tn==std::string()) { - TeX_name="\\\\mbox{"+name+"}"; - } else { - TeX_name=tn; - } + if (tn==std::string()) + TeX_name = "\\\\mbox{"+name+"}"; + else + TeX_name = tn; return *this; } @@ -504,15 +483,15 @@ $series_func_implementation function_options & function_options::set_return_type(unsigned rt, unsigned rtt) { - use_return_type=true; - return_type=rt; - return_type_tinfo=rtt; + use_return_type = true; + return_type = rt; + return_type_tinfo = rtt; return *this; } function_options & function_options::do_not_evalf_params(void) { - evalf_params_first=false; + evalf_params_first = false; return *this; } @@ -520,16 +499,16 @@ function_options & function_options::remember(unsigned size, unsigned assoc_size, unsigned strategy) { - use_remember=true; - remember_size=size; - remember_assoc_size=assoc_size; - remember_strategy=strategy; + use_remember = true; + remember_size = size; + remember_assoc_size = assoc_size; + remember_strategy = strategy; return *this; } function_options & function_options::overloaded(unsigned o) { - functions_with_same_name=o; + functions_with_same_name = o; return *this; } @@ -542,7 +521,7 @@ function_options & function_options::set_symmetry(const symmetry & s) void function_options::test_and_set_nparams(unsigned n) { if (nparams==0) { - nparams=n; + nparams = n; } else if (nparams!=n) { // we do not throw an exception here because this code is // usually executed before main(), so the exception could not @@ -571,13 +550,14 @@ function::function() : serial(0) void function::copy(const function & other) { - exprseq::copy(other); - serial=other.serial; + inherited::copy(other); + serial = other.serial; } void function::destroy(bool call_parent) { - if (call_parent) exprseq::destroy(call_parent); + if (call_parent) + inherited::destroy(call_parent); } ////////// @@ -635,7 +615,7 @@ function::function(const archive_node &n, const lst &sym_lst) : inherited(n, sym serial = ser; return; } - i++; ser++; + ++i; ++ser; } throw (std::runtime_error("unknown function '" + s + "' in archive")); } else @@ -676,7 +656,7 @@ void function::print(const print_context & c, unsigned level) const << ", nops=" << nops() << std::endl; unsigned delta_indent = static_cast(c).delta_indent; - for (unsigned i=0; iprint(c); - it++; + ++it; if (it != itend) c.s << ","; } @@ -709,7 +690,11 @@ void function::print(const print_context & c, unsigned level) const ex function::expand(unsigned options) const { - return this->setflag(status_flags::expanded); + // Only expand arguments when asked to do so + if (options & expand_options::expand_function_args) + return inherited::expand(options); + else + return (options == 0) ? setflag(status_flags::expanded) : *this; } int function::degree(const ex & s) const @@ -758,7 +743,7 @@ ex function::eval(int level) const return this->hold(); } - bool use_remember=opt.use_remember; + bool use_remember = opt.use_remember; ex eval_result; if (use_remember && lookup_remember_table(eval_result)) { return eval_result; @@ -781,7 +766,20 @@ ex function::evalf(int level) const { GINAC_ASSERT(serialevalf(level)); + ++it; + } if (registered_functions()[serial].evalf_f==0) { return function(serial,eseq).hold(); @@ -837,17 +835,8 @@ ${series_switch_statement} throw(std::logic_error("function::series(): invalid nparams")); } -bool function::match(const ex & pattern, lst & repl_lst) const -{ - // Serial number must match - if (is_ex_of_type(pattern, function) && serial != ex_to(pattern).serial) - return false; - return inherited::match(pattern, repl_lst); -} - // protected - /** Implementation of ex::diff() for functions. It applies the chain rule, * except for the Order term function. * \@see ex::diff */ @@ -876,7 +865,8 @@ ex function::derivative(const symbol & s) const } else { // Chain rule ex arg_diff; - for (unsigned i=0; i!=seq.size(); i++) { + unsigned num = seq.size(); + for (unsigned i=0; i(const_cast(other)); + const function & o = static_cast(other); - if (serial!=o.serial) { + if (serial != o.serial) return serial < o.serial ? -1 : 1; - } - return exprseq::compare_same_type(o); + else + return exprseq::compare_same_type(o); } bool function::is_equal_same_type(const basic & other) const { GINAC_ASSERT(is_of_type(other, function)); - const function & o=static_cast(const_cast(other)); + const function & o = static_cast(other); + + if (serial != o.serial) + return false; + else + return exprseq::is_equal_same_type(o); +} + +bool function::match_same_type(const basic & other) const +{ + GINAC_ASSERT(is_of_type(other, function)); + const function & o = static_cast(other); - if (serial!=o.serial) return false; - return exprseq::is_equal_same_type(o); + return serial == o.serial; } unsigned function::return_type(void) const { - if (seq.size()==0) { + if (seq.empty()) return return_types::commutative; - } - return (*seq.begin()).return_type(); + else + return seq.begin()->return_type(); } - + unsigned function::return_type_tinfo(void) const { - if (seq.size()==0) { + if (seq.empty()) return tinfo_key; - } - return (*seq.begin()).return_type_tinfo(); + else + return seq.begin()->return_type_tinfo(); } ////////// @@ -949,7 +949,7 @@ ex function::pderivative(unsigned diff_param) const // partial differentiation // the following lines have been generated for max. ${maxargs} parameters ${diff_switch_statement} // end of generated lines - } + } throw(std::logic_error("function::pderivative(): no diff function defined")); } @@ -973,10 +973,10 @@ void function::store_remember_table(ex const & result) const unsigned function::register_new(function_options const & opt) { - unsigned same_name=0; + unsigned same_name = 0; for (unsigned i=0; i=opt.functions_with_same_name) { @@ -1007,8 +1007,8 @@ unsigned function::find_function(const std::string &name, unsigned nparams) while (i != end) { if (i->get_name() == name && i->get_nparams() == nparams) return serial; - i++; - serial++; + ++i; + ++serial; } throw (std::runtime_error("no function '" + name + "' with " + ToString(nparams) + " parameters defined")); }