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
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
DEFAULT_ARCHIVING(add)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
}
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();
}
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;}
#include "registrar.h"
#include "ex.h"
#include "config.h"
-#include "utils.h"
+#include "tostring.h"
namespace GiNaC {
n.add_string("class", class_name());
}
-//////////
-// functions overriding virtual functions from bases classes
-//////////
-
-// none
-
//////////
// new virtual functions which can be overridden by derived classes
//////////
{
/* 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)
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
{
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;
};
{
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;
{
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;
};
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
{
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;
};
{
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;
{
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;
{
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;
}
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// 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;
}
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
// 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
//////////
* 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);
DEFAULT_UNARCHIVE(expairseq)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// 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;
DEFAULT_ARCHIVING(fail)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
DEFAULT_COMPARE(fail)
{
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:
--- /dev/null
+/** @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<const print_tree &>(c).delta_indent;
+ for (unsigned i=0; i<seq.size(); ++i)
+ seq[i].print(c, level + delta_indent);
+ c.s << std::string(level + delta_indent, ' ') << "=====" << std::endl;
+
+ } else {
+
+ c.s << "D[";
+ paramset::const_iterator i = parameter_set.begin(), end = parameter_set.end();
+ --end;
+ while (i != end)
+ c.s << *i++ << ",";
+ c.s << *i << "](" << registered_functions()[serial].name << ")";
+ printseq(c, '(', ',', ')', exprseq::precedence(), function::precedence());
+ }
+}
+
+ex fderivative::eval(int level) const
+{
+ if (level > 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<const fderivative &>(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<const fderivative &>(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<const fderivative &>(other);
+
+ return parameter_set == o.parameter_set;
+}
+
+} // namespace GiNaC
--- /dev/null
+/** @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 <set>
+
+#include "function.h"
+
+namespace GiNaC {
+
+
+typedef std::multiset<unsigned> 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<T>(obj) for derivatives. */
+template<> inline bool is_exactly_a<fderivative>(const basic & obj)
+{
+ return obj.tinfo()==TINFO_fderivative;
+}
+
+} // namespace GiNaC
+
+#endif // ndef __GINAC_DERIVATIVE_H__
$interface=<<END_OF_INTERFACE;
/** \@file function.h
*
- * Interface to abstract class function (new function concept). */
+ * Interface to class of symbolic functions. */
/*
* This file was generated automatically by function.pl.
class function_options
{
friend class function;
+ friend class fderivative;
public:
function_options();
function_options(std::string const & n, std::string const & tn=std::string());
friend class remember_table_entry;
// friend class remember_table_list;
// friend class remember_table;
- friend ex Derivative_eval(const ex &, const ex &);
// member functions
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
+ // functions overriding virtual functions from base classes
public:
void print(const print_context & c, unsigned level = 0) const;
unsigned precedence(void) const {return 70;}
$implementation=<<END_OF_IMPLEMENTATION;
/** \@file function.cpp
*
- * Implementation of class function. */
+ * Implementation of class of symbolic functions. */
/*
* This file was generated automatically by function.pl.
#include <list>
#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"
}
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
// 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<symmetry>(opt.symtree));
int sig = canonicalize(v.begin(), ex_to<symmetry>(opt.symtree));
if (sig != INT_MAX) {
// Something has changed while sorting arguments, more evaluations later
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<lst>(seq[1]);
- new_lst.append(i);
- result += arg_diff * Derivative(fcn, new_lst);
- }
- }
} else {
// Chain rule
ex arg_diff;
{
GINAC_ASSERT(serial<registered_functions().size());
- if (registered_functions()[serial].derivative_f==0) {
- return Derivative(*this, lst(ex(diff_param)));
- }
+ // No derivative defined? Then return abstract derivative object
+ if (registered_functions()[serial].derivative_f == NULL)
+ return fderivative(serial, diff_param, seq);
+
switch (registered_functions()[serial].nparams) {
// the following lines have been generated for max. ${maxargs} parameters
${diff_switch_statement}
#include "ncmul.h"
#include "inifcns.h"
+#include "fderivative.h"
#include "operators.h"
#ifndef GINAC_BASE_ONLY
DEFAULT_UNARCHIVE(spinidx)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
void idx::print(const print_context & c, unsigned level) const
* @return newly constructed index */
explicit idx(const ex & v, const ex & dim);
- // 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 info(unsigned inf) const;
* @return newly constructed index */
varidx(const ex & v, const ex & dim, bool covariant = false);
- // 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 is_dummy_pair_same_type(const basic & other) const;
* @return newly constructed index */
spinidx(const ex & v, const ex & dim = 2, bool covariant = false, bool dotted = false);
- // 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 is_dummy_pair_same_type(const basic & other) const;
DEFAULT_UNARCHIVE(indexed)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
void indexed::print(const print_context & c, unsigned level) const
<< std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
<< ", " << seq.size()-1 << " indices"
<< ", symmetry=" << symtree << std::endl;
- c.s << std::endl;
unsigned delta_indent = static_cast<const print_tree &>(c).delta_indent;
seq[0].print(c, level + delta_indent);
printindices(c, level + delta_indent);
series_func(Order_series).
latex_name("\\mathcal{O}"));
-//////////
-// Inert partial differentiation operator
-//////////
-
-ex Derivative_eval(const ex & f, const ex & l)
-{
- if (!is_ex_of_type(f, function))
- throw(std::invalid_argument("Derivative(): 1st argument must be a function"));
- if (!is_ex_of_type(l, lst))
- throw(std::invalid_argument("Derivative(): 2nd argument must be a list"));
-
-#if 0
- // Perform differentiations if possible
- const function &fcn = ex_to<function>(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<lst>(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
//////////
/** 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. */
return sign*_ex1();
}
- if (is_ex_exactly_of_type(x, function)) {
+ if (is_exactly_a<function>(x)) {
ex t = x.op(0);
// sin(asin(x)) -> x
if (is_ex_the_function(x, asin))
return sign*_ex0();
}
- if (is_ex_exactly_of_type(x, function)) {
+ if (is_exactly_a<function>(x)) {
ex t = x.op(0);
// cos(acos(x)) -> x
if (is_ex_the_function(x, acos))
throw (pole_error("tan_eval(): simple pole",1));
}
- if (is_ex_exactly_of_type(x, function)) {
+ if (is_exactly_a<function>(x)) {
ex t = x.op(0);
// tan(atan(x)) -> x
if (is_ex_the_function(x, atan))
ex_to<numeric>(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<function>(x)) {
ex t = x.op(0);
// sinh(asinh(x)) -> x
if (is_ex_the_function(x, asinh))
ex_to<numeric>(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<function>(x)) {
ex t = x.op(0);
// cosh(acosh(x)) -> x
if (is_ex_the_function(x, acosh))
ex_to<numeric>(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<function>(x)) {
ex t = x.op(0);
// tanh(atanh(x)) -> x
if (is_ex_the_function(x, atanh))
DEFAULT_UNARCHIVE(matrix)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// 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;
DEFAULT_ARCHIVING(mul)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// 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;}
DEFAULT_ARCHIVING(ncmul)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
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<int> intvector;
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());
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<add>(*cit)) {
positions_of_adds[number_of_adds] = current_position;
- const add & expanded_addref = ex_to<add>(*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;
}
while (true) {
exvector term = expanded_seq;
- for (int i=0; i<number_of_adds; i++) {
- GINAC_ASSERT(is_ex_exactly_of_type(expanded_seq[positions_of_adds[i]], add));
- const add & addref = ex_to<add>(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<number_of_adds; i++)
+ term[positions_of_adds[i]] = expanded_seq[positions_of_adds[i]].op(k[i]);
distrseq.push_back((new ncmul(term, true))->
setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)));
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;}
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
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;}
DEFAULT_UNARCHIVE(power)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
power(const ex & lh, const ex & rh) : inherited(TINFO_power), basis(lh), exponent(rh) {}
template<typename T> 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;}
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
DEFAULT_UNARCHIVE(relational)
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// 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;}
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
{
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:
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;
}
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
#include "print.h"
#include "archive.h"
#include "debugmsg.h"
+#include "tostring.h"
#include "utils.h"
namespace GiNaC {
}
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
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
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
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
if (children.empty()) {
if (indices.size() > 0)
c.s << *(indices.begin());
+ else
+ c.s << "none";
} else {
switch (type) {
case none: c.s << '!'; break;
}
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
DEFAULT_COMPARE(tensor)
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; }
};
{
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;
{
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;
/** 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;
{
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;
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;
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;
// 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
// none
//////////
-// functions overriding virtual functions from bases classes
+// functions overriding virtual functions from base classes
//////////
// public
#include <string>
#include <stdexcept>
-#if defined(HAVE_SSTREAM)
-#include <sstream>
-#elif defined(HAVE_STRSTREAM)
-#include <strstream>
-#else
-#error Need either sstream or strstream
-#endif
#include "assertion.h"
namespace GiNaC {
-// This should be obsoleted once <sstream> is widely deployed.
-template<class T>
-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 {};
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