From: Christian Bauer Date: Wed, 27 Jun 2001 00:32:01 +0000 (+0000) Subject: - replaced the Derivative() function by a more resonable fderivative class; X-Git-Tag: release_0-9-1~8 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=aa6281216091efd92dc5fcc3f96c7189114e80f1 - replaced the Derivative() function by a more resonable fderivative class; to see it in action, try "series(abs(x),x==0,3)" and "series(abs(x),x==y,3)" in ginsh with previous GiNaC releases and with this one - add::eval() throws an exception when the first term is non-commutative and the overall_coeff is non-zero - small fixes to print_tree output of indexed objects - ncmul::expand() now actually does expand something like "(dirac_gamma(mu)+1) *dirac_gamma(nu)" correctly (but the change to add::eval() should make this a "can't happen" case) - moved ToString() to tostring.h (fewer header dependencies) - ALL YOUR "BASES CLASSES" ARE BELONG TO US --- diff --git a/ginac/Makefile.am b/ginac/Makefile.am index 913457cb..fc759b1e 100644 --- a/ginac/Makefile.am +++ b/ginac/Makefile.am @@ -8,7 +8,7 @@ libginac_la_SOURCES = add.cpp archive.cpp basic.cpp constant.cpp ex.cpp \ symbol.cpp pseries.cpp utils.cpp ncmul.cpp structure.cpp exprseq_suppl.cpp \ lst.cpp lst_suppl.cpp input_parser.yy input_lexer.ll input_lexer.h \ remember.h remember.cpp debugmsg.h utils.h idx.cpp indexed.cpp tensor.cpp \ - color.cpp clifford.cpp wildcard.cpp symmetry.cpp + color.cpp clifford.cpp wildcard.cpp symmetry.cpp fderivative.cpp tostring.h libginac_la_LDFLAGS = -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \ -release $(LT_RELEASE) ginacincludedir = $(includedir)/ginac @@ -17,7 +17,7 @@ ginacinclude_HEADERS = ginac.h add.h archive.h basic.h constant.h ex.h \ lst.h matrix.h mul.h ncmul.h normal.h numeric.h operators.h power.h \ registrar.h relational.h pseries.h structure.h symbol.h tinfos.h assertion.h \ version.h idx.h indexed.h tensor.h color.h clifford.h wildcard.h print.h \ - symmetry.h + symmetry.h fderivative.h LFLAGS = -Pginac_yy -olex.yy.c YFLAGS = -p ginac_yy -d EXTRA_DIST = container.pl function.pl structure.pl input_parser.h version.h.in diff --git a/ginac/add.cpp b/ginac/add.cpp index 7764d368..b681a4f9 100644 --- a/ginac/add.cpp +++ b/ginac/add.cpp @@ -107,7 +107,7 @@ add::add(epvector * vp, const ex & oc) DEFAULT_ARCHIVING(add) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public @@ -339,12 +339,14 @@ ex add::eval(int level) const } int seq_size = seq.size(); - if (seq_size==0) { + if (seq_size == 0) { // +(;c) -> c return overall_coeff; - } else if ((seq_size==1) && overall_coeff.is_zero()) { + } else if (seq_size == 1 && overall_coeff.is_zero()) { // +(x;0) -> x return recombine_pair_to_ex(*(seq.begin())); + } else if (!overall_coeff.is_zero() && seq[0].rest.return_type() != return_types::commutative) { + throw (std::logic_error("add::eval(): sum of non-commutative objects has non-zero numeric term")); } return this->hold(); } diff --git a/ginac/add.h b/ginac/add.h index c0dfca55..fe8d20b7 100644 --- a/ginac/add.h +++ b/ginac/add.h @@ -44,7 +44,7 @@ public: add(const epvector & v, const ex & oc); add(epvector * vp, const ex & oc); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned precedence(void) const {return 40;} diff --git a/ginac/archive.cpp b/ginac/archive.cpp index c547916a..c5c26131 100644 --- a/ginac/archive.cpp +++ b/ginac/archive.cpp @@ -27,7 +27,7 @@ #include "registrar.h" #include "ex.h" #include "config.h" -#include "utils.h" +#include "tostring.h" namespace GiNaC { diff --git a/ginac/basic.cpp b/ginac/basic.cpp index f8839db9..36ea6419 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -101,12 +101,6 @@ void basic::archive(archive_node &n) const n.add_string("class", class_name()); } -////////// -// functions overriding virtual functions from bases classes -////////// - -// none - ////////// // new virtual functions which can be overridden by derived classes ////////// diff --git a/ginac/basic.h b/ginac/basic.h index 56369b82..28568c56 100644 --- a/ginac/basic.h +++ b/ginac/basic.h @@ -96,8 +96,6 @@ protected: { /* debugmsg("basic ctor with tinfo_key", LOGLEVEL_CONSTRUCT); */ } - // functions overriding virtual functions from bases classes - // none // new virtual functions which can be overridden by derived classes public: // only const functions please (may break reference counting) diff --git a/ginac/clifford.cpp b/ginac/clifford.cpp index cde94ebd..8d8c2c63 100644 --- a/ginac/clifford.cpp +++ b/ginac/clifford.cpp @@ -123,7 +123,7 @@ DEFAULT_ARCHIVING(diracgamma) DEFAULT_ARCHIVING(diracgamma5) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// int clifford::compare_same_type(const basic & other) const diff --git a/ginac/clifford.h b/ginac/clifford.h index 7120a4b6..0c8573ae 100644 --- a/ginac/clifford.h +++ b/ginac/clifford.h @@ -71,7 +71,7 @@ class diracone : public tensor { GINAC_DECLARE_REGISTERED_CLASS(diracone, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; }; @@ -82,7 +82,7 @@ class diracgamma : public tensor { GINAC_DECLARE_REGISTERED_CLASS(diracgamma, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const; @@ -95,7 +95,7 @@ class diracgamma5 : public tensor { GINAC_DECLARE_REGISTERED_CLASS(diracgamma5, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; }; diff --git a/ginac/color.cpp b/ginac/color.cpp index 3b544171..561f88b1 100644 --- a/ginac/color.cpp +++ b/ginac/color.cpp @@ -124,7 +124,7 @@ DEFAULT_ARCHIVING(su3f) DEFAULT_ARCHIVING(su3d) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// int color::compare_same_type(const basic & other) const diff --git a/ginac/color.h b/ginac/color.h index ba627350..03b9d8d3 100644 --- a/ginac/color.h +++ b/ginac/color.h @@ -73,7 +73,7 @@ class su3one : public tensor { GINAC_DECLARE_REGISTERED_CLASS(su3one, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; }; @@ -83,7 +83,7 @@ class su3t : public tensor { GINAC_DECLARE_REGISTERED_CLASS(su3t, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const; @@ -95,7 +95,7 @@ class su3f : public tensor { GINAC_DECLARE_REGISTERED_CLASS(su3f, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; @@ -107,7 +107,7 @@ class su3d : public tensor { GINAC_DECLARE_REGISTERED_CLASS(su3d, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; diff --git a/ginac/constant.cpp b/ginac/constant.cpp index 4ca94921..60c3be24 100644 --- a/ginac/constant.cpp +++ b/ginac/constant.cpp @@ -131,7 +131,7 @@ void constant::archive(archive_node &n) const } ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/constant.h b/ginac/constant.h index 160b7ac6..bdd8d69e 100644 --- a/ginac/constant.h +++ b/ginac/constant.h @@ -46,7 +46,7 @@ public: constant(const std::string & initname, evalffunctype efun = 0, const std::string & texname = std::string()); constant(const std::string & initname, const numeric & initnumber, const std::string & texname = std::string()); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; int degree(const ex & s) const; diff --git a/ginac/container.pl b/ginac/container.pl index a0a4a7b1..8374b9b9 100755 --- a/ginac/container.pl +++ b/ginac/container.pl @@ -430,7 +430,7 @@ void ${CONTAINER}::archive(archive_node &n) const } ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/ex.cpp b/ginac/ex.cpp index de48a4f7..b6b96859 100644 --- a/ginac/ex.cpp +++ b/ginac/ex.cpp @@ -43,18 +43,6 @@ namespace GiNaC { // none (all inlined) -////////// -// functions overriding virtual functions from bases classes -////////// - -// none - -////////// -// new virtual functions which can be overridden by derived classes -////////// - -// none - ////////// // non-virtual functions in this class ////////// diff --git a/ginac/ex.h b/ginac/ex.h index fcba4588..88f4e2ef 100644 --- a/ginac/ex.h +++ b/ginac/ex.h @@ -70,12 +70,6 @@ public: * symbols and other parser errors will throw an exception. */ ex(const std::string &s, const ex &l); - // functions overriding virtual functions from bases classes - // none - - // new virtual functions which can be overridden by derived classes - // none - // non-virtual functions in this class public: void swap(ex & other); diff --git a/ginac/expairseq.cpp b/ginac/expairseq.cpp index 87b19e14..d796e4b2 100644 --- a/ginac/expairseq.cpp +++ b/ginac/expairseq.cpp @@ -177,7 +177,7 @@ void expairseq::archive(archive_node &n) const DEFAULT_UNARCHIVE(expairseq) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/expairseq.h b/ginac/expairseq.h index 8d083c16..9fe72d57 100644 --- a/ginac/expairseq.h +++ b/ginac/expairseq.h @@ -83,7 +83,7 @@ public: expairseq(const epvector & v, const ex & oc); expairseq(epvector * vp, const ex & oc); // vp will be deleted - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: basic * duplicate() const; void print(const print_context & c, unsigned level = 0) const; diff --git a/ginac/fail.cpp b/ginac/fail.cpp index 4c3090fb..d3ed59a2 100644 --- a/ginac/fail.cpp +++ b/ginac/fail.cpp @@ -44,7 +44,7 @@ DEFAULT_CTORS(fail) DEFAULT_ARCHIVING(fail) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// DEFAULT_COMPARE(fail) diff --git a/ginac/fail.h b/ginac/fail.h index 24050923..3c514797 100644 --- a/ginac/fail.h +++ b/ginac/fail.h @@ -32,7 +32,7 @@ class fail : public basic { GINAC_DECLARE_REGISTERED_CLASS(fail, basic) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; protected: diff --git a/ginac/fderivative.cpp b/ginac/fderivative.cpp new file mode 100644 index 00000000..319cae20 --- /dev/null +++ b/ginac/fderivative.cpp @@ -0,0 +1,229 @@ +/** @file fderivative.cpp + * + * Implementation of abstract derivatives of functions. */ + +/* + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#include "fderivative.h" +#include "print.h" +#include "archive.h" +#include "debugmsg.h" +#include "utils.h" + +namespace GiNaC { + +GINAC_IMPLEMENT_REGISTERED_CLASS(fderivative, function) + +////////// +// default constructor, destructor, copy constructor assignment operator and helpers +////////// + +fderivative::fderivative() +{ + debugmsg("fderivative default constructor", LOGLEVEL_CONSTRUCT); + tinfo_key = TINFO_fderivative; +} + +void fderivative::copy(const fderivative & other) +{ + inherited::copy(other); + parameter_set = other.parameter_set; +} + +DEFAULT_DESTROY(fderivative) + +////////// +// other constructors +////////// + +fderivative::fderivative(unsigned ser, unsigned param, const exvector & args) : function(ser, args) +{ + debugmsg("fderivative constructor from unsigned,unsigned,exvector", LOGLEVEL_CONSTRUCT); + parameter_set.insert(param); + tinfo_key = TINFO_fderivative; +} + +fderivative::fderivative(unsigned ser, const paramset & params, const exvector & args) : function(ser, args), parameter_set(params) +{ + debugmsg("fderivative constructor from unsigned,paramset,exvector", LOGLEVEL_CONSTRUCT); + tinfo_key = TINFO_fderivative; +} + +fderivative::fderivative(unsigned ser, const paramset & params, exvector * vp) : function(ser, vp), parameter_set(params) +{ + debugmsg("fderivative constructor from unsigned,paramset,exvector *", LOGLEVEL_CONSTRUCT); + tinfo_key = TINFO_fderivative; +} + +////////// +// archiving +////////// + +fderivative::fderivative(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst) +{ + debugmsg("fderivative constructor from archive_node", LOGLEVEL_CONSTRUCT); + unsigned i = 0; + while (true) { + unsigned u; + if (n.find_unsigned("param", u, i)) + parameter_set.insert(u); + else + break; + i++; + } +} + +void fderivative::archive(archive_node &n) const +{ + inherited::archive(n); + paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end(); + while (i != end) { + n.add_unsigned("param", *i); + ++i; + } +} + +DEFAULT_UNARCHIVE(fderivative) + +////////// +// functions overriding virtual functions from base classes +////////// + +void fderivative::print(const print_context & c, unsigned level) const +{ + debugmsg("fderivative print", LOGLEVEL_PRINT); + + 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() + << ", params="; + paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end(); + --end; + while (i != end) + c.s << *i++ << ","; + c.s << *i << endl; + unsigned delta_indent = static_cast(c).delta_indent; + for (unsigned i=0; i 1) { + // first evaluate children, then we will end up here again + return fderivative(serial, parameter_set, evalchildren(level)); + } + + // No parameters specified? Then return the function itself + if (parameter_set.empty()) + return function(serial, seq); + + // If the function in question actually has a derivative, return it + if (registered_functions()[serial].has_derivative() && parameter_set.size() == 1) + return pderivative(*(parameter_set.begin())); + + return this->hold(); +} + +/** Numeric evaluation falls back to evaluation of arguments. + * @see basic::evalf */ +ex fderivative::evalf(int level) const +{ + return basic::evalf(level); +} + +/** The series expansion of derivatives falls back to Taylor expansion. + * @see basic::series */ +ex fderivative::series(const relational & r, int order, unsigned options) const +{ + return basic::series(r, order, options); +} + +ex fderivative::thisexprseq(const exvector & v) const +{ + return fderivative(serial, parameter_set, v); +} + +ex fderivative::thisexprseq(exvector * vp) const +{ + return fderivative(serial, parameter_set, vp); +} + +/** Implementation of ex::diff() for derivatives. It applies the chain rule. + * @see ex::diff */ +ex fderivative::derivative(const symbol & s) const +{ + ex result; + for (unsigned i=0; i!=seq.size(); i++) { + ex arg_diff = seq[i].diff(s); + if (!arg_diff.is_zero()) { + paramset ps = parameter_set; + ps.insert(i); + result += arg_diff * fderivative(serial, ps, seq); + } + } + return result; +} + +int fderivative::compare_same_type(const basic & other) const +{ + GINAC_ASSERT(is_of_type(other, fderivative)); + const fderivative & o = static_cast(other); + + if (parameter_set != o.parameter_set) + return parameter_set < o.parameter_set ? -1 : 1; + else + return inherited::compare_same_type(o); +} + +bool fderivative::is_equal_same_type(const basic & other) const +{ + GINAC_ASSERT(is_of_type(other, fderivative)); + const fderivative & o = static_cast(other); + + if (parameter_set != o.parameter_set) + return false; + else + return inherited::is_equal_same_type(o); +} + +bool fderivative::match_same_type(const basic & other) const +{ + GINAC_ASSERT(is_of_type(other, fderivative)); + const fderivative & o = static_cast(other); + + return parameter_set == o.parameter_set; +} + +} // namespace GiNaC diff --git a/ginac/fderivative.h b/ginac/fderivative.h new file mode 100644 index 00000000..a0b0f512 --- /dev/null +++ b/ginac/fderivative.h @@ -0,0 +1,89 @@ +/** @file fderivative.h + * + * Interface to abstract derivatives of functions. */ + +/* + * 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 + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + */ + +#ifndef __GINAC_FDERIVATIVE_H__ +#define __GINAC_FDERIVATIVE_H__ + +#include + +#include "function.h" + +namespace GiNaC { + + +typedef std::multiset paramset; + +/** This class represents the (abstract) derivative of a symbolic function. + * It is used to represent the derivatives of functions that do not have + * a derivative or series expansion procedure defined. */ +class fderivative : public function +{ + GINAC_DECLARE_REGISTERED_CLASS(fderivative, function) + + // other constructors +public: + /** Construct derivative with respect to one parameter. + * + * @param ser Serial number of function + * @param param Number of parameter with respect to which to take the derivative + * @param args Arguments of derivative function */ + fderivative(unsigned ser, unsigned param, const exvector & args); + + /** Construct derivative with respect to multiple parameters. + * + * @param ser Serial number of function + * @param params Set of numbers of parameters with respect to which to take the derivative + * @param args Arguments of derivative function */ + fderivative(unsigned ser, const paramset & params, const exvector & args); + + // internal constructors + fderivative(unsigned ser, const paramset & params, exvector * vp); // vp will be deleted + + // functions overriding virtual functions from base classes +public: + void print(const print_context & c, unsigned level = 0) const; + ex eval(int level = 0) const; + ex evalf(int level = 0) 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; + bool is_equal_same_type(const basic & other) const; + bool match_same_type(const basic & other) const; + + // member variables +protected: + paramset parameter_set; /**< Set of parameter numbers with respect to which to take the derivative */ +}; + +// utility functions + +/** Specialization of is_exactly_a(obj) for derivatives. */ +template<> inline bool is_exactly_a(const basic & obj) +{ + return obj.tinfo()==TINFO_fderivative; +} + +} // namespace GiNaC + +#endif // ndef __GINAC_DERIVATIVE_H__ diff --git a/ginac/function.pl b/ginac/function.pl index de7433ed..f6923c0a 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -158,7 +158,7 @@ END_OF_SERIES_FUNC_IMPLEMENTATION $interface=< #include "function.h" +#include "fderivative.h" #include "ex.h" #include "lst.h" #include "symmetry.h" #include "print.h" #include "archive.h" #include "inifcns.h" +#include "tostring.h" #include "utils.h" #include "debugmsg.h" #include "remember.h" @@ -640,7 +642,7 @@ void function::archive(archive_node &n) const } ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public @@ -732,7 +734,7 @@ ex function::eval(int level) const // Canonicalize argument order according to the symmetry properties if (seq.size() > 1 && !(opt.symtree.is_zero())) { exvector v = seq; - GINAC_ASSERT(is_ex_exactly_of_type(opt.symtree, symmetry)); + GINAC_ASSERT(is_of_type(opt.symtree)); int sig = canonicalize(v.begin(), ex_to(opt.symtree)); if (sig != INT_MAX) { // Something has changed while sorting arguments, more evaluations later @@ -846,25 +848,10 @@ ${series_switch_statement} ex function::derivative(const symbol & s) const { ex result; - + if (serial == function_index_Order) { // Order Term function only differentiates the argument return Order(seq[0].diff(s)); - } else if (serial == function_index_Derivative) { - // Inert derivative performs chain rule on the first argument only, and - // adds differentiation parameter to list (second argument) - GINAC_ASSERT(is_ex_exactly_of_type(seq[0], function)); - GINAC_ASSERT(is_ex_exactly_of_type(seq[1], function)); - ex fcn = seq[0]; - ex arg_diff; - for (unsigned i=0; i!=fcn.nops(); i++) { - arg_diff = fcn.op(i).diff(s); - if (!arg_diff.is_zero()) { - lst new_lst = ex_to(seq[1]); - new_lst.append(i); - result += arg_diff * Derivative(fcn, new_lst); - } - } } else { // Chain rule ex arg_diff; @@ -945,9 +932,10 @@ ex function::pderivative(unsigned diff_param) const // partial differentiation { GINAC_ASSERT(serial(f); - if (fcn.registered_functions()[fcn.get_serial()].has_derivative() && l.nops() > 0) { - - // The function actually seems to have a derivative, let's calculate it - ex d = fcn.pderivative(ex_to_numeric(l.op(0)).to_int()); - - // If this was the last differentiation, return the result - if (l.nops() == 1) - return d; - - // Otherwise recursively continue as long as the derivative is still - // a function - if (is_ex_of_type(d, function)) { - lst l_copy = ex_to(l); - l_copy.remove_first(); - return Derivative(d, l_copy); - } - } -#endif - return Derivative(f, l).hold(); -} - -REGISTER_FUNCTION(Derivative, eval_func(Derivative_eval). - latex_name("\\mathrm{D}")); - ////////// // Solve linear system ////////// diff --git a/ginac/inifcns.h b/ginac/inifcns.h index 8acc2bf4..0defba9f 100644 --- a/ginac/inifcns.h +++ b/ginac/inifcns.h @@ -132,9 +132,6 @@ DECLARE_FUNCTION_2P(binomial) /** Order term function (for truncated power series). */ DECLARE_FUNCTION_1P(Order) -/** Inert partial differentiation operator. */ -DECLARE_FUNCTION_2P(Derivative) - ex lsolve(const ex &eqns, const ex &symbols); /** Check whether a function is the Order (O(n)) function. */ diff --git a/ginac/inifcns_trans.cpp b/ginac/inifcns_trans.cpp index 229d3f72..150e3428 100644 --- a/ginac/inifcns_trans.cpp +++ b/ginac/inifcns_trans.cpp @@ -263,7 +263,7 @@ static ex sin_eval(const ex & x) return sign*_ex1(); } - if (is_ex_exactly_of_type(x, function)) { + if (is_exactly_a(x)) { ex t = x.op(0); // sin(asin(x)) -> x if (is_ex_the_function(x, asin)) @@ -345,7 +345,7 @@ static ex cos_eval(const ex & x) return sign*_ex0(); } - if (is_ex_exactly_of_type(x, function)) { + if (is_exactly_a(x)) { ex t = x.op(0); // cos(acos(x)) -> x if (is_ex_the_function(x, acos)) @@ -423,7 +423,7 @@ static ex tan_eval(const ex & x) throw (pole_error("tan_eval(): simple pole",1)); } - if (is_ex_exactly_of_type(x, function)) { + if (is_exactly_a(x)) { ex t = x.op(0); // tan(atan(x)) -> x if (is_ex_the_function(x, atan)) @@ -736,7 +736,7 @@ static ex sinh_eval(const ex & x) ex_to(x/Pi).real().is_zero()) // sinh(I*x) -> I*sin(x) return I*sin(x/I); - if (is_ex_exactly_of_type(x, function)) { + if (is_exactly_a(x)) { ex t = x.op(0); // sinh(asinh(x)) -> x if (is_ex_the_function(x, asinh)) @@ -791,7 +791,7 @@ static ex cosh_eval(const ex & x) ex_to(x/Pi).real().is_zero()) // cosh(I*x) -> cos(x) return cos(x/I); - if (is_ex_exactly_of_type(x, function)) { + if (is_exactly_a(x)) { ex t = x.op(0); // cosh(acosh(x)) -> x if (is_ex_the_function(x, acosh)) @@ -846,7 +846,7 @@ static ex tanh_eval(const ex & x) ex_to(x/Pi).real().is_zero()) // tanh(I*x) -> I*tan(x); return I*tan(x/I); - if (is_ex_exactly_of_type(x, function)) { + if (is_exactly_a(x)) { ex t = x.op(0); // tanh(atanh(x)) -> x if (is_ex_the_function(x, atanh)) diff --git a/ginac/matrix.cpp b/ginac/matrix.cpp index 1f5e9af5..15ebd9aa 100644 --- a/ginac/matrix.cpp +++ b/ginac/matrix.cpp @@ -141,7 +141,7 @@ void matrix::archive(archive_node &n) const DEFAULT_UNARCHIVE(matrix) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/matrix.h b/ginac/matrix.h index 927c27c1..59213742 100644 --- a/ginac/matrix.h +++ b/ginac/matrix.h @@ -40,7 +40,7 @@ public: matrix(unsigned r, unsigned c, const exvector & m2); matrix(unsigned r, unsigned c, const lst & l); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned nops() const; diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 9bb753a1..3cfb7ff6 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -122,7 +122,7 @@ mul::mul(const ex & lh, const ex & mh, const ex & rh) DEFAULT_ARCHIVING(mul) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/mul.h b/ginac/mul.h index d24d37ed..23e0e1f3 100644 --- a/ginac/mul.h +++ b/ginac/mul.h @@ -45,7 +45,7 @@ public: mul(epvector * vp, const ex & oc); mul(const ex & lh, const ex & mh, const ex & rh); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned precedence(void) const {return 50;} diff --git a/ginac/ncmul.cpp b/ginac/ncmul.cpp index f7d1a417..bfc2acdd 100644 --- a/ginac/ncmul.cpp +++ b/ginac/ncmul.cpp @@ -109,7 +109,7 @@ ncmul::ncmul(exvector * vp) : inherited(vp) DEFAULT_ARCHIVING(ncmul) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public @@ -140,7 +140,7 @@ void ncmul::print(const print_context & c, unsigned level) const bool ncmul::info(unsigned inf) const { - throw(std::logic_error("which flags have to be implemented in ncmul::info()?")); + return inherited::info(inf); } typedef std::vector intvector; @@ -151,12 +151,7 @@ ex ncmul::expand(unsigned options) const exvector expanded_seq = expandchildren(options); // Now, look for all the factors that are sums and remember their - // position and number of terms. One remark is in order here: we do not - // take into account the overall_coeff of the add objects. This is - // because in GiNaC, all terms of a sum must be of the same type, so - // a non-zero overall_coeff (which can only be numeric) would imply that - // the sum only has commutative terms. But then it would never appear - // as a factor of an ncmul. + // position and number of terms. intvector positions_of_adds(expanded_seq.size()); intvector number_of_add_operands(expanded_seq.size()); @@ -166,12 +161,12 @@ ex ncmul::expand(unsigned options) const unsigned current_position = 0; exvector::const_iterator last = expanded_seq.end(); for (exvector::const_iterator cit=expanded_seq.begin(); cit!=last; ++cit) { - if (is_ex_exactly_of_type(*cit, add)) { + if (is_exactly_a(*cit)) { positions_of_adds[number_of_adds] = current_position; - const add & expanded_addref = ex_to(*cit); - number_of_add_operands[number_of_adds] = expanded_addref.seq.size(); - number_of_expanded_terms *= expanded_addref.seq.size(); - ++number_of_adds; + unsigned num_ops = cit->nops(); + number_of_add_operands[number_of_adds] = num_ops; + number_of_expanded_terms *= num_ops; + number_of_adds++; } ++current_position; } @@ -190,11 +185,8 @@ ex ncmul::expand(unsigned options) const while (true) { exvector term = expanded_seq; - for (int i=0; i(expanded_seq[positions_of_adds[i]]); - term[positions_of_adds[i]] = addref.recombine_pair_to_ex(addref.seq[k[i]]); - } + for (int i=0; i setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0))); diff --git a/ginac/ncmul.h b/ginac/ncmul.h index b0fbbee9..67d381bc 100644 --- a/ginac/ncmul.h +++ b/ginac/ncmul.h @@ -51,7 +51,7 @@ public: ncmul(const exvector & v, bool discardable=false); ncmul(exvector * vp); // vp will be deleted - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned precedence(void) const {return 50;} diff --git a/ginac/numeric.cpp b/ginac/numeric.cpp index ffcdfbfa..880e0a7e 100644 --- a/ginac/numeric.cpp +++ b/ginac/numeric.cpp @@ -336,7 +336,7 @@ void numeric::archive(archive_node &n) const DEFAULT_UNARCHIVE(numeric) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// /** Helper function to print a real number in a nicer way than is CLN's diff --git a/ginac/numeric.h b/ginac/numeric.h index 251e5736..09f15233 100644 --- a/ginac/numeric.h +++ b/ginac/numeric.h @@ -80,7 +80,7 @@ public: numeric(double d); numeric(const char *); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned precedence(void) const {return 30;} diff --git a/ginac/power.cpp b/ginac/power.cpp index 5daa8419..2d4360de 100644 --- a/ginac/power.cpp +++ b/ginac/power.cpp @@ -90,7 +90,7 @@ void power::archive(archive_node &n) const DEFAULT_UNARCHIVE(power) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/power.h b/ginac/power.h index 952a72a6..175fea05 100644 --- a/ginac/power.h +++ b/ginac/power.h @@ -46,7 +46,7 @@ public: power(const ex & lh, const ex & rh) : inherited(TINFO_power), basis(lh), exponent(rh) {} template power(const ex & lh, const T & rh) : inherited(TINFO_power), basis(lh), exponent(rh) {} - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned precedence(void) const {return 60;} diff --git a/ginac/pseries.cpp b/ginac/pseries.cpp index 0602ddd7..4816d1fc 100644 --- a/ginac/pseries.cpp +++ b/ginac/pseries.cpp @@ -119,7 +119,7 @@ void pseries::archive(archive_node &n) const DEFAULT_UNARCHIVE(pseries) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// void pseries::print(const print_context & c, unsigned level) const diff --git a/ginac/relational.cpp b/ginac/relational.cpp index 74ce1acb..c4e34ddf 100644 --- a/ginac/relational.cpp +++ b/ginac/relational.cpp @@ -92,7 +92,7 @@ void relational::archive(archive_node &n) const DEFAULT_UNARCHIVE(relational) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/relational.h b/ginac/relational.h index fc559b5f..40c799bf 100644 --- a/ginac/relational.h +++ b/ginac/relational.h @@ -49,7 +49,7 @@ public: public: relational(const ex & lhs, const ex & rhs, operators oper=equal); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; unsigned precedence(void) const {return 20;} diff --git a/ginac/structure.cpp b/ginac/structure.cpp index 54dc1dfc..e1ea6d56 100644 --- a/ginac/structure.cpp +++ b/ginac/structure.cpp @@ -45,7 +45,7 @@ DEFAULT_CTORS(structure) DEFAULT_ARCHIVING(structure) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// void structure::print(const print_context & c, unsigned level) const diff --git a/ginac/structure.h b/ginac/structure.h index 62848b22..1f7eaea0 100644 --- a/ginac/structure.h +++ b/ginac/structure.h @@ -41,7 +41,7 @@ class structure : public basic { GINAC_DECLARE_REGISTERED_CLASS(structure, basic) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level=0) const; protected: diff --git a/ginac/structure.pl b/ginac/structure.pl index 8303dbe4..f6b8a489 100755 --- a/ginac/structure.pl +++ b/ginac/structure.pl @@ -170,7 +170,7 @@ protected: public: ${STRUCTURE}(${constructor_arglist}); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: basic * duplicate() const; void print(const print_context & c, unsigned level = 0) const; @@ -313,7 +313,7 @@ ${STRUCTURE}::${STRUCTURE}(${constructor_arglist}) } ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/symbol.cpp b/ginac/symbol.cpp index ba0cccd1..f5fd4a09 100644 --- a/ginac/symbol.cpp +++ b/ginac/symbol.cpp @@ -28,6 +28,7 @@ #include "print.h" #include "archive.h" #include "debugmsg.h" +#include "tostring.h" #include "utils.h" namespace GiNaC { @@ -137,7 +138,7 @@ void symbol::archive(archive_node &n) const } ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public @@ -242,16 +243,6 @@ bool symbol::is_equal_same_type(const basic & other) const return serial==o->serial; } -unsigned symbol::return_type(void) const -{ - return return_types::commutative; -} - -unsigned symbol::return_type_tinfo(void) const -{ - return tinfo_key; -} - unsigned symbol::calchash(void) const { // this is where the schoolbook method diff --git a/ginac/symbol.h b/ginac/symbol.h index 16c31933..2d9ec3ba 100644 --- a/ginac/symbol.h +++ b/ginac/symbol.h @@ -87,8 +87,6 @@ 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; unsigned calchash(void) const; // non-virtual functions in this class diff --git a/ginac/symmetry.cpp b/ginac/symmetry.cpp index dc2546ff..1b818191 100644 --- a/ginac/symmetry.cpp +++ b/ginac/symmetry.cpp @@ -135,7 +135,7 @@ void symmetry::archive(archive_node &n) const DEFAULT_UNARCHIVE(symmetry) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// int symmetry::compare_same_type(const basic & other) const @@ -154,6 +154,8 @@ void symmetry::print(const print_context & c, unsigned level = 0) const if (children.empty()) { if (indices.size() > 0) c.s << *(indices.begin()); + else + c.s << "none"; } else { switch (type) { case none: c.s << '!'; break; diff --git a/ginac/tensor.cpp b/ginac/tensor.cpp index 1c8847a4..65c8b595 100644 --- a/ginac/tensor.cpp +++ b/ginac/tensor.cpp @@ -142,7 +142,7 @@ void tensepsilon::archive(archive_node &n) const } ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// DEFAULT_COMPARE(tensor) diff --git a/ginac/tensor.h b/ginac/tensor.h index 147ab44d..d868355b 100644 --- a/ginac/tensor.h +++ b/ginac/tensor.h @@ -39,7 +39,7 @@ class tensor : public basic protected: tensor(unsigned ti); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes protected: unsigned return_type(void) const { return return_types::noncommutative_composite; } }; @@ -51,7 +51,7 @@ class tensdelta : public tensor { GINAC_DECLARE_REGISTERED_CLASS(tensdelta, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; @@ -66,7 +66,7 @@ class tensmetric : public tensor { GINAC_DECLARE_REGISTERED_CLASS(tensmetric, tensor) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; @@ -86,7 +86,7 @@ public: /** Construct Lorentz metric tensor with given signature. */ minkmetric(bool pos_sig); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; @@ -105,7 +105,7 @@ class spinmetric : public tensmetric { GINAC_DECLARE_REGISTERED_CLASS(spinmetric, tensmetric) - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; @@ -124,7 +124,7 @@ class tensepsilon : public tensor public: tensepsilon(bool minkowski, bool pos_sig); - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes public: void print(const print_context & c, unsigned level = 0) const; ex eval_indexed(const basic & i) const; diff --git a/ginac/tinfos.h b/ginac/tinfos.h index 775cfc77..20e6d2b3 100644 --- a/ginac/tinfos.h +++ b/ginac/tinfos.h @@ -36,6 +36,7 @@ const unsigned TINFO_constant = 0x00021001U; const unsigned TINFO_exprseq = 0x00030001U; const unsigned TINFO_function = 0x00031001U; +const unsigned TINFO_fderivative = 0x00032001U; const unsigned TINFO_ncmul = 0x00031002U; const unsigned TINFO_lst = 0x00040001U; diff --git a/ginac/utils.cpp b/ginac/utils.cpp index 7acb3a98..75b0e84f 100644 --- a/ginac/utils.cpp +++ b/ginac/utils.cpp @@ -760,7 +760,7 @@ const ex & _ex120(void) // other ctors // none - // functions overriding virtual functions from bases classes + // functions overriding virtual functions from base classes // none // new virtual functions which can be overridden by derived classes @@ -792,7 +792,7 @@ const ex & _ex120(void) // none ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// // public diff --git a/ginac/utils.h b/ginac/utils.h index 3e8e17ca..001f64f4 100644 --- a/ginac/utils.h +++ b/ginac/utils.h @@ -28,32 +28,10 @@ #include #include -#if defined(HAVE_SSTREAM) -#include -#elif defined(HAVE_STRSTREAM) -#include -#else -#error Need either sstream or strstream -#endif #include "assertion.h" namespace GiNaC { -// This should be obsoleted once is widely deployed. -template -std::string ToString(const T & t) -{ -#if defined(HAVE_SSTREAM) - std::ostringstream buf; - buf << t << std::ends; - return buf.str(); -#else - char buf[256]; - std::ostrstream(buf,sizeof(buf)) << t << std::ends; - return buf; -#endif -} - /** Exception class thrown by classes which provide their own series expansion * to signal that ordinary Taylor expansion is safe. */ class do_taylor {}; diff --git a/ginac/wildcard.cpp b/ginac/wildcard.cpp index 33ccb461..31d934a3 100644 --- a/ginac/wildcard.cpp +++ b/ginac/wildcard.cpp @@ -77,7 +77,7 @@ void wildcard::archive(archive_node &n) const DEFAULT_UNARCHIVE(wildcard) ////////// -// functions overriding virtual functions from bases classes +// functions overriding virtual functions from base classes ////////// int wildcard::compare_same_type(const basic & other) const