X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Ffunction.pl;h=6dbee8bb1039b6385f016555ed24f2ced46c351e;hb=2c2f86ef17534853bc9b5e9c03229c5b57862d98;hp=6ebdada4080be3dba8bf6db65d0e68f469b1d6f9;hpb=6b3768e8c544739ae53321539cb4d1e3112ded1b;p=ginac.git diff --git a/ginac/function.pl b/ginac/function.pl index 6ebdada4..6dbee8bb 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -31,48 +31,58 @@ sub generate { return $res; } -$declare_function_macro=generate( - <<'END_OF_DECLARE_FUNCTION_MACRO','ex const & p${N}','p${N}'); +$declare_function_macro_namespace=generate( + <<'END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE','const GiNaC::ex & p${N}','p${N}'); #define DECLARE_FUNCTION_${N}P(NAME) \\ -extern unsigned function_index_##NAME; \\ +extern const unsigned function_index_##NAME; \\ +inline GiNaC::function NAME(${SEQ1}) { \\ + return GiNaC::function(function_index_##NAME, ${SEQ2}); \\ +} + +END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE + +$declare_function_macro_no_namespace=generate( + <<'END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE','const ex & p${N}','p${N}'); +#define DECLARE_FUNCTION_${N}P(NAME) \\ +extern const unsigned function_index_##NAME; \\ inline function NAME(${SEQ1}) { \\ return function(function_index_##NAME, ${SEQ2}); \\ } -END_OF_DECLARE_FUNCTION_MACRO +END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE $typedef_eval_funcp=generate( 'typedef ex (* eval_funcp_${N})(${SEQ1});'."\n", -'ex const &',''); +'const ex &',''); $typedef_evalf_funcp=generate( 'typedef ex (* evalf_funcp_${N})(${SEQ1});'."\n", -'ex const &',''); +'const ex &',''); -$typedef_diff_funcp=generate( -'typedef ex (* diff_funcp_${N})(${SEQ1}, unsigned);'."\n", -'ex const &',''); +$typedef_derivative_funcp=generate( +'typedef ex (* derivative_funcp_${N})(${SEQ1}, unsigned);'."\n", +'const ex &',''); $typedef_series_funcp=generate( -'typedef ex (* series_funcp_${N})(${SEQ1}, symbol const &, ex const &, int);'."\n", -'ex const &',''); +'typedef ex (* series_funcp_${N})(${SEQ1}, const symbol &, const ex &, int);'."\n", +'const ex &',''); $constructors_interface=generate( ' function(unsigned ser, ${SEQ1});'."\n", -'ex const & param${N}',''); +'const ex & param${N}',''); $register_new_interface=generate( -' static unsigned register_new(char const * nm, eval_funcp_${N} e,'."\n". -' evalf_funcp_${N} ef=0, diff_funcp_${N} d=0, series_funcp_${N} s=0);'. +' static unsigned register_new(const char * nm, eval_funcp_${N} e,'."\n". +' evalf_funcp_${N} ef=0, derivative_funcp_${N} d=0, series_funcp_${N} s=0);'. "\n",'',''); $constructors_implementation=generate( - <<'END_OF_CONSTRUCTORS_IMPLEMENTATION','ex const & param${N}','param${N}'); + <<'END_OF_CONSTRUCTORS_IMPLEMENTATION','const ex & param${N}','param${N}'); function::function(unsigned ser, ${SEQ1}) : exprseq(${SEQ2}), serial(ser) { debugmsg(\"function constructor from unsigned,${N}*ex\",LOGLEVEL_CONSTRUCT); - tinfo_key = TINFO_FUNCTION; + tinfo_key = TINFO_function; } END_OF_CONSTRUCTORS_IMPLEMENTATION @@ -93,24 +103,29 @@ END_OF_EVALF_SWITCH_STATEMENT $diff_switch_statement=generate( <<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]',''); case ${N}: - return ((diff_funcp_${N})(registered_functions()[serial].d))(${SEQ1},diff_param); + return ((derivative_funcp_${N})(registered_functions()[serial].d))(${SEQ1},diff_param); break; END_OF_DIFF_SWITCH_STATEMENT $series_switch_statement=generate( <<'END_OF_SERIES_SWITCH_STATEMENT','seq[${N}-1]',''); case ${N}: - return ((series_funcp_${N})(registered_functions()[serial].s))(${SEQ1},s,point,order); + try { + res = ((series_funcp_${N})(registered_functions()[serial].s))(${SEQ1},s,point,order); + } catch (do_taylor) { + res = basic::series(s, point, order); + } + return res; break; END_OF_SERIES_SWITCH_STATEMENT $register_new_implementation=generate( <<'END_OF_REGISTER_NEW_IMPLEMENTATION','',''); -unsigned function::register_new(char const * nm, eval_funcp_${N} e, - evalf_funcp_${N} ef, diff_funcp_${N} d, series_funcp_${N} s) +unsigned function::register_new(const char * nm, eval_funcp_${N} e, + evalf_funcp_${N} ef, derivative_funcp_${N} d, series_funcp_${N} s) { registered_function_info rfi={nm,${N},0,eval_funcp(e), - evalf_funcp(ef),diff_funcp(d),series_funcp(s)}; + evalf_funcp(ef),derivative_funcp(d),series_funcp(s)}; registered_functions().push_back(rfi); return registered_functions().size()-1; } @@ -119,29 +134,68 @@ END_OF_REGISTER_NEW_IMPLEMENTATION $interface=< #include -#include "config.h" -class function; +#ifdef __CINT__ +// CINT needs to work properly with +#include +#endif // def __CINT__ #include "exprseq.h" +#ifndef NO_NAMESPACE_GINAC + // the following lines have been generated for max. ${maxargs} parameters -$declare_function_macro +$declare_function_macro_namespace // end of generated lines +#else // ndef NO_NAMESPACE_GINAC + +// the following lines have been generated for max. ${maxargs} parameters +$declare_function_macro_no_namespace +// end of generated lines + +#endif // ndef NO_NAMESPACE_GINAC + +#ifndef NO_NAMESPACE_GINAC + #define REGISTER_FUNCTION(NAME,E,EF,D,S) \\ -unsigned function_index_##NAME=function::register_new(#NAME,E,EF,D,S); +const unsigned function_index_##NAME=GiNaC::function::register_new(#NAME,E,EF,D,S); + +#else // ndef NO_NAMESPACE_GINAC + +#define REGISTER_FUNCTION(NAME,E,EF,D,S) \\ +const unsigned function_index_##NAME=function::register_new(#NAME,E,EF,D,S); + +#endif // ndef NO_NAMESPACE_GINAC #define BEGIN_TYPECHECK \\ bool automatic_typecheck=true; @@ -151,36 +205,53 @@ if (!is_ex_exactly_of_type(VAR,TYPE)) { \\ automatic_typecheck=false; \\ } else +#ifndef NO_NAMESPACE_GINAC + +#define TYPECHECK_INTEGER(VAR) \\ +if (!(VAR).info(GiNaC::info_flags::integer)) { \\ + automatic_typecheck=false; \\ +} else + +#else // ndef NO_NAMESPACE_GINAC + #define TYPECHECK_INTEGER(VAR) \\ if (!(VAR).info(info_flags::integer)) { \\ automatic_typecheck=false; \\ } else +#endif // ndef NO_NAMESPACE_GINAC + #define END_TYPECHECK(RV) \\ {} \\ if (!automatic_typecheck) { \\ return RV.hold(); \\ } +#ifndef NO_NAMESPACE_GINAC +namespace GiNaC { +#endif // ndef NO_NAMESPACE_GINAC + +class function; + typedef ex (* eval_funcp)(); typedef ex (* evalf_funcp)(); -typedef ex (* diff_funcp)(); +typedef ex (* derivative_funcp)(); typedef ex (* series_funcp)(); // the following lines have been generated for max. ${maxargs} parameters $typedef_eval_funcp $typedef_evalf_funcp -$typedef_diff_funcp +$typedef_derivative_funcp $typedef_series_funcp // end of generated lines struct registered_function_info { - char const * name; + const char * name; unsigned nparams; unsigned options; eval_funcp e; evalf_funcp ef; - diff_funcp d; + derivative_funcp d; series_funcp s; }; @@ -188,6 +259,9 @@ struct registered_function_info { and user defined functions */ class function : public exprseq { + GINAC_DECLARE_REGISTERED_CLASS(function, exprseq) + + // CINT has a linking problem friend void ginsh_get_ginac_functions(void); // member functions @@ -196,10 +270,10 @@ class function : public exprseq public: function(); ~function(); - function(function const & other); - function const & operator=(function const & other); + function(const function & other); + const function & operator=(const function & other); protected: - void copy(function const & other); + void copy(const function & other); void destroy(bool call_parent); // other constructors @@ -208,8 +282,8 @@ public: // the following lines have been generated for max. ${maxargs} parameters $constructors_interface // end of generated lines - function(unsigned ser, exprseq const & es); - function(unsigned ser, exvector const & v, bool discardable=0); + function(unsigned ser, const exprseq & es); + function(unsigned ser, const exvector & v, bool discardable=0); function(unsigned ser, exvector * vp); // vp will be deleted // functions overriding virtual functions from bases classes @@ -222,13 +296,13 @@ public: ex expand(unsigned options=0) const; ex eval(int level=0) const; ex evalf(int level=0) const; - ex diff(symbol const & s) const; - ex series(symbol const & s, ex const & point, int order) const; - ex thisexprseq(exvector const & v) const; + ex series(const symbol & s, const ex & point, int order) const; + ex thisexprseq(const exvector & v) const; ex thisexprseq(exvector * vp) const; protected: - int compare_same_type(basic const & other) const; - bool is_equal_same_type(basic const & other) const; + ex derivative(const symbol & s) const; + int compare_same_type(const basic & other) const; + bool is_equal_same_type(const basic & other) const; unsigned return_type(void) const; unsigned return_type_tinfo(void) const; @@ -237,7 +311,7 @@ protected: // non-virtual functions in this class protected: - ex pdiff(unsigned diff_param) const; // partial differentiation + ex pderivative(unsigned diff_param) const; // partial differentiation static vector & registered_functions(void); public: // the following lines have been generated for max. ${maxargs} parameters @@ -253,31 +327,73 @@ protected: // utility macros +#ifndef NO_NAMESPACE_GINAC + +#define is_ex_the_function(OBJ, FUNCNAME) \\ + (is_ex_exactly_of_type(OBJ, function) && static_cast(OBJ.bp)->getserial() == function_index_##FUNCNAME) + +#else // ndef NO_NAMESPACE_GINAC + #define is_ex_the_function(OBJ, FUNCNAME) \\ (is_ex_exactly_of_type(OBJ, function) && static_cast(OBJ.bp)->getserial() == function_index_##FUNCNAME) +#endif // ndef NO_NAMESPACE_GINAC + // global constants extern const function some_function; -extern type_info const & typeid_function; +extern const type_info & typeid_function; + +#ifndef NO_NAMESPACE_GINAC +} // namespace GiNaC +#endif // ndef NO_NAMESPACE_GINAC -#endif // ndef _FUNCTION_H_ +#endif // ndef __GINAC_FUNCTION_H__ END_OF_INTERFACE $implementation=< #include -#include "ginac.h" +#include "function.h" +#include "ex.h" +#include "archive.h" +#include "inifcns.h" +#include "utils.h" +#include "debugmsg.h" + +#ifndef NO_NAMESPACE_GINAC +namespace GiNaC { +#endif // ndef NO_NAMESPACE_GINAC + +GINAC_IMPLEMENT_REGISTERED_CLASS(function, exprseq) ////////// // default constructor, destructor, copy constructor assignment operator and helpers @@ -288,7 +404,7 @@ $implementation=<::const_iterator i = registered_functions().begin(), iend = registered_functions().end(); + while (i != iend) { + if (s == i->name) { + serial = ser; + return; + } + i++; ser++; + } + throw (std::runtime_error("unknown function '" + s + "' in archive")); + } else + throw (std::runtime_error("unnamed function in archive")); +} + +/** Unarchive the object. */ +ex function::unarchive(const archive_node &n, const lst &sym_lst) +{ + return (new function(n, sym_lst))->setflag(status_flags::dynallocated); +} + +/** Archive the object. */ +void function::archive(archive_node &n) const +{ + inherited::archive(n); + GINAC_ASSERT(serial < registered_functions().size()); + n.add_string("name", registered_functions()[serial].name); } ////////// @@ -378,7 +534,7 @@ void function::printraw(ostream & os) const { debugmsg("function printraw",LOGLEVEL_PRINT); - ASSERT(serial(const_cast(other)); + GINAC_ASSERT(is_of_type(other, function)); + const function & o=static_cast(const_cast(other)); if (serial!=o.serial) { return serial < o.serial ? -1 : 1; @@ -519,10 +704,10 @@ int function::compare_same_type(basic const & other) const return exprseq::compare_same_type(o); } -bool function::is_equal_same_type(basic const & other) const +bool function::is_equal_same_type(const basic & other) const { - ASSERT(is_of_type(other, function)); - function const & o=static_cast(const_cast(other)); + GINAC_ASSERT(is_of_type(other, function)); + const function & o=static_cast(const_cast(other)); if (serial!=o.serial) return false; return exprseq::is_equal_same_type(o); @@ -556,19 +741,19 @@ unsigned function::return_type_tinfo(void) const // protected -ex function::pdiff(unsigned diff_param) const // partial differentiation +ex function::pderivative(unsigned diff_param) const // partial differentiation { - ASSERT(serial & function::registered_functions(void) @@ -594,7 +779,11 @@ $register_new_implementation ////////// const function some_function; -type_info const & typeid_function=typeid(some_function); +const type_info & typeid_function=typeid(some_function); + +#ifndef NO_NAMESPACE_GINAC +} // namespace GiNaC +#endif // ndef NO_NAMESPACE_GINAC END_OF_IMPLEMENTATION