return generate_from_to($template,$seq_template1,$seq_template2,1,$maxargs);
}
-$declare_function_macro_namespace = <<'END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NAMESPACE';
+$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, p2); \
}
-END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NAMESPACE
+END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO
-$declare_function_macro_namespace .= generate_from_to(
- <<'END_OF_DECLARE_FUNCTION_MACRO_NAMESPACE','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}',3,$maxargs);
#define DECLARE_FUNCTION_${N}P(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 = <<'END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NO_NAMESPACE';
-#define DECLARE_FUNCTION_1P(NAME) \
-extern const unsigned function_index_##NAME; \
-inline function NAME(const ex & p1) { \
- return function(function_index_##NAME, p1); \
-}
-#define DECLARE_FUNCTION_2P(NAME) \
-extern const unsigned function_index_##NAME; \
-inline function NAME(const ex & p1, const ex & p2) { \
- return function(function_index_##NAME, p1, p2); \
-}
-
-END_OF_DECLARE_FUNCTION_1_AND_2P_MACRO_NO_NAMESPACE
-
-$declare_function_macro_no_namespace .= generate_from_to(
- <<'END_OF_DECLARE_FUNCTION_MACRO_NO_NAMESPACE','const ex & p${N}','p${N}',3,$maxargs);
-#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_NO_NAMESPACE
+END_OF_DECLARE_FUNCTION_MACRO
$typedef_eval_funcp=generate(
'typedef ex (* eval_funcp_${N})(${SEQ1});'."\n",
function::function(unsigned ser, ${SEQ1})
: exprseq(${SEQ2}), serial(ser)
{
- debugmsg(\"function constructor from unsigned,${N}*ex\",LOGLEVEL_CONSTRUCT);
+ debugmsg(\"function ctor from unsigned,${N}*ex\",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_function;
}
END_OF_CONSTRUCTORS_IMPLEMENTATION
<<'END_OF_EVALF_SWITCH_STATEMENT','eseq[${N}-1]','');
case ${N}:
return ((evalf_funcp_${N})(registered_functions()[serial].evalf_f))(${SEQ1});
- break;
END_OF_EVALF_SWITCH_STATEMENT
$diff_switch_statement=generate(
<<'END_OF_DIFF_SWITCH_STATEMENT','seq[${N}-1]','');
case ${N}:
return ((derivative_funcp_${N})(registered_functions()[serial].derivative_f))(${SEQ1},diff_param);
- break;
END_OF_DIFF_SWITCH_STATEMENT
$series_switch_statement=generate(
res = basic::series(r, order, options);
}
return res;
- break;
END_OF_SERIES_SWITCH_STATEMENT
$eval_func_implementation=generate(
* Please do not modify it directly, edit the perl script instead!
* function.pl options: \$maxargs=${maxargs}
*
- * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2001 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
#include "exprseq.h"
-#ifndef NO_NAMESPACE_GINAC
-
-// the following lines have been generated for max. ${maxargs} parameters
-$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
+$declare_function_macro
// end of generated lines
-#endif // ndef NO_NAMESPACE_GINAC
-
-#ifndef NO_NAMESPACE_GINAC
-
#define REGISTER_FUNCTION(NAME,OPT) \\
const unsigned function_index_##NAME= \\
GiNaC::function::register_new(GiNaC::function_options(#NAME).OPT);
derivative_func(D). \\
series_func(S));
-#else // ndef NO_NAMESPACE_GINAC
-
-#define REGISTER_FUNCTION(NAME,OPT) \\
-const unsigned function_index_##NAME= \\
- function::register_new(function_options(#NAME).OPT);
-
-#define REGISTER_FUNCTION_OLD(NAME,E,EF,D,S) \\
-const unsigned function_index_##NAME= \\
- function::register_new(function_options(#NAME). \\
- eval_func(E). \\
- evalf_func(EF). \\
- derivative_func(D). \\
- series_func(S));
-
-#endif // ndef NO_NAMESPACE_GINAC
-
#define BEGIN_TYPECHECK \\
bool automatic_typecheck=true;
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;
~function_options();
void initialize(void);
function_options & set_name(std::string const & n, std::string const & tn=std::string());
+ function_options & latex_name(std::string const & tn);
// the following lines have been generated for max. ${maxargs} parameters
$eval_func_interface
$evalf_func_interface
// member functions
- // default constructor, destructor, copy constructor assignment operator and helpers
-public:
- function();
- ~function();
- function(const function & other);
- const function & operator=(const function & other);
-protected:
- void copy(const function & other);
- void destroy(bool call_parent);
-
- // other constructors
+ // other ctors
public:
function(unsigned ser);
// the following lines have been generated for max. ${maxargs} parameters
// functions overriding virtual functions from bases classes
public:
- basic * duplicate() const;
- void printraw(std::ostream & os) const;
- void print(std::ostream & os, unsigned upper_precedence=0) const;
- void printtree(std::ostream & os, unsigned indent) const;
- void printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence=0) const;
+ void print(const print_context & c, unsigned level = 0) const;
+ unsigned precedence(void) const {return 70;}
+ int degree(const ex & s) const;
+ int ldegree(const ex & s) const;
+ ex coeff(const ex & s, int n = 1) const;
ex expand(unsigned options=0) const;
ex eval(int level=0) const;
ex evalf(int level=0) const;
+ unsigned calchash(void) const;
ex series(const relational & r, int order, unsigned options = 0) const;
ex thisexprseq(const exvector & v) const;
ex thisexprseq(exvector * vp) const;
protected:
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;
public:
static unsigned register_new(function_options const & opt);
static unsigned find_function(const std::string &name, unsigned nparams);
- unsigned getserial(void) const {return serial;}
+ unsigned get_serial(void) const {return serial;}
+ std::string get_name(void) const;
// member variables
return static_cast<const function &>(*e.bp);
}
-#ifndef NO_NAMESPACE_GINAC
-
-#define is_ex_the_function(OBJ, FUNCNAME) \\
- (is_ex_exactly_of_type(OBJ, function) && static_cast<GiNaC::function *>(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<function *>(OBJ.bp)->getserial() == function_index_##FUNCNAME)
-
-#endif // ndef NO_NAMESPACE_GINAC
-
-// global constants
+ (is_ex_exactly_of_type(OBJ, function) && static_cast<GiNaC::function *>(OBJ.bp)->get_serial() == function_index_##FUNCNAME)
-extern const function some_function;
-extern const type_info & typeid_function;
-
-#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
#endif // ndef __GINAC_FUNCTION_H__
* Please do not modify it directly, edit the perl script instead!
* function.pl options: \$maxargs=${maxargs}
*
- * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2001 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
#include "function.h"
#include "ex.h"
#include "lst.h"
+#include "print.h"
#include "archive.h"
#include "inifcns.h"
#include "utils.h"
#include "debugmsg.h"
#include "remember.h"
-#ifndef NO_NAMESPACE_GINAC
namespace GiNaC {
-#endif // ndef NO_NAMESPACE_GINAC
//////////
// helper class function_options
void function_options::initialize(void)
{
- set_name("unnamed_function","\\\\operatorname{unnamed}");
+ set_name("unnamed_function","\\\\mbox{unnamed}");
nparams=0;
eval_f=evalf_f=derivative_f=series_f=0;
evalf_params_first=true;
{
name=n;
if (tn==std::string()) {
- TeX_name="\\\\operatorname{"+name+"}";
+ TeX_name="\\\\mbox{"+name+"}";
} else {
TeX_name=tn;
}
return *this;
}
+function_options & function_options::latex_name(std::string const & tn)
+{
+ TeX_name=tn;
+ return *this;
+}
+
// the following lines have been generated for max. ${maxargs} parameters
$eval_func_implementation
$evalf_func_implementation
GINAC_IMPLEMENT_REGISTERED_CLASS(function, exprseq)
//////////
-// default constructor, destructor, copy constructor assignment operator and helpers
+// default ctor, dtor, copy ctor assignment operator and helpers
//////////
// public
function::function() : serial(0)
{
- debugmsg("function default constructor",LOGLEVEL_CONSTRUCT);
+ debugmsg("function default ctor",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_function;
}
-function::~function()
-{
- debugmsg("function destructor",LOGLEVEL_DESTRUCT);
- destroy(false);
-}
-
-function::function(const function & other)
-{
- debugmsg("function copy constructor",LOGLEVEL_CONSTRUCT);
- copy(other);
-}
-
-const function & function::operator=(const function & other)
-{
- debugmsg("function operator=",LOGLEVEL_ASSIGNMENT);
- if (this != &other) {
- destroy(true);
- copy(other);
- }
- return *this;
-}
-
// protected
void function::copy(const function & other)
}
//////////
-// other constructors
+// other ctors
//////////
// public
function::function(unsigned ser) : serial(ser)
{
- debugmsg("function constructor from unsigned",LOGLEVEL_CONSTRUCT);
+ debugmsg("function ctor from unsigned",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_function;
}
function::function(unsigned ser, const exprseq & es) : exprseq(es), serial(ser)
{
- debugmsg("function constructor from unsigned,exprseq",LOGLEVEL_CONSTRUCT);
+ debugmsg("function ctor from unsigned,exprseq",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_function;
}
function::function(unsigned ser, const exvector & v, bool discardable)
: exprseq(v,discardable), serial(ser)
{
- debugmsg("function constructor from string,exvector,bool",LOGLEVEL_CONSTRUCT);
+ debugmsg("function ctor from string,exvector,bool",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_function;
}
function::function(unsigned ser, exvector * vp)
: exprseq(vp), serial(ser)
{
- debugmsg("function constructor from unsigned,exvector *",LOGLEVEL_CONSTRUCT);
+ debugmsg("function ctor from unsigned,exvector *",LOGLEVEL_CONSTRUCT);
tinfo_key = TINFO_function;
}
/** Construct object from archive_node. */
function::function(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
{
- debugmsg("function constructor from archive_node", LOGLEVEL_CONSTRUCT);
+ debugmsg("function ctor from archive_node", LOGLEVEL_CONSTRUCT);
// Find serial number by function name
std::string s;
// public
-basic * function::duplicate() const
+void function::print(const print_context & c, unsigned level) const
{
- debugmsg("function duplicate",LOGLEVEL_DUPLICATE);
- return new function(*this);
-}
-
-void function::printraw(std::ostream & os) const
-{
- debugmsg("function printraw",LOGLEVEL_PRINT);
+ debugmsg("function print", LOGLEVEL_PRINT);
GINAC_ASSERT(serial<registered_functions().size());
- os << "function(name=" << registered_functions()[serial].name;
- for (exvector::const_iterator it=seq.begin(); it!=seq.end(); ++it) {
- os << ",";
- (*it).bp->print(os);
+ if (is_of_type(c, print_tree)) {
+
+ c.s << std::string(level, ' ') << class_name() << " "
+ << registered_functions()[serial].name
+ << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
+ << ", nops=" << nops()
+ << std::endl;
+ unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
+ for (unsigned i=0; i<nops(); ++i)
+ seq[i].print(c, level + delta_indent);
+ c.s << std::string(level + delta_indent, ' ') << "=====" << std::endl;
+
+ } else if (is_of_type(c, print_csrc)) {
+
+ // Print function name in lowercase
+ std::string lname = registered_functions()[serial].name;
+ for (unsigned i=0; i<lname.size(); i++)
+ lname[i] = tolower(lname[i]);
+ c.s << lname << "(";
+
+ // Print arguments, separated by commas
+ exvector::const_iterator it = seq.begin(), itend = seq.end();
+ while (it != itend) {
+ it->print(c);
+ it++;
+ if (it != itend)
+ c.s << ",";
+ }
+ c.s << ")";
+
+ } else if is_of_type(c, print_latex) {
+ c.s << registered_functions()[serial].TeX_name;
+ printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
+ } else {
+ c.s << registered_functions()[serial].name;
+ printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
}
- os << ")";
}
-void function::print(std::ostream & os, unsigned upper_precedence) const
+ex function::expand(unsigned options) const
{
- debugmsg("function print",LOGLEVEL_PRINT);
-
- GINAC_ASSERT(serial<registered_functions().size());
-
- os << registered_functions()[serial].name;
- printseq(os,'(',',',')',exprseq::precedence,function::precedence);
+ return this->setflag(status_flags::expanded);
}
-void function::printtree(std::ostream & os, unsigned indent) const
+int function::degree(const ex & s) const
{
- debugmsg("function printtree",LOGLEVEL_PRINT);
-
- GINAC_ASSERT(serial<registered_functions().size());
-
- os << std::string(indent,' ') << "function "
- << registered_functions()[serial].name
- << ", hash=" << hashvalue
- << " (0x" << std::hex << hashvalue << std::dec << ")"
- << ", flags=" << flags
- << ", nops=" << nops() << std::endl;
- for (unsigned i=0; i<nops(); ++i) {
- seq[i].printtree(os,indent+delta_indent);
- }
- os << std::string(indent+delta_indent,' ') << "=====" << std::endl;
+ return is_equal(*s.bp) ? 1 : 0;
}
-void function::printcsrc(std::ostream & os, unsigned type, unsigned upper_precedence) const
+int function::ldegree(const ex & s) const
{
- debugmsg("function print csrc",LOGLEVEL_PRINT);
-
- GINAC_ASSERT(serial<registered_functions().size());
-
- // Print function name in lowercase
- std::string lname;
- lname=registered_functions()[serial].name;
- for (unsigned i=0; i<lname.size(); i++)
- lname[i] = tolower(lname[i]);
- os << lname << "(";
-
- // Print arguments, separated by commas
- exvector::const_iterator it = seq.begin();
- exvector::const_iterator itend = seq.end();
- while (it != itend) {
- it->bp->printcsrc(os, type, 0);
- it++;
- if (it != itend)
- os << ",";
- }
- os << ")";
+ return is_equal(*s.bp) ? 1 : 0;
}
-ex function::expand(unsigned options) const
+ex function::coeff(const ex & s, int n) const
{
- return this->setflag(status_flags::expanded);
+ if (is_equal(*s.bp))
+ return n==1 ? _ex1() : _ex0();
+ else
+ return n==0 ? ex(*this) : _ex0();
}
ex function::eval(int level) const
throw(std::logic_error("function::evalf(): invalid nparams"));
}
+unsigned function::calchash(void) const
+{
+ unsigned v = golden_ratio_hash(golden_ratio_hash(tinfo()) ^ serial);
+ for (unsigned i=0; i<nops(); i++) {
+ v = rotate_left_31(v);
+ v ^= this->op(i).gethash();
+ }
+ v &= 0x7FFFFFFFU;
+ if (flags & status_flags::evaluated) {
+ setflag(status_flags::hash_calculated);
+ hashvalue = v;
+ }
+ return v;
+}
+
ex function::thisexprseq(const exvector & v) const
{
return function(serial,v);
/** Implementation of ex::series for functions.
* \@see ex::series */
-ex function::series(const relational & r, int order, unsigned options = 0) const
+ex function::series(const relational & r, int order, unsigned options) const
{
GINAC_ASSERT(serial<registered_functions().size());
GINAC_ASSERT(serial<registered_functions().size());
if (registered_functions()[serial].derivative_f==0) {
- return Derivative(*this, lst(diff_param));
+ return Derivative(*this, lst(ex(diff_param)));
}
switch (registered_functions()[serial].nparams) {
// the following lines have been generated for max. ${maxargs} parameters
throw (std::runtime_error("no function '" + name + "' with " + ToString(nparams) + " parameters defined"));
}
-//////////
-// static member variables
-//////////
-
-// none
-
-//////////
-// global constants
-//////////
-
-const function some_function;
-const type_info & typeid_function=typeid(some_function);
+/** Return the print name of the function. */
+std::string function::get_name(void) const
+{
+ GINAC_ASSERT(serial<registered_functions().size());
+ return registered_functions()[serial].name;
+}
-#ifndef NO_NAMESPACE_GINAC
} // namespace GiNaC
-#endif // ndef NO_NAMESPACE_GINAC
END_OF_IMPLEMENTATION