From aef64ef1f63f7b4cb9236c5c189873e48c6c999b Mon Sep 17 00:00:00 2001 From: Christian Bauer Date: Thu, 5 Apr 2001 19:45:05 +0000 Subject: [PATCH] - subs() can be used to substitute functions, tensors and indexed objects - op(0) of an idx object returns the index value; a nice side-effect of this is that idx'es no longer all have the same hash value - added checks for clifford class --- check/Makefile.am | 3 +- check/exam_clifford.cpp | 85 +++++++++++++++++++++++++++++++++++++++++ check/exams.cpp | 1 + check/exams.h | 1 + check/exams.ref | 2 + ginac/basic.cpp | 28 ++++++++------ ginac/function.pl | 14 +++++++ ginac/idx.cpp | 16 ++++++++ ginac/idx.h | 2 + ginac/indexed.cpp | 14 +++++++ ginac/indexed.h | 1 + ginac/symbol.cpp | 2 +- ginac/tensor.cpp | 13 +++++++ ginac/tensor.h | 2 + 14 files changed, 171 insertions(+), 13 deletions(-) create mode 100644 check/exam_clifford.cpp diff --git a/check/Makefile.am b/check/Makefile.am index 26ef2584..fb943d0b 100644 --- a/check/Makefile.am +++ b/check/Makefile.am @@ -10,7 +10,8 @@ checks_LDADD = ../ginac/libginac.la exams_SOURCES = exam_paranoia.cpp exam_numeric.cpp exam_powerlaws.cpp \ exam_inifcns.cpp exam_differentiation.cpp exam_polygcd.cpp \ exam_normalization.cpp exam_pseries.cpp exam_matrices.cpp exam_lsolve.cpp \ - exam_indexed.cpp exam_color.cpp exam_misc.cpp exams.cpp exams.h + exam_indexed.cpp exam_color.cpp exam_clifford.cpp exam_misc.cpp exams.cpp \ + exams.h exams_LDADD = ../ginac/libginac.la times_SOURCES = time_dennyfliegner.cpp time_gammaseries.cpp \ diff --git a/check/exam_clifford.cpp b/check/exam_clifford.cpp new file mode 100644 index 00000000..d4491191 --- /dev/null +++ b/check/exam_clifford.cpp @@ -0,0 +1,85 @@ +/** @file exam_clifford.cpp + * + * Here we test GiNaC's Clifford algebra objects. */ + +/* + * 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 "exams.h" + +static unsigned check_equal(const ex &e1, const ex &e2) +{ + ex e = e1 - e2; + if (!e.is_zero()) { + clog << e1 << "-" << e2 << " erroneously returned " + << e << " instead of 0" << endl; + return 1; + } + return 0; +} + +static unsigned check_equal_simplify(const ex &e1, const ex &e2) +{ + ex e = simplify_indexed(e1) - e2; + if (!e.is_zero()) { + clog << "simplify_indexed(" << e1 << ")-" << e2 << " erroneously returned " + << e << " instead of 0" << endl; + return 1; + } + return 0; +} + +static unsigned clifford_check1(void) +{ + // checks general identities and contractions + + unsigned result = 0; + + symbol dim("D"); + varidx mu(symbol("mu"), dim), nu(symbol("nu"), dim); + ex e; + + e = dirac_gamma(mu) * dirac_gamma(nu) * + dirac_gamma(nu.toggle_variance()) * dirac_gamma(mu.toggle_variance()); + result += check_equal_simplify(e, pow(dim, 2) * dirac_one()); + + e = dirac_gamma(mu) * dirac_gamma(nu) * + dirac_gamma(mu.toggle_variance()) * dirac_gamma(nu.toggle_variance()); + result += check_equal_simplify(e, 2*dim*dirac_one()-pow(dim, 2)*dirac_one()); + + return result; +} + +unsigned exam_clifford(void) +{ + unsigned result = 0; + + cout << "examining clifford objects" << flush; + clog << "----------clifford objects:" << endl; + + result += clifford_check1(); cout << '.' << flush; + + if (!result) { + cout << " passed " << endl; + clog << "(no output)" << endl; + } else { + cout << " failed " << endl; + } + + return result; +} diff --git a/check/exams.cpp b/check/exams.cpp index 429bfc13..b4ec8cb4 100644 --- a/check/exams.cpp +++ b/check/exams.cpp @@ -49,6 +49,7 @@ try { \ EXAM(lsolve) EXAM(indexed) EXAM(color) + EXAM(clifford) EXAM(misc) if (result) { diff --git a/check/exams.h b/check/exams.h index 94ae18a1..ae454e40 100644 --- a/check/exams.h +++ b/check/exams.h @@ -40,6 +40,7 @@ unsigned exam_matrices(); unsigned exam_lsolve(); unsigned exam_indexed(); unsigned exam_color(); +unsigned exam_clifford(); unsigned exam_misc(); #endif // ndef EXAMS_H diff --git a/check/exams.ref b/check/exams.ref index 47d34012..d44e9104 100644 --- a/check/exams.ref +++ b/check/exams.ref @@ -22,5 +22,7 @@ (no output) ----------color objects: (no output) +----------clifford objects: +(no output) ----------miscellaneous other things: (no output) diff --git a/ginac/basic.cpp b/ginac/basic.cpp index fe1d4ea1..1b388259 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -31,6 +31,10 @@ #include "symbol.h" #include "lst.h" #include "ncmul.h" +#include "idx.h" +#include "indexed.h" +#include "tensor.h" +#include "function.h" #include "archive.h" #include "utils.h" #include "debugmsg.h" @@ -462,11 +466,11 @@ ex basic::expand(unsigned options) const // public -/** Substitute symbols in expression and return the result as a new expression. - * There are two valid types of replacement arguments: 1) a relational like - * symbol==ex and 2) a list of relationals lst(symbol1==ex1,symbol2==ex2,...), - * which is converted to subs(lst(symbol1,symbol2,...),lst(ex1,ex2,...)). - * In addition, an object of class idx can be used instead of a symbol. */ +/** Substitute objects (symbols, indices, tensors, functions, indexed) in + * expression and return the result as a new expression. There are two + * valid types of replacement arguments: 1) a relational like object==ex + * and 2) a list of relationals lst(object1==ex1,object2==ex2,...), which + * is converted to subs(lst(object1,object2,...),lst(ex1,ex2,...)). */ ex basic::subs(const ex & e) const { if (e.info(info_flags::relation_equal)) { @@ -481,13 +485,15 @@ ex basic::subs(const ex & e) const if (!e.op(i).info(info_flags::relation_equal)) { throw(std::invalid_argument("basic::subs(ex): argument must be a list or equations")); } - if (!e.op(i).op(0).info(info_flags::symbol)) { - if (!e.op(i).op(0).info(info_flags::idx)) { - throw(std::invalid_argument("basic::subs(ex): lhs must be a symbol or an idx")); - } + ex s = e.op(i).op(0); + ex r = e.op(i).op(1); + if (!is_ex_of_type(s, symbol) && !is_ex_of_type(s, idx) && + !is_ex_of_type(s, tensor) && !is_ex_of_type(s, function) && + !is_ex_of_type(s, indexed)) { + throw(std::invalid_argument("basic::subs(ex): lhs must be a symbol, idx, tensor, function or indexed")); } - ls.append(e.op(i).op(0)); - lr.append(e.op(i).op(1)); + ls.append(s); + lr.append(r); } return subs(ls,lr); } diff --git a/ginac/function.pl b/ginac/function.pl index b36df872..f6e7b332 100755 --- a/ginac/function.pl +++ b/ginac/function.pl @@ -345,6 +345,7 @@ public: ex evalf(int level=0) const; unsigned calchash(void) const; ex series(const relational & r, int order, unsigned options = 0) const; + ex subs(const lst & ls, const lst & lr) const; ex thisexprseq(const exvector & v) const; ex thisexprseq(exvector * vp) const; protected: @@ -821,6 +822,19 @@ ${series_switch_statement} throw(std::logic_error("function::series(): invalid nparams")); } +ex function::subs(const lst & ls, const lst & lr) const +{ + GINAC_ASSERT(ls.nops() == lr.nops()); + + for (unsigned i=0; i(duplicate()); i_copy->value = lr.op(i); + i_copy->clearflag(status_flags::hash_calculated); return i_copy->setflag(status_flags::dynallocated); } } @@ -236,6 +251,7 @@ ex idx::subs(const lst & ls, const lst & lr) const idx *i_copy = static_cast(duplicate()); i_copy->value = subsed_value; + i_copy->clearflag(status_flags::hash_calculated); return i_copy->setflag(status_flags::dynallocated); } diff --git a/ginac/idx.h b/ginac/idx.h index aa7f94e1..a54ad7c3 100644 --- a/ginac/idx.h +++ b/ginac/idx.h @@ -51,6 +51,8 @@ public: void printtree(std::ostream & os, unsigned indent) const; void print(std::ostream & os, unsigned upper_precedence=0) const; bool info(unsigned inf) const; + unsigned nops() const; + ex & let_op(int i); protected: ex subs(const lst & ls, const lst & lr) const; diff --git a/ginac/indexed.cpp b/ginac/indexed.cpp index 833d46c9..c530c1f4 100644 --- a/ginac/indexed.cpp +++ b/ginac/indexed.cpp @@ -28,6 +28,7 @@ #include "mul.h" #include "ncmul.h" #include "power.h" +#include "lst.h" #include "archive.h" #include "utils.h" #include "debugmsg.h" @@ -368,6 +369,19 @@ ex indexed::coeff(const ex & s, int n) const return n==0 ? ex(*this) : _ex0(); } +ex indexed::subs(const lst & ls, const lst & lr) const +{ + GINAC_ASSERT(ls.nops() == lr.nops()); + + for (unsigned i=0; i