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 \
--- /dev/null
+/** @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;
+}
EXAM(lsolve)
EXAM(indexed)
EXAM(color)
+ EXAM(clifford)
EXAM(misc)
if (result) {
unsigned exam_lsolve();
unsigned exam_indexed();
unsigned exam_color();
+unsigned exam_clifford();
unsigned exam_misc();
#endif // ndef EXAMS_H
(no output)
----------color objects:
(no output)
+----------clifford objects:
+(no output)
----------miscellaneous other things:
(no output)
#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"
// 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)) {
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);
}
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:
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<ls.nops(); i++) {
+ if (is_ex_of_type(ls.op(i), function) &&
+ compare_same_type(ex_to_function(ls.op(i)))==0)
+ return lr.op(i);
+ }
+
+ return inherited::subs(ls, lr);
+}
+
// protected
#include "utils.h"
#include "debugmsg.h"
+#include "exprseq.h" // !!
+
namespace GiNaC {
GINAC_IMPLEMENT_REGISTERED_CLASS(idx, basic)
return inherited::info(inf);
}
+unsigned idx::nops() const
+{
+ // don't count the dimension as that is not really a sub-expression
+ return 1;
+}
+
+ex & idx::let_op(int i)
+{
+ GINAC_ASSERT(i == 0);
+ return value;
+}
+
/** Returns order relation between two indices of the same type. The order
* must be such that dummy indices lie next to each other. */
int idx::compare_same_type(const basic & other) const
// Otherwise substitute value
idx *i_copy = static_cast<idx *>(duplicate());
i_copy->value = lr.op(i);
+ i_copy->clearflag(status_flags::hash_calculated);
return i_copy->setflag(status_flags::dynallocated);
}
}
idx *i_copy = static_cast<idx *>(duplicate());
i_copy->value = subsed_value;
+ i_copy->clearflag(status_flags::hash_calculated);
return i_copy->setflag(status_flags::dynallocated);
}
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;
#include "mul.h"
#include "ncmul.h"
#include "power.h"
+#include "lst.h"
#include "archive.h"
#include "utils.h"
#include "debugmsg.h"
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<ls.nops(); i++) {
+ if (is_ex_of_type(ls.op(i), indexed) &&
+ compare_same_type(ex_to_indexed(ls.op(i)))==0)
+ return lr.op(i);
+ }
+
+ return inherited::subs(ls, lr);
+}
+
ex indexed::thisexprseq(const exvector & v) const
{
return indexed(symmetry, v);
int degree(const ex & s) const;
int ldegree(const ex & s) const;
ex coeff(const ex & s, int n = 1) const;
+ ex subs(const lst & ls, const lst & lr) const;
exvector get_free_indices(void) const;
protected:
ex symbol::subs(const lst & ls, const lst & lr) const
{
- GINAC_ASSERT(ls.nops()==lr.nops());
+ GINAC_ASSERT(ls.nops() == lr.nops());
for (unsigned i=0; i<ls.nops(); i++) {
if (is_ex_exactly_of_type(ls.op(i),symbol)) {
#include "idx.h"
#include "indexed.h"
#include "relational.h"
+#include "lst.h"
#include "numeric.h"
#include "archive.h"
#include "utils.h"
DEFAULT_PRINT(minkmetric, "eta")
DEFAULT_PRINT(tensepsilon, "eps")
+ex tensor::subs(const lst & ls, const lst & lr) const
+{
+ GINAC_ASSERT(ls.nops() == lr.nops());
+
+ for (unsigned i=0; i<ls.nops(); i++) {
+ if (is_ex_of_type(ls.op(i), tensor) &&
+ compare_same_type(ex_to_tensor(ls.op(i)))==0)
+ return lr.op(i);
+ }
+ return *this;
+}
+
/** Automatic symbolic evaluation of an indexed delta tensor. */
ex tensdelta::eval_indexed(const basic & i) const
{
tensor(unsigned ti);
// functions overriding virtual functions from bases classes
+public:
+ ex subs(const lst & ls, const lst & lr) const;
protected:
unsigned return_type(void) const { return return_types::noncommutative_composite; }
};