X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Ffunction.pl;h=47cc5492bf5867be978fe666c4d97081ebe4e7f1;hp=258f4a07b82ea18fce25d639ea58317d68b1cbfe;hb=ec397a253020039a0b0ea4ec5e91dde24100366a;hpb=ca4c4bce2953c1abdf041f082c8e28c429eb6b77 diff --git a/ginac/function.pl b/ginac/function.pl index 258f4a07..47cc5492 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -80,7 +80,6 @@ $constructors_implementation=generate( function::function(unsigned ser, ${SEQ1}) : exprseq(${SEQ2}), serial(ser) { - debugmsg(\"function ctor from unsigned,${N}*ex\",LOGLEVEL_CONSTRUCT); tinfo_key = TINFO_function; } END_OF_CONSTRUCTORS_IMPLEMENTATION @@ -201,25 +200,6 @@ $declare_function_macro const unsigned function_index_##NAME= \\ GiNaC::function::register_new(GiNaC::function_options(#NAME).OPT); -#define BEGIN_TYPECHECK \\ -bool automatic_typecheck=true; - -#define TYPECHECK(VAR,TYPE) \\ -if (!is_exactly_a(VAR)) { \\ - automatic_typecheck=false; \\ -} else - -#define TYPECHECK_INTEGER(VAR) \\ -if (!(VAR).info(GiNaC::info_flags::integer)) { \\ - automatic_typecheck=false; \\ -} else - -#define END_TYPECHECK(RV) \\ -{} \\ -if (!automatic_typecheck) { \\ - return RV.hold(); \\ -} - namespace GiNaC { class function; @@ -237,6 +217,13 @@ $typedef_derivative_funcp $typedef_series_funcp // end of generated lines +// Alternatively, an exvector may be passed into the static function, instead +// of individual ex objects. Then, the number of arguments is not limited. +typedef ex (* eval_funcp_exvector)(const exvector &); +typedef ex (* evalf_funcp_exvector)(const exvector &); +typedef ex (* derivative_funcp_exvector)(const exvector &, unsigned); +typedef ex (* series_funcp_exvector)(const exvector &, const relational &, int, unsigned); + class function_options { friend class function; @@ -254,6 +241,11 @@ $evalf_func_interface $derivative_func_interface $series_func_interface // end of generated lines + function_options & eval_func(eval_funcp_exvector e); + function_options & evalf_func(evalf_funcp_exvector ef); + function_options & derivative_func(derivative_funcp_exvector d); + function_options & series_func(series_funcp_exvector s); + function_options & set_return_type(unsigned rt, unsigned rtt=0); function_options & do_not_evalf_params(void); function_options & remember(unsigned size, unsigned assoc_size=0, @@ -287,6 +279,11 @@ protected: unsigned remember_assoc_size; unsigned remember_strategy; + bool eval_use_exvector_args; + bool evalf_use_exvector_args; + bool derivative_use_exvector_args; + bool series_use_exvector_args; + unsigned functions_with_same_name; ex symtree; @@ -351,10 +348,11 @@ protected: void store_remember_table(ex const & result) const; public: static unsigned register_new(function_options const & opt); + static unsigned current_serial; static unsigned find_function(const std::string &name, unsigned nparams); unsigned get_serial(void) const {return serial;} std::string get_name(void) const; - + // member variables protected: @@ -362,12 +360,6 @@ protected: }; // utility functions/macros -/** Return the object of type function handled by an ex. - * This is unsafe: you need to check the type first. */ -inline const function &ex_to_function(const ex &e) -{ - return static_cast(*e.bp); -} /** Specialization of is_exactly_a(obj) for objects of type function. */ template<> inline bool is_exactly_a(const basic & obj) @@ -376,7 +368,7 @@ template<> inline bool is_exactly_a(const basic & obj) } #define is_ex_the_function(OBJ, FUNCNAME) \\ - (is_ex_exactly_of_type(OBJ, function) && static_cast(OBJ.bp)->get_serial() == function_index_##FUNCNAME) + (is_exactly_a(OBJ) && ex_to(OBJ).get_serial() == function_index_##FUNCNAME) } // namespace GiNaC @@ -411,6 +403,7 @@ $implementation=< #include #include #include @@ -425,7 +418,6 @@ $implementation=<(s)) ? 1 : 0; } int function::ldegree(const ex & s) const { - return is_equal(*s.bp) ? 1 : 0; + return is_equal(ex_to(s)) ? 1 : 0; } ex function::coeff(const ex & s, int n) const { - if (is_equal(*s.bp)) - return n==1 ? _ex1() : _ex0(); + if (is_equal(ex_to(s))) + return n==1 ? _ex1 : _ex0; else - return n==0 ? ex(*this) : _ex0(); + return n==0 ? ex(*this) : _ex0; } ex function::eval(int level) const @@ -739,7 +756,7 @@ ex function::eval(int level) const if (sig != INT_MAX) { // Something has changed while sorting arguments, more evaluations later if (sig == 0) - return _ex0(); + return _ex0; return ex(sig) * thisexprseq(v); } } @@ -753,7 +770,10 @@ ex function::eval(int level) const if (use_remember && lookup_remember_table(eval_result)) { return eval_result; } - + current_serial = serial; + if (registered_functions()[serial].eval_use_exvector_args) + eval_result = ((eval_funcp_exvector)(registered_functions()[serial].eval_f))(seq); + else switch (opt.nparams) { // the following lines have been generated for max. ${maxargs} parameters ${eval_switch_statement} @@ -789,6 +809,9 @@ ex function::evalf(int level) const if (registered_functions()[serial].evalf_f==0) { return function(serial,eseq).hold(); } + current_serial = serial; + if (registered_functions()[serial].evalf_use_exvector_args) + return ((evalf_funcp_exvector)(registered_functions()[serial].evalf_f))(seq); switch (registered_functions()[serial].nparams) { // the following lines have been generated for max. ${maxargs} parameters ${evalf_switch_statement} @@ -832,6 +855,15 @@ ex function::series(const relational & r, int order, unsigned options) const return basic::series(r, order); } ex res; + current_serial = serial; + if (registered_functions()[serial].series_use_exvector_args) { + try { + res = ((series_funcp_exvector)(registered_functions()[serial].series_f))(seq, r, order, options); + } catch (do_taylor) { + res = basic::series(r, order, options); + } + return res; + } switch (registered_functions()[serial].nparams) { // the following lines have been generated for max. ${maxargs} parameters ${series_switch_statement} @@ -936,6 +968,9 @@ ex function::pderivative(unsigned diff_param) const // partial differentiation if (registered_functions()[serial].derivative_f == NULL) return fderivative(serial, diff_param, seq); + current_serial = serial; + if (registered_functions()[serial].derivative_use_exvector_args) + return ((derivative_funcp_exvector)(registered_functions()[serial].derivative_f))(seq, diff_param); switch (registered_functions()[serial].nparams) { // the following lines have been generated for max. ${maxargs} parameters ${diff_switch_statement}