From vollinga at thep.physik.uni-mainz.de Fri Apr 1 17:00:52 2005 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Fri, 1 Apr 2005 17:00:52 +0200 Subject: [GiNaC-devel] clifford patch Message-ID: <20050401150052.GA19322@thep.physik.uni-mainz.de> Hi Vladimir, I applied your and C.Dams' patch now. But I also applied a forgotten patch from you from December that changes ex clifford::get_metric(const ex & i, const ex & j) const from return indexed(metric, symmetric2(), i, j); to return indexed(metric, i, j); With this December patch the exams for clifford fail with ----------clifford objects: 2*ONE*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu-2*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*ONE erroneously return ed 2*ONE*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu-2*[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*ONE instead of 0 [[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*e~lambda-[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu*e~lambda-0 erroneousl y returned [[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~mu~nu*e~lambda-[[-1,0,0,0],[0,0,0,0],[0,0,1,0],[0,0,0,-1]]~nu~mu*e~lambda i nstead of 0 Without it, it produces no error. The December patch makes sense to me, because the tutorial promises that one can use non-symmetric metrics. Am I wrong here? So, what should I do about it? Regards, Jens From fausap at libero.it Sat Apr 9 12:13:30 2005 From: fausap at libero.it (Fausto Saporito) Date: Sat, 9 Apr 2005 12:13:30 +0200 Subject: [GiNaC-devel] CLN compiling issue on Mac OS X 1.3 Message-ID: <33836d60520f5a680ecd18820653914c@libero.it> Hello, I have a problem generating configure under Mac OS X 1.3 with Fink. When I run autoconf I don't receive any errors, but when I run configure script I have after a while, checking whether make sets $(MAKE)... yes checking for gcc... gcc checking for C compiler default output file name... a.out checking whether the C compiler works... yes checking whether we are cross compiling... no checking for suffix of executables... checking for suffix of object files... o checking whether we are using the GNU C compiler... yes checking whether gcc accepts -g... yes checking for gcc option to accept ANSI C... none needed checking how to run the C preprocessor... gcc -E checking for g++... g++ checking whether we are using the GNU C++ compiler... yes checking whether g++ accepts -g... yes checking how to run the C++ preprocessor... g++ -E ./configure: line 3318: CL_AS_UNDERSCORE: command not found checking for ranlib... ranlib checking for a BSD-compatible install... /usr/bin/install -c ./configure: line 3478: syntax error near unexpected token `autoconf' ./configure: line 3478: ` CL_CANONICAL_HOST(autoconf)' I'm using autoconf 2.59 is it the right version? What is the exact procedure to generate a configure? I didn't find any autogen.sh script, so I tried to use the autogen.sh present in GiNaC cvs tree. When I run autogen.sh I have some warnings: + Running aclocal: /sw/share/aclocal/pth.m4:43: warning: underquoted definition of _AC_PTH_ERROR run info '(automake)Extending aclocal' or see http://sources.redhat.com/automake/automake.html#Extending-aclocal /sw/share/aclocal/pth.m4:55: warning: underquoted definition of _AC_PTH_VERBOSE /sw/share/aclocal/pth.m4:61: warning: underquoted definition of AC_CHECK_PTH /sw/share/aclocal/pkg.m4:5: warning: underquoted definition of PKG_CHECK_MODULES /sw/share/aclocal/libgcrypt.m4:23: warning: underquoted definition of AM_PATH_LIBGCRYPT /sw/share/aclocal/gtk.m4:7: warning: underquoted definition of AM_PATH_GTK /sw/share/aclocal/glib.m4:8: warning: underquoted definition of AM_PATH_GLIB done. + Running libtoolize: done. + Running autoheader: autoheader: warning: missing template: CL_USE_GMP autoheader: Use AC_DEFINE([CL_USE_GMP], [], [Description]) autoheader: warning: missing template: CL_VERSION autoheader: warning: missing template: CL_VERSION_MAJOR autoheader: warning: missing template: CL_VERSION_MINOR autoheader: warning: missing template: CL_VERSION_PATCHLEVEL done. + Running automake: configure.ac: no proper invocation of AM_INIT_AUTOMAKE was found. configure.ac: You should verify that configure.ac invokes AM_INIT_AUTOMAKE, configure.ac: that aclocal.m4 is present in the top-level directory, configure.ac: and that aclocal.m4 was recently regenerated (using aclocal). configure.ac: installing `autoconf/missing' automake: no `Makefile.am' found for any configure output done. + Running autoconf: done. Any idea? thanks a lot, Fausto From vollinga at thep.physik.uni-mainz.de Sun Apr 10 10:54:16 2005 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Sun, 10 Apr 2005 10:54:16 +0200 Subject: [GiNaC-devel] CLN compiling issue on Mac OS X 1.3 Message-ID: <20050410085416.GA9609@thep.physik.uni-mainz.de> Hi Fausto, I am not sure about your problem, but maybe the following might help you. On Sat, Apr 09, 2005 at 12:13:30PM +0200, Fausto Saporito wrote: > I'm using autoconf 2.59 is it the right version? That version works fine with GiNaC. > What is the exact procedure to generate a configure? I didn't find any > autogen.sh script, so I tried to use the autogen.sh present in GiNaC > cvs tree. Use autoreconf -i That does the job those autogen.sh scripts normally take care of. It's part of the autoconf package. > /sw/share/aclocal/pth.m4:55: warning: underquoted definition of > _AC_PTH_VERBOSE > /sw/share/aclocal/pth.m4:61: warning: underquoted definition of > AC_CHECK_PTH > /sw/share/aclocal/pkg.m4:5: warning: underquoted definition of > PKG_CHECK_MODULES > /sw/share/aclocal/libgcrypt.m4:23: warning: underquoted definition of > AM_PATH_LIBGCRYPT > /sw/share/aclocal/gtk.m4:7: warning: underquoted definition of > AM_PATH_GTK > /sw/share/aclocal/glib.m4:8: warning: underquoted definition of > AM_PATH_GLIB The automake files of GiNaC are set up for older versions of automake, like automake 1.4. Newer versions (and there are plenty of them!) produce these warnings. It's kind of annoying but basically harmless. > + Running autoheader: autoheader: warning: missing template: CL_USE_GMP > autoheader: Use AC_DEFINE([CL_USE_GMP], [], [Description]) > autoheader: warning: missing template: CL_VERSION > autoheader: warning: missing template: CL_VERSION_MAJOR > autoheader: warning: missing template: CL_VERSION_MINOR > autoheader: warning: missing template: CL_VERSION_PATCHLEVEL > done. > + Running automake: configure.ac: no proper invocation of > AM_INIT_AUTOMAKE was found. > configure.ac: You should verify that configure.ac invokes > AM_INIT_AUTOMAKE, > configure.ac: that aclocal.m4 is present in the top-level directory, > configure.ac: and that aclocal.m4 was recently regenerated (using > aclocal). > configure.ac: installing `autoconf/missing' > automake: no `Makefile.am' found for any configure output > done. This is not harmless anymore ;-) What's your version of automake? Regards, Jens From fausap at libero.it Mon Apr 11 22:01:11 2005 From: fausap at libero.it (Fausto Saporito) Date: Mon, 11 Apr 2005 22:01:11 +0200 Subject: [GiNaC-devel] CLN compiling issue on Mac OS X 1.3 In-Reply-To: <20050410085416.GA9609@thep.physik.uni-mainz.de> References: <20050410085416.GA9609@thep.physik.uni-mainz.de> Message-ID: Hello Jens, thanks for the reply. > > Use > autoreconf -i > That does the job those autogen.sh scripts normally take care of. > It's part of the autoconf package. I ran the command and I received this output: Using `AC_PROG_RANLIB' is rendered obsolete by `AC_PROG_LIBTOOL' Putting files in AC_CONFIG_AUX_DIR, `autoconf'. libtoolize: `config.guess' exists: use `--force' to overwrite libtoolize: `config.sub' exists: use `--force' to overwrite libtoolize: `ltmain.sh' exists: use `--force' to overwrite autoheader-2.59: warning: missing template: CL_USE_GMP autoheader-2.59: Use AC_DEFINE([CL_USE_GMP], [], [Description]) autoheader-2.59: warning: missing template: CL_VERSION autoheader-2.59: warning: missing template: CL_VERSION_MAJOR autoheader-2.59: warning: missing template: CL_VERSION_MINOR autoheader-2.59: warning: missing template: CL_VERSION_PATCHLEVEL autoreconf: /sw/bin/autoheader-2.59 failed with exit status: 1 > > This is not harmless anymore ;-) What's your version of automake? > automake 1.6.3 regards, fausto From kreckel at ginac.de Sun Apr 10 00:07:34 2005 From: kreckel at ginac.de (Richard B. Kreckel) Date: Sun, 10 Apr 2005 00:07:34 +0200 (CEST) Subject: [GiNaC-devel] CLN compiling issue on Mac OS X 1.3 In-Reply-To: <33836d60520f5a680ecd18820653914c@libero.it> Message-ID: On Sat, 9 Apr 2005, Fausto Saporito wrote: > I have a problem generating configure under Mac OS X 1.3 with Fink. Why can't you just use the configure script that comes with the library? Regards -richy. -- Richard B. Kreckel From C.Dams at science.ru.nl Mon Apr 18 18:30:17 2005 From: C.Dams at science.ru.nl (Chris Dams) Date: Mon, 18 Apr 2005 18:30:17 +0200 (CEST) Subject: [GiNaC-devel] printing of Dirac-slash objects. Message-ID: Dear developers, I found out that dirac_slash(p+q,4) is printed as "q+p\". I think this is confusing and that "(q+p)\" would be much clearer. A patch is attached. Best wishes, Chris -------------- next part -------------- Index: clifford.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.h,v retrieving revision 1.56 diff -c -r1.56 clifford.h *** clifford.h 1 Apr 2005 14:23:40 -0000 1.56 --- clifford.h 18 Apr 2005 16:29:24 -0000 *************** *** 52,57 **** --- 52,59 ---- clifford(unsigned char rl, const ex & metr, std::auto_ptr vp); // functions overriding virtual functions from base classes + public: + unsigned precedence() const {return 65;} protected: ex eval_ncmul(const exvector & v) const; bool match_same_type(const basic & other) const; Index: clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.85 diff -c -r1.85 clifford.cpp *** clifford.cpp 1 Apr 2005 14:23:40 -0000 1.85 --- clifford.cpp 18 Apr 2005 16:29:24 -0000 *************** *** 200,206 **** { // dirac_slash() object is printed differently if (is_dirac_slash(seq[0])) { ! seq[0].print(c, level); c.s << "\\"; } else this->print_dispatch(c, level); --- 200,206 ---- { // dirac_slash() object is printed differently if (is_dirac_slash(seq[0])) { ! seq[0].print(c, precedence()); c.s << "\\"; } else this->print_dispatch(c, level); *************** *** 211,217 **** // dirac_slash() object is printed differently if (is_dirac_slash(seq[0])) { c.s << "{"; ! seq[0].print(c, level); c.s << "\\hspace{-1.0ex}/}"; } else { c.s << "\\clifford[" << int(representation_label) << "]"; --- 211,217 ---- // dirac_slash() object is printed differently if (is_dirac_slash(seq[0])) { c.s << "{"; ! seq[0].print(c, precedence()); c.s << "\\hspace{-1.0ex}/}"; } else { c.s << "\\clifford[" << int(representation_label) << "]"; From kisilv at maths.leeds.ac.uk Wed Apr 20 12:07:29 2005 From: kisilv at maths.leeds.ac.uk (Vladimir Kisil) Date: Wed, 20 Apr 2005 11:07:29 +0100 Subject: [GiNaC-devel] A patch for add::coeff() and new clifford_max_label() Message-ID: Dear All, Working on further patches to clifford.cpp I found that such a simple program #include #include using namespace std; using namespace GiNaC; #include int main(){ realsymbol a("a"); varidx nu(symbol("nu", "\\nu"), 2), mu(symbol("mu", "\\mu"), 2); try { ex e = a* dirac_gamma(nu) + 2*dirac_gamma(nu); cout << e.collect(dirac_gamma(nu)) << endl; // -> (2+a)*gamma~nu e = dirac_gamma(mu)* dirac_gamma(nu) + dirac_gamma(nu); cout << e.collect(dirac_gamma(nu)) << endl; // Raised exception: // add::eval(): sum of non-commutative objects has non-zero numeric term } catch (exception &p) { cerr << "Got problem: " << p.what() << endl; } } raises an exception in the second output statement. I think everyone would like it can produce something like "(ONE+gamma~mu)*gamma~nu" instead. And first output should remain "(2+a)*gamma~nu" and not became "(2*ONE+a*ONE)*gamma~nu" on the other hand. I am not sure that is the best way to achieve it but propose a patch which seems to solve it. It introduces one more utility function clifford_max_label() at clifford.cpp, which returns the maximal representation label of non-commutative Clifford object in the expression. Besides that there is also a patch to add::coeff() in add.cpp. I wrote it in mind to reduce unwonted overheads for expression without any Clifford numbers. After this issue will be rectified some more patches to clifford.cpp will follow. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv at maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/ Index: ginac/clifford.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.h,v retrieving revision 1.56 diff -r1.56 clifford.h 285a286,292 > /** Returns the maximal representation label of a clifford object > * if e contains at least one, otherwise returns -1 > * > * @param e Expression to be processed > * @ignore_ONE defines if clifford_ONE should be ignored in the search*/ > ex clifford_max_label(const ex & e, bool ignore_ONE = false); > Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.86 diff -r1.86 clifford.cpp 1035a1084,1100 > ex clifford_max_label(const ex & e, bool ignore_ONE) > { > if (is_a(e)) > if (ignore_ONE && is_a(e.op(0))) > return _ex_1; > else > return ex_to(e).get_representation_label(); > else { > ex rl = _ex_1; > for (size_t i=0; i < e.nops(); i++) > rl = ex_to(rl - clifford_max_label(e.op(i), ignore_ONE)).is_positive()? > rl : clifford_max_label(e.op(i), ignore_ONE); > return rl; > } > } Index: ginac/add.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/add.cpp,v retrieving revision 1.76 diff -r1.76 add.cpp 31a32 > #include "clifford.h" 293a295,297 > std::auto_ptr coeffseq_cliff(new epvector); > ex rl = clifford_max_label(s); > bool do_clifford = (!rl.is_equal(_ex_1)), nonscalar = false; 299c303,310 < if (!restcoeff.is_zero()) --- > if (!restcoeff.is_zero()) { > if (do_clifford) > if (clifford_max_label(restcoeff).is_equal(_ex_1)) > coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(mul(restcoeff,dirac_ONE(ex_to(rl).to_int())), i->coeff)); > else { > coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(restcoeff, i->coeff)); > nonscalar = true; > } 300a312 > } 304c316,317 < return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); --- > return (new add(nonscalar? coeffseq_cliff : coeffseq, > n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); From vollinga at thep.physik.uni-mainz.de Wed Apr 20 15:46:24 2005 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Wed, 20 Apr 2005 15:46:24 +0200 Subject: [GiNaC-devel] printing of Dirac-slash objects. In-Reply-To: References: Message-ID: <20050420134624.GA16392@thep.physik.uni-mainz.de> Hi Chris, On Mon, Apr 18, 2005 at 06:30:17PM +0200, Chris Dams wrote: > > Dear developers, > > I found out that dirac_slash(p+q,4) is printed as "q+p\". I think this > is > confusing and that "(q+p)\" would be much clearer. A patch is > attached. > > Best wishes, > Chris your patch has been applied. Thanks! Regards, Jens From vollinga at thep.physik.uni-mainz.de Wed Apr 20 19:23:15 2005 From: vollinga at thep.physik.uni-mainz.de (Jens Vollinga) Date: Wed, 20 Apr 2005 19:23:15 +0200 Subject: [GiNaC-devel] A patch for add::coeff() and new clifford_max_label() In-Reply-To: References: Message-ID: <20050420172315.GA23671@thep.physik.uni-mainz.de> Hi Kisil, On Wed, Apr 20, 2005 at 11:07:29AM +0100, Vladimir Kisil wrote: > raises an exception in the second output statement. I think everyone > would like it can produce something like "(ONE+gamma~mu)*gamma~nu" > instead. And first output should remain "(2+a)*gamma~nu" and not > became "(2*ONE+a*ONE)*gamma~nu" on the other hand. thanks for your patch. It seems to work fine. Nevertheless, I am a bit reluctant to put it into CVS, because there seems to be a bigger issue behind the problem: 'collect' basically uses 'coeff' to do its job. But 'coeff' doesn't care about non-commuting objects. This leads to behavior like the following: ... ex e = dirac_gamma(nu) * dirac_gamma(mu) + dirac_gamma(sigma) * dirac_gamma(mu); cout << e.collect(dirac_gamma(mu)) << endl; gives (gamma~sigma+gamma~nu)*gamma~mu which is fine, but ... ex e = dirac_gamma(mu) * dirac_gamma(nu) + dirac_gamma(mu) * dirac_gamma(sigma); cout << e.collect(dirac_gamma(mu)) << endl; gives (gamma~sigma+gamma~nu)*gamma~mu-gamma~nu*gamma~mu-gamma~sigma*gamma~mu+gamma~mu*gamma~sigma+gamma~mu*gamma~nu which is not wrong but strange. With non-commuting objects one probably needs to distinguish between a left coefficient and a right coefficient. Fixing this problem likely changes the way the ONE-Problem can be addressed. So, at the moment I am not sure what to do. Regards, Jens From kisilv at maths.leeds.ac.uk Wed Apr 20 20:11:40 2005 From: kisilv at maths.leeds.ac.uk (Vladimir Kisil) Date: Wed, 20 Apr 2005 19:11:40 +0100 Subject: [GiNaC-devel] A patch for add::coeff() and new clifford_max_label() In-Reply-To: Your message of "Wed, 20 Apr 2005 19:23:15 +0200." <20050420172315.GA23671@thep.physik.uni-mainz.de> Message-ID: Dear Jens, I see the point. To add a puzzle I play with the following test: #include #include using namespace std; using namespace GiNaC; #include int main(){ realsymbol a("a"), b("b"), c("c"), d("d"); varidx nu(symbol("nu", "\\nu"), 2), mu(symbol("mu", "\\mu"), 2); try { //cout << latex; ex e = 2*a*b*c*dirac_gamma(nu,1) + 2*dirac_gamma(nu,1)*b*b*a*a; cout << e.collect(dirac_gamma(nu,1)) << endl; // -> gamma~nu*(2*c*b*a+2*b^2*a^2) [OK] e = a*d*dirac_gamma(mu,2)*b*b*a*a* dirac_gamma(nu,1) + b*c*dirac_gamma(nu,1)*d*a+ sin(a)*c*dirac_gamma(nu,1)*abs(b)*b; cout << e.collect(dirac_gamma(nu,1)) << endl; //-> (c*ONE*b*sin(a)*abs(b)+d*c*ONE*b*a+d*gamma~mu*b^2*a^3)*gamma~nu [OK] e = d*dirac_gamma(mu,2) * dirac_gamma(nu,1) + a*b*c*dirac_gamma(nu,1); cout << e.collect(dirac_gamma(nu,1)) << endl; //-> gamma~nu*c*b*a+gamma~nu*(d*gamma~mu+c*ONE*b*a)-gamma~nu*c*ONE*b*a [Ugly!] // Just change representation label of dirac_gamma(mu,1) make iprovement e = d*dirac_gamma(mu,1) * dirac_gamma(nu,1) + a*b*c*dirac_gamma(nu,1); cout << e.collect(dirac_gamma(nu,1)) << endl; //-> (d*gamma~mu+c*ONE*b*a)*gamma~nu [Again OK!??] } catch (exception &p) { cerr << "Got problem: " << p.what() << endl; } } In the third out the expression gamma~nu*c*b*a-gamma~nu*c*ONE*b*a is not simplified to 0 automatically, although this disappear in the fourth output if all Clifford entries has the same representation label. Just in case my previous patch may be of some use I would like to give another version of it. The function clifford_max_label() returns now "char" not "ex" which seems more natural. I think that function may be useful in clifford.cpp anyway. By the way, considering commutativity-noncommutative in GiNaC I realised that all symbols are assumed commutative. Is it difficult to add a new class of noncommutative symbols? Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv at maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/ Index: ginac/clifford.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.h,v retrieving revision 1.57 diff -r1.57 clifford.h 287a288,294 > /** Returns the maximal representation label of a clifford object > * if e contains at least one, otherwise returns -1 > * > * @param e Expression to be processed > * @ignore_ONE defines if clifford_ONE should be ignored in the search*/ > char clifford_max_label(const ex & e, bool ignore_ONE = false); Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.88 diff -r1.88 clifford.cpp 1035a1084,1099 > char clifford_max_label(const ex & e, bool ignore_ONE) > { > if (is_a(e)) > if (ignore_ONE && is_a(e.op(0))) > return -1; > else > return ex_to(e).get_representation_label(); > else { > char rl = -1; > for (size_t i=0; i < e.nops(); i++) > rl = (rl > clifford_max_label(e.op(i), ignore_ONE)) ? rl : clifford_max_label(e.op(i), ignore_ONE); > return rl; > } > } > Index: ginac/add.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/add.cpp,v retrieving revision 1.76 diff -r1.76 add.cpp 31a32 > #include "clifford.h" 293a295,297 > std::auto_ptr coeffseq_cliff(new epvector); > char rl = clifford_max_label(s); > bool do_clifford = (rl != -1), nonscalar = false; 299c303,310 < if (!restcoeff.is_zero()) --- > if (!restcoeff.is_zero()) { > if (do_clifford) > if (clifford_max_label(restcoeff) == -1) > coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i->coeff)); > else { > coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(restcoeff, i->coeff)); > nonscalar = true; > } 300a312 > } 304c316,317 < return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); --- > return (new add(nonscalar? coeffseq_cliff : coeffseq, > n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); From Christian.Bauer at uni-mainz.de Wed Apr 20 20:49:44 2005 From: Christian.Bauer at uni-mainz.de (Christian Bauer) Date: Wed, 20 Apr 2005 20:49:44 +0200 Subject: [GiNaC-devel] A patch for add::coeff() and new clifford_max_label() In-Reply-To: References: <20050420172315.GA23671@thep.physik.uni-mainz.de> Message-ID: <20050420184944.GE4850@thep.physik.uni-mainz.de> Hi! On Wed, Apr 20, 2005 at 07:11:40PM +0100, Vladimir Kisil wrote: > Is it difficult to add a new class of noncommutative symbols? You can create noncommutative symbols with this constructor: symbol(const std::string & initname, unsigned rt, unsigned rtt, unsigned domain = domain::complex); "rt" and "rtt" are return_type and return_type_tinfo, respectively. Bye, Christian -- / Physics is an algorithm \/ http://www.uni-mainz.de/~bauec002/ From kisilv at maths.leeds.ac.uk Thu Apr 28 18:18:37 2005 From: kisilv at maths.leeds.ac.uk (Vladimir Kisil) Date: Thu, 28 Apr 2005 17:18:37 +0100 Subject: [GiNaC-devel] End of the patch Message-ID: This is the end of previous patch. -- Vladimir V. Kisil email: kisilv at maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/ Index: check/exam_clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/check/exam_clifford.cpp,v retrieving revision 1.24 diff -r1.24 exam_clifford.cpp 24a25,26 > const numeric half(1, 2); > 27c29 < ex e = e1 - e2; --- > ex e = normal(e1 - e2); 29,30c31,32 < clog << e1 << "-" << e2 << " erroneously returned " < << e << " instead of 0" << endl; --- > clog << "(" << e1 << ") - (" << e2 << ") erroneously returned " > << e << " instead of 0" << endl; 38c40 < ex e = simplify_indexed(e1) - e2; --- > ex e = normal(simplify_indexed(e1) - e2); 40,41c42,43 < clog << "simplify_indexed(" << e1 << ")-" << e2 << " erroneously returned " < << e << " instead of 0" << endl; --- > clog << "simplify_indexed(" << e1 << ") - (" << e2 << ") erroneously returned " > << e << " instead of 0" << endl; 46a49,88 > static unsigned check_equal_lst(const ex &e1, const ex &e2) > { > for(int i = 0; i++; i < e1.nops()) { > ex e = e1.op(i) - e2.op(i); > if (!e.is_zero()) { > clog << "(" << e1 << ") - (" << e2 << ") erroneously returned " > << e << " instead of 0 (in the entry " << i << ")" << endl; > return 1; > } > } > return 0; > } > > static unsigned check_equal_simplify_term(const ex &e1, const ex &e2, varidx &mu) > { > ex e = expand_dummy_sum(normal(simplify_indexed(e1) - e2), true); > > for (int j=0; j<4; j++) { > ex esub = e.subs(lst(mu == idx(j, mu.get_dim()), mu.toggle_variance() == idx(j, mu.get_dim()))); > if (!(canonicalize_clifford(esub).is_zero())) { > clog << "simplify_indexed(" << e1 << ") - (" << e2 << ") erroneously returned " > << canonicalize_clifford(esub) << " instead of 0 for mu=" << j << endl; > return 1; > } > } > return 0; > } > > static unsigned check_equal_simplify_term2(const ex &e1, const ex &e2) > { > ex e = expand_dummy_sum(normal(simplify_indexed(e1) - e2), true); > if (!(canonicalize_clifford(e).is_zero())) { > clog << "simplify_indexed(" << e1 << ") - (" << e2 << ") erroneously returned " > << canonicalize_clifford(e) << " instead of 0" << endl; > return 1; > } > return 0; > } > > 264a307 > 271c314,316 < ex G = A; --- > matrix A_symm(4,4), A2(4, 4); > A_symm = A.add(A.transpose()).mul(half); > A2 = A_symm.mul(A_symm); 273,274d317 < matrix A2(4, 4); < A2 = A.mul(A); 276c319 < --- > bool anticommuting = ex_to(clifford_unit(nu, A)).is_anticommuting(); 280,281c323,324 < e = dirac_ONE() * clifford_unit(mu, G) * dirac_ONE(); < result += check_equal(e, clifford_unit(mu, G)); --- > e = dirac_ONE(2) * clifford_unit(mu, A, 2) * dirac_ONE(2); > result += check_equal(e, clifford_unit(mu, A, 2)); 283,284c326,327 < e = clifford_unit(varidx(2, 4), G) * clifford_unit(varidx(1, 4), G) < * clifford_unit(varidx(1, 4), G) * clifford_unit(varidx(2, 4), G); --- > e = clifford_unit(idx(2, 4), A) * clifford_unit(idx(1, 4), A) > * clifford_unit(idx(1, 4), A) * clifford_unit(idx(2, 4), A); 287c330,334 < e = clifford_unit(nu, G) * clifford_unit(nu.toggle_variance(), G); --- > e = clifford_unit(varidx(2, 4), A) * clifford_unit(varidx(1, 4), A) > * clifford_unit(varidx(1, 4), A) * clifford_unit(varidx(2, 4), A); > result += check_equal(e, A(1, 1) * A(2, 2) * dirac_ONE()); > > e = clifford_unit(nu, A) * clifford_unit(nu.toggle_variance(), A); 290,291c337,338 < e = clifford_unit(nu, G) * clifford_unit(nu, G); < result += check_equal_simplify(e, indexed(G, sy_symm(), nu, nu) * dirac_ONE()); --- > e = clifford_unit(nu, A) * clifford_unit(nu, A); > result += check_equal_simplify(e, indexed(A_symm, sy_symm(), nu, nu) * dirac_ONE()); 293,294c340,341 < e = clifford_unit(nu, G) * clifford_unit(nu.toggle_variance(), G) * clifford_unit(mu, G); < result += check_equal_simplify(e, A.trace() * clifford_unit(mu, G)); --- > e = clifford_unit(nu, A) * clifford_unit(nu.toggle_variance(), A) * clifford_unit(mu, A); > result += check_equal_simplify(e, A.trace() * clifford_unit(mu, A)); 296,297c343,347 < e = clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(nu.toggle_variance(), G); < result += check_equal_simplify(e, 2*indexed(G, sy_symm(), mu, mu)*clifford_unit(mu, G) - A.trace()*clifford_unit(mu, G)); --- > e = clifford_unit(nu, A) * clifford_unit(mu, A) * clifford_unit(nu.toggle_variance(), A); > if (anticommuting) > result += check_equal_simplify(e, 2*indexed(A_symm, sy_symm(), mu, mu)*clifford_unit(mu, A) - A.trace()*clifford_unit(mu, A)); > > result += check_equal_simplify_term(e, 2 * indexed(A_symm, sy_symm(), nu.toggle_variance(), mu) *clifford_unit(nu, A)-A.trace()*clifford_unit(mu, A), mu); 299,300c349,350 < e = clifford_unit(nu, G) * clifford_unit(nu.toggle_variance(), G) < * clifford_unit(mu, G) * clifford_unit(mu.toggle_variance(), G); --- > e = clifford_unit(nu, A) * clifford_unit(nu.toggle_variance(), A) > * clifford_unit(mu, A) * clifford_unit(mu.toggle_variance(), A); 303,304c353,354 < e = clifford_unit(mu, G) * clifford_unit(nu, G) < * clifford_unit(nu.toggle_variance(), G) * clifford_unit(mu.toggle_variance(), G); --- > e = clifford_unit(mu, A) * clifford_unit(nu, A) > * clifford_unit(nu.toggle_variance(), A) * clifford_unit(mu.toggle_variance(), A); 307,323c357,370 < e = clifford_unit(mu, G) * clifford_unit(nu, G) < * clifford_unit(mu.toggle_variance(), G) * clifford_unit(nu.toggle_variance(), G); < result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE()); < < e = clifford_unit(mu.toggle_variance(), G) * clifford_unit(nu, G) < * clifford_unit(mu, G) * clifford_unit(nu.toggle_variance(), G); < result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE()); < < e = clifford_unit(nu.toggle_variance(), G) * clifford_unit(rho.toggle_variance(), G) < * clifford_unit(mu, G) * clifford_unit(rho, G) * clifford_unit(nu, G); < e = e.simplify_indexed().collect(clifford_unit(mu, G)); < result += check_equal(e, (pow(A.trace(), 2)+4-4*A.trace()*indexed(A, mu, mu)) * clifford_unit(mu, G)); < < e = clifford_unit(nu.toggle_variance(), G) * clifford_unit(rho, G) < * clifford_unit(mu, G) * clifford_unit(rho.toggle_variance(), G) * clifford_unit(nu, G); < e = e.simplify_indexed().collect(clifford_unit(mu, G)); < result += check_equal(e, (pow(A.trace(), 2)+4-4*A.trace()*indexed(A, mu, mu))* clifford_unit(mu, G)); --- > e = clifford_unit(mu, A) * clifford_unit(nu, A) > * clifford_unit(mu.toggle_variance(), A) * clifford_unit(nu.toggle_variance(), A); > if (anticommuting) > result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE()); > > result += check_equal_simplify_term2(e, 2*indexed(A_symm, sy_symm(), nu.toggle_variance(), mu.toggle_variance()) * clifford_unit(mu, A) * clifford_unit(nu, A) - pow(A.trace(), 2)*dirac_ONE()); > > e = clifford_unit(mu.toggle_variance(), A) * clifford_unit(nu, A) > * clifford_unit(mu, A) * clifford_unit(nu.toggle_variance(), A); > if (anticommuting) { > result += check_equal_simplify(e, 2*A2.trace()*dirac_ONE() - pow(A.trace(), 2)*dirac_ONE()); > e1 = remove_dirac_ONE(simplify_indexed(e)); > result += check_equal(e1, 2*A2.trace() - pow(A.trace(), 2)); > } 325,327c372 < // canonicalize_clifford() checks < e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G); < result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G, sy_symm(), mu, nu)); --- > result += check_equal_simplify_term2(e, 2*indexed(A_symm, nu, mu) * clifford_unit(mu.toggle_variance(), A) * clifford_unit(nu.toggle_variance(), A) - pow(A.trace(), 2)*dirac_ONE()); 329,338c374,406 < e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G) < + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G) < + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G) < - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G) < - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G) < - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6 < + indexed(G, sy_symm(), mu, nu) * clifford_unit(lam, G) < - indexed(G, sy_symm(), mu, lam) * clifford_unit(nu, G) < + indexed(G, sy_symm(), nu, lam) * clifford_unit(mu, G) < - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G); --- > e = clifford_unit(nu.toggle_variance(), A) * clifford_unit(rho.toggle_variance(), A) > * clifford_unit(mu, A) * clifford_unit(rho, A) * clifford_unit(nu, A); > e = e.simplify_indexed().collect(clifford_unit(mu, A)); > if (anticommuting) > result += check_equal(e, (4*indexed(A2, sy_symm(), mu, mu) - 4 * indexed(A_symm, sy_symm(), mu, mu)*A.trace() +pow(A.trace(), 2)) * clifford_unit(mu, A)); > > result += check_equal_simplify_term(e, 4* indexed(A_symm, sy_symm(), nu.toggle_variance(), rho)*indexed(A_symm, sy_symm(), rho.toggle_variance(), mu) *clifford_unit(nu, A) > - 2*A.trace() * (clifford_unit(rho, A) * indexed(A_symm, sy_symm(), rho.toggle_variance(), mu) > +clifford_unit(nu, A) * indexed(A_symm, sy_symm(), nu.toggle_variance(), mu)) + pow(A.trace(),2)* clifford_unit(mu, A), mu); > > e = clifford_unit(nu.toggle_variance(), A) * clifford_unit(rho, A) > * clifford_unit(mu, A) * clifford_unit(rho.toggle_variance(), A) * clifford_unit(nu, A); > e = e.simplify_indexed().collect(clifford_unit(mu, A)); > if (anticommuting) > result += check_equal(e, (4*indexed(A2, sy_symm(), mu, mu) - 4*indexed(A_symm, sy_symm(), mu, mu)*A.trace() +pow(A.trace(), 2))* clifford_unit(mu, A)); > > result += check_equal_simplify_term(e, 4* indexed(A_symm, sy_symm(), nu.toggle_variance(), rho)*indexed(A_symm, sy_symm(), rho.toggle_variance(), mu) *clifford_unit(nu, A) > - 2*A.trace() * (clifford_unit(rho, A) * indexed(A_symm, sy_symm(), rho.toggle_variance(), mu) > +clifford_unit(nu, A) * indexed(A_symm, sy_symm(), nu.toggle_variance(), mu)) + pow(A.trace(),2)* clifford_unit(mu, A), mu); > > e = clifford_unit(mu, A) * clifford_unit(nu, A) + clifford_unit(nu, A) * clifford_unit(mu, A); > result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(A_symm, sy_symm(), mu, nu)); > > e = (clifford_unit(mu, A) * clifford_unit(nu, A) * clifford_unit(lam, A) > + clifford_unit(nu, A) * clifford_unit(lam, A) * clifford_unit(mu, A) > + clifford_unit(lam, A) * clifford_unit(mu, A) * clifford_unit(nu, A) > - clifford_unit(nu, A) * clifford_unit(mu, A) * clifford_unit(lam, A) > - clifford_unit(lam, A) * clifford_unit(nu, A) * clifford_unit(mu, A) > - clifford_unit(mu, A) * clifford_unit(lam, A) * clifford_unit(nu, A)) / 6 > + indexed(A_symm, sy_symm(), mu, nu) * clifford_unit(lam, A) > - indexed(A_symm, sy_symm(), mu, lam) * clifford_unit(nu, A) > + indexed(A_symm, sy_symm(), nu, lam) * clifford_unit(mu, A) > - clifford_unit(mu, A) * clifford_unit(nu, A) * clifford_unit(lam, A); 344,345c412,413 < ex c = clifford_unit(nu, G, 1); < e = lst_to_clifford(lst(t, x, y, z), mu, G, 1) * lst_to_clifford(lst(1, 2, 3, 4), c); --- > ex c = clifford_unit(nu, A, 1); > e = lst_to_clifford(lst(t, x, y, z), mu, A, 1) * lst_to_clifford(lst(1, 2, 3, 4), c); 347c415,443 < result += check_equal((e*e1).simplify_indexed().normal(), dirac_ONE(1)); --- > result += check_equal_lst((e*e1).simplify_indexed(), dirac_ONE(1)); > > // Moebius map (both forms) checks for symmetric metrics only > matrix M1(2, 2), M2(2, 2); > c = clifford_unit(nu, A); > > e = clifford_moebius_map(0, dirac_ONE(), > dirac_ONE(), 0, lst(t, x, y, z), A); // this is just the inversion > M1 = 0, dirac_ONE(), > dirac_ONE(), 0; > e1 = clifford_moebius_map(M1, lst(t, x, y, z), A); // the inversion again > result += check_equal_lst(e, e1); > > e1 = clifford_to_lst(clifford_inverse(lst_to_clifford(lst(t, x, y, z), mu, A)), c); > result += check_equal_lst(e, e1); > > e = clifford_moebius_map(dirac_ONE(), lst_to_clifford(lst(1, 2, 3, 4), nu, A), > 0, dirac_ONE(), lst(t, x, y, z), A); //this is just a shift > M2 = dirac_ONE(), lst_to_clifford(lst(1, 2, 3, 4), c), > 0, dirac_ONE(); > e1 = clifford_moebius_map(M2, lst(t, x, y, z), c); // the same shift > result += check_equal_lst(e, e1); > > result += check_equal(e, lst(t+1, x+2, y+3, z+4)); > > // Check the group law for Moebius maps > e = clifford_moebius_map(M1, ex_to(e1), c); //composition of M1 and M2 > e1 = clifford_moebius_map(M1.mul(M2), lst(t, x, y, z), c); // the product M1*M2 > result += check_equal_lst(e, e1); 352c448,449 < static unsigned clifford_check7() --- > > static unsigned clifford_check7(const ex & G, const symbol & dim) 358d454 < symbol dim("D"); 362c458 < ex e; --- > ex e, G_base; 364c460,463 < ex G = minkmetric(); --- > if (is_a(G)) > G_base = G.op(0); > else > G_base = G; 389,404c488,519 < // canonicalize_clifford() checks < e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G); < result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G, sy_symm(), mu, nu)); < < e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G) < + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G) < + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G) < - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G) < - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G) < - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6 < + indexed(G, sy_symm(), mu, nu) * clifford_unit(lam, G) < - indexed(G, sy_symm(), mu, lam) * clifford_unit(nu, G) < + indexed(G, sy_symm(), nu, lam) * clifford_unit(mu, G) < - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G); < result += check_equal(canonicalize_clifford(e), 0); < --- > // canonicalize_clifford() checks, only for symmetric metrics > if (ex_to(ex_to(ex_to(clifford_unit(mu, G)).get_metric()).get_symmetry()).has_symmetry()) { > e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G); > result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*indexed(G_base, sy_symm(), nu, mu)); > > e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G) > + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G) > + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G) > - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G) > - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G) > - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6 > + indexed(G_base, sy_symm(), mu, nu) * clifford_unit(lam, G) > - indexed(G_base, sy_symm(), mu, lam) * clifford_unit(nu, G) > + indexed(G_base, sy_symm(), nu, lam) * clifford_unit(mu, G) > - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G); > result += check_equal(canonicalize_clifford(e), 0); > } else { > e = clifford_unit(mu, G) * clifford_unit(nu, G) + clifford_unit(nu, G) * clifford_unit(mu, G); > result += check_equal(canonicalize_clifford(e), dirac_ONE()*(indexed(G_base, mu, nu) + indexed(G_base, nu, mu))); > > e = (clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G) > + clifford_unit(nu, G) * clifford_unit(lam, G) * clifford_unit(mu, G) > + clifford_unit(lam, G) * clifford_unit(mu, G) * clifford_unit(nu, G) > - clifford_unit(nu, G) * clifford_unit(mu, G) * clifford_unit(lam, G) > - clifford_unit(lam, G) * clifford_unit(nu, G) * clifford_unit(mu, G) > - clifford_unit(mu, G) * clifford_unit(lam, G) * clifford_unit(nu, G)) / 6 > + half * (indexed(G_base, mu, nu) + indexed(G_base, nu, mu)) * clifford_unit(lam, G) > - half * (indexed(G_base, mu, lam) + indexed(G_base, lam, mu)) * clifford_unit(nu, G) > + half * (indexed(G_base, nu, lam) + indexed(G_base, lam, nu)) * clifford_unit(mu, G) > - clifford_unit(mu, G) * clifford_unit(nu, G) * clifford_unit(lam, G); > result += check_equal(canonicalize_clifford(e), 0); > } 420a536,545 > // anticommuting, symmetric examples > result += clifford_check6(ex_to(diag_matrix(lst(-1, 1, 1, 1)))); cout << '.' << flush; > result += clifford_check6(ex_to(diag_matrix(lst(-1, -1, -1, -1)))); cout << '.' << flush; > result += clifford_check6(ex_to(diag_matrix(lst(-1, 1, 1, -1)))); cout << '.' << flush; > result += clifford_check6(ex_to(diag_matrix(lst(-1, 0, 1, -1)))); cout << '.' << flush; > result += clifford_check6(ex_to(diag_matrix(lst(-3, 0, 2, -1)))); cout << '.' << flush; > > realsymbol s("s"), t("t"); // symbolic entries in matric > result += clifford_check6(ex_to(diag_matrix(lst(-1, 1, s, t)))); cout << '.' << flush; > 422,425c547,550 < A = -1, 0, 0, 0, < 0, 1, 0, 0, < 0, 0, 1, 0, < 0, 0, 0, 1; --- > A = 1, 0, 0, 0, // anticommuting, not symmetric, Tr=0 > 0, -1, 0, 0, > 0, 0, 0, -1, > 0, 0, 1, 0; 428,431c553,556 < A = -1, 0, 0, 0, < 0,-1, 0, 0, < 0, 0,-1, 0, < 0, 0, 0,-1; --- > A = 1, 0, 0, 0, // anticommuting, not symmetric, Tr=2 > 0, 1, 0, 0, > 0, 0, 0, -1, > 0, 0, 1, 0; 433,437c558,562 < < A = -1, 0, 0, 0, < 0, 1, 0, 0, < 0, 0, 1, 0, < 0, 0, 0,-1; --- > > A = 1, 0, 0, 0, // not anticommuting, symmetric, Tr=0 > 0, -1, 0, 0, > 0, 0, 0, -1, > 0, 0, -1, 0; 440,443c565,568 < A = -1, 0, 0, 0, < 0, 0, 0, 0, < 0, 0, 1, 0, < 0, 0, 0,-1; --- > A = 1, 0, 0, 0, // not anticommuting, symmetric, Tr=2 > 0, 1, 0, 0, > 0, 0, 0, -1, > 0, 0, -1, 0; 446c571,581 < result += clifford_check7(); cout << '.' << flush; --- > A = 1, 1, 0, 0, // not anticommuting, not symmetric, Tr=4 > 0, 1, 1, 0, > 0, 0, 1, 1, > 0, 0, 0, 1; > result += clifford_check6(A); cout << '.' << flush; > > symbol dim("D"); > result += clifford_check7(minkmetric(), dim); cout << '.' << flush; > > varidx chi(symbol("chi"), dim), xi(symbol("xi"), dim); > result += clifford_check7(lorentz_g(xi, chi), dim); cout << '.' << flush; From kisilv at maths.leeds.ac.uk Thu Apr 28 18:17:55 2005 From: kisilv at maths.leeds.ac.uk (Vladimir Kisil) Date: Thu, 28 Apr 2005 17:17:55 +0100 Subject: [GiNaC-devel] Clifford patch Message-ID: Dear All, Here is a new patch for the clifford.cpp, which is even too large to fin in one message. Thus the tail is sent separately. It relays on two other additions: 1. A patch to add.cpp, which I posted here on Wed Apr 20 12:07:29 CEST 2005. It seems that a more fundamental solutions is required here, so my code is only a temporary one. 2. An additional function expand_dummy_sum() in indexed.cpp. It shares a portion of common code with simplify_indexed() and I put this piece into a separate auxiliary procedure product_to_exvector(). The main changes to clifford.cpp itself are as follows: 1. There are now two different simplifications paths in clifford::contract_with() depending on if Clifford units are anticommuting or not. This information is now stored in a new member variable bool anticommuting; The difference in results of contractions can be seen from exam_clifford.cpp. 2. The present code should work now with non-symmetric metric as well. At present it always result in a symmetrised metric M(i,j)+M(j,i), but this should change when more functions from geometric algebras will be added. 3. Exams in exam_clifford.cpp cover now all defined functions in the majority of possible parameter variations. 4. Many small corrections. 5. Those changes are reflected in ginac.texi Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv at maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/ Index: doc/tutorial/ginac.texi =================================================================== RCS file: /home/cvs/GiNaC/doc/tutorial/ginac.texi,v retrieving revision 1.165 diff -r1.165 ginac.texi 2569a2570,2610 > @cindex @code{expand_dummy_sum()} > A dummy index summation like > @tex > $ a_i b^i$ > @end tex > @ifnottex > a.i b~i > @end ifnottex > can be expanded for indexes with numeric > dimensions (e.g. 3) into the explicit sum like > @tex > $a_1b^1+a_2b^2+a_3b^3 $. > @end tex > @ifnottex > a.1 b~1 + a.2 b~2 + a.3 b~3. > @end ifnottex > This performed by the function > > @example > ex expand_dummy_sum(const ex & e, bool subs_idx = false); > @end example > > which takes an expression @code{e} and returns the expanded sum for all > dummy indexes with numeric dimensions. If the parameter @code{subs_idx} > is set to @code{true} then all substitutions are made by @code{idx} class > indexes, i.e. without variance. In this case the above sum > @tex > $ a_i b^i$ > @end tex > @ifnottex > a.i b~i > @end ifnottex > will be expanded to > @tex > $a_1b_1+a_2b_2+a_3b_3 $. > @end tex > @ifnottex > a.1 b.1 + a.2 b.2 + a.3 b.3. > @end ifnottex > > 3192c3233 < $e_i e_j + e_j e_i = M(i, j) $ --- > $e_i e_j + e_j e_i = M(i, j) + M(j, i) $ 3195c3236 < e~i e~j + e~j e~i = M(i, j) --- > e~i e~j + e~j e~i = M(i, j) + M(j, i) 3197,3199c3238,3241 < for some matrix (@code{metric}) < @math{M(i, j)}, which may be non-symmetric and containing symbolic < entries. Such generators are created by the function --- > for some bilinear form (@code{metric}) > @math{M(i, j)}, which may be non-symmetric (see arXiv:math.QA/9911180) > and contain symbolic entries. Such generators are created by the > function 3202c3244,3245 < ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0); --- > ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0, > bool anticommuting = false); 3206c3249,3251 < generators, @code{metr} defines the metric @math{M(i, j)} and can be --- > generators, an index @code{mu} with a numeric value may be of type > @code{idx} as well. > Parameter @code{metr} defines the metric @math{M(i, j)} and can be 3208,3212c3253,3277 < object, optional parameter @code{rl} allows to distinguish different < Clifford algebras (which will commute with each other). Note that the call < @code{clifford_unit(mu, minkmetric())} creates something very close to < @code{dirac_gamma(mu)}. The method @code{clifford::get_metric()} returns a < metric defining this Clifford number. --- > object. Optional parameter @code{rl} allows to distinguish different > Clifford algebras, which will commute with each other. The last > optional parameter @code{anticommuting} defines if the anticommuting > assumption (i.e. > @tex > $e_i e_j + e_j e_i = 0$) > @end tex > @ifnottex > e~i e~j + e~j e~i = 0) > @end ifnottex > will be used for contraction of Clifford units. If the @code{metric} is > supplied by a @code{matrix} object, then the value of > @code{anticommuting} is calculated automatically and the supplied one > will be ignored. One can overcome this by giving @code{metric} through > matrix wrapped into an @code{indexed} object. > > Note that the call @code{clifford_unit(mu, minkmetric())} creates > something very close to @code{dirac_gamma(mu)}, although > @code{dirac_gamma} have more efficient simplification mechanism. > @cindex @code{clifford::get_metric()} > The method @code{clifford::get_metric()} returns a metric defining this > Clifford number. > @cindex @code{clifford::is_anticommuting()} > The method @code{clifford::is_anticommuting()} returns the > @code{anticommuting} property of a unit. 3221c3286,3288 < since this may yield some further automatic simplifications. --- > since this may yield some further automatic simplifications. Again, for a > metric defined through a @code{matrix} such a symmetry is detected > automatically. 3246c3313,3314 < @code{pow(e0, 2) = 1}, @code{pow(e1, 2) = -1}, @code{pow(e2, 2) = 0} and @code{pow(e3, 2) = s}. --- > @code{pow(e0, 2) = 1}, @code{pow(e1, 2) = -1}, @code{pow(e2, 2) = 0} and > @code{pow(e3, 2) = s}. 3254c3322 < unsigned char rl = 0); --- > unsigned char rl = 0, bool anticommuting = false); 3276c3344 < @code{clifford_unit(mu, metr, rl)}. The previous code may be rewritten --- > @code{clifford_unit(mu, metr, rl, anticommuting)}. The previous code may be rewritten 3324c3392 < is zero or is not a @code{numeric} for some @samp{k} --- > is zero or is not @code{numeric} for some @samp{k} 3413c3481 < The last provided function is --- > The next provided function is 3419c3487 < unsigned char rl = 0); --- > unsigned char rl = 0, bool anticommuting = false); 3421c3489 < unsigned char rl = 0); --- > unsigned char rl = 0, bool anticommuting = false); 3427,3436c3495,3518 < the metric of the surrounding (pseudo-)Euclidean space. This can be a < matrix or a Clifford unit, in the later case the parameter @code{rl} is < ignored even if supplied. The returned value of this function is a list < of components of the resulting vector. < < LaTeX output for Clifford units looks like @code{\clifford[1]@{e@}^@{@{\nu@}@}}, < where @code{1} is the @code{representation_label} and @code{\nu} is the < index of the corresponding unit. This provides a flexible typesetting < with a suitable defintion of the @code{\clifford} command. For example, the < definition --- > the metric of the surrounding (pseudo-)Euclidean space. This can be an > indexed object, tensormetric, matrix or a Clifford unit, in the later > case the optional parameters @code{rl} and @code{anticommuting} are ignored > even if supplied. The returned value of this function is a list of > components of the resulting vector. > > @cindex @code{clifford_max_label()} > Finally the function > > @example > char clifford_max_label(const ex & e, bool ignore_ONE = false); > @end example > > can detect a presence of Clifford objects in the expression @code{e}: if > such objects are found it returns the maximal > @code{representation_label} of them, otherwise @code{-1}. The optional > parameter @code{ignore_ONE} indicates if @code{dirac_ONE} objects should > be ignored during the search. > > LaTeX output for Clifford units looks like > @code{\clifford[1]@{e@}^@{@{\nu@}@}}, where @code{1} is the > @code{representation_label} and @code{\nu} is the index of the > corresponding unit. This provides a flexible typesetting with a suitable > defintion of the @code{\clifford} command. For example, the definition Index: ginac/add.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/add.cpp,v retrieving revision 1.76 diff -r1.76 add.cpp 31a32,33 > #include "clifford.h" > #include "ncmul.h" 293a296,298 > std::auto_ptr coeffseq_cliff(new epvector); > char rl = clifford_max_label(s); > bool do_clifford = (rl != -1), nonscalar = false; 299c304,311 < if (!restcoeff.is_zero()) --- > if (!restcoeff.is_zero()) { > if (do_clifford) > if (clifford_max_label(restcoeff) == -1) > coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i->coeff)); > else { > coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(restcoeff, i->coeff)); > nonscalar = true; > } 300a313 > } 304c317,318 < return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); --- > return (new add(nonscalar? coeffseq_cliff : coeffseq, > n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated); Index: ginac/indexed.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/indexed.h,v retrieving revision 1.50 diff -r1.50 indexed.h 252a253,263 > /** This function returns the given expression with expanded sums > * for all dummy indexes summation, where dimensionality of > * the dummy index is numeric. > * Optionally all indexes with a variance will be substituted by > * indices with the corresponding numeric values without variance. > * > * @param e the given expression > * @param subs_idx indicates if variance of dummy indixes should be neglected > */ > ex expand_dummy_sum(const ex & e, bool subs_idx = false); > Index: ginac/indexed.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/indexed.cpp,v retrieving revision 1.94 diff -r1.94 indexed.cpp 672,674c672,674 < /** Simplify product of indexed expressions (commutative, noncommutative and < * simple squares), return list of free indices. */ < ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & dummy_indices, const scalar_products & sp) --- > /* An auxiliary function used by simplify_indexed() and expand_dummy_sum() > * It returns an exvector of factors from the supplied product*/ > static void product_to_exvector(const ex &e, exvector &v, bool &non_commutative) 678c678 < bool non_commutative = is_exactly_a(e); --- > non_commutative = is_exactly_a(e); 681d680 < exvector v; 703a703,715 > } > > /** Simplify product of indexed expressions (commutative, noncommutative and > * simple squares), return list of free indices. */ > ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & dummy_indices, const scalar_products & sp) > { > // Collect factors in an exvector > exvector v; > > // Remember whether the product was commutative or noncommutative > // (because we chop it into factors and need to reassemble later) > bool non_commutative; > product_to_exvector(e, v, non_commutative); 1278a1291,1352 > } > > ex expand_dummy_sum(const ex &e, bool subs_idx) > { > ex e_expanded = e.expand(); > pointer_to_map_function_1arg fcn(expand_dummy_sum, subs_idx); > if (is_a(e_expanded)) > return e_expanded.map(fcn); > else if (is_a(e_expanded) || is_a(e_expanded) || is_a(e_expanded)) { > exvector p; > bool nc; > product_to_exvector(e_expanded, p, nc); > exvector::const_iterator ip = p.begin(), ipend = p.end(); > exvector v; > while (ip != ipend) { > if (is_a(*ip)) { > v = ex_to(*ip).get_dummy_indices(); > exvector::const_iterator ip1 = ip+1; > while (ip1 != ipend) { > if (is_a(*ip1)) { > exvector v1 = ex_to(*ip).get_dummy_indices(ex_to(*ip1)); > v.insert(v.end(), v1.begin(), v1.end()); > } > ip1++; > } > exvector::const_iterator it = v.begin(), itend = v.end(); > while (it != itend) { > varidx nu = ex_to(*it); > if (nu.is_dim_numeric()) { > ex en = 0; > for (int i=0; i < ex_to(nu.get_dim()).to_int(); i++) > if (is_a(nu) && !subs_idx) > en += e_expanded.subs(lst(nu == varidx(i, nu.get_dim(), true), nu.toggle_variance() == varidx(i, nu.get_dim()))); > else > en += e_expanded.subs(lst(nu == idx(i, nu.get_dim()), nu.toggle_variance() == idx(i, nu.get_dim()))); > return expand_dummy_sum(en, subs_idx); > } > it++; > } > } > ip++; > } > return e; > } else if (is_a(e_expanded)) { > exvector v = ex_to(e_expanded).get_dummy_indices(); > exvector::const_iterator it = v.begin(), itend = v.end(); > while (it != itend) { > varidx nu = ex_to(*it); > if (nu.is_dim_numeric()) { > ex en = 0; > for (int i=0; i < ex_to(nu.get_dim()).to_int(); i++) > if (is_a(nu) && !subs_idx) > en += e_expanded.subs(lst(nu == varidx(i, nu.get_dim(), true), nu.toggle_variance() == varidx(i, nu.get_dim()))); > else > en += e_expanded.subs(lst(nu == idx(i, nu.get_dim()), nu.toggle_variance() == idx(i, nu.get_dim()))); > return expand_dummy_sum(en, subs_idx); > } > it++; > } > return e; > } else > return e; Index: ginac/clifford.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.h,v retrieving revision 1.57 diff -r1.57 clifford.h 47,48c47,48 < clifford(const ex & b, unsigned char rl = 0); < clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl = 0); --- > clifford(const ex & b, unsigned char rl = 0, bool anticommut = false); > clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommut = false); 51,52c51,52 < clifford(unsigned char rl, const ex & metr, const exvector & v, bool discardable = false); < clifford(unsigned char rl, const ex & metr, std::auto_ptr vp); --- > clifford(unsigned char rl, const ex & metr, bool anticommut, const exvector & v, bool discardable = false); > clifford(unsigned char rl, const ex & metr, bool anticommut, std::auto_ptr vp); 69c69 < ex get_metric(const ex & i, const ex & j) const; --- > ex get_metric(const ex & i, const ex & j, bool symmetrised = false) const; 70a71 > bool is_anticommuting() const { return anticommuting; } //**< See the member variable anticommuting */ 79c80,81 < ex metric; --- > ex metric; /**< Metric of the space, all constructors make it an indexed object */ > bool anticommuting; /**< Simplifications for anticommuting units is much simpler and we need this info readily available */ 196c198 < * @param metr Metric (should be of class tensmetric or a derived class, or a matrix) --- > * @param metr Metric (should be indexed, tensmetric or a derived class, or a matrix) 199c201 < ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0); --- > ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommuting = false); 287a290,296 > /** Returns the maximal representation label of a clifford object > * if e contains at least one, otherwise returns -1 > * > * @param e Expression to be processed > * @ignore_ONE defines if clifford_ONE should be ignored in the search*/ > char clifford_max_label(const ex & e, bool ignore_ONE = false); > 298c307 < * @param metr Metric (should be of class tensmetric or a derived class, or a matrix) --- > * @param metr Metric (should be indexed, tensmetric or a derived class, or a matrix) 302c311 < ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0); --- > ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommuting = false); 329a339 > * @param anticommuting indicates if Clifford units anticommutes 331c341 < ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl = 0); --- > ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl = 0, bool anticommuting = false); 339a350 > * @param anticommuting indicates if Clifford units anticommutes 341c352 < ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl = 0); --- > ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl = 0, bool anticommuting = false); Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.88 diff -r1.88 clifford.cpp 80,81c80,81 < < clifford::clifford() : representation_label(0), metric(default_metric()) --- > > clifford::clifford() : representation_label(0), metric(default_metric()), anticommuting(false) 100c100 < clifford::clifford(const ex & b, unsigned char rl) : inherited(b), representation_label(rl), metric(0) --- > clifford::clifford(const ex & b, unsigned char rl, bool anticommut) : inherited(b), representation_label(rl), metric(0), anticommuting(anticommut) 109c109 < clifford::clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl) : inherited(b, mu), representation_label(rl), metric(metr) --- > clifford::clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl, bool anticommut) : inherited(b, mu), representation_label(rl), metric(metr), anticommuting(anticommut) 115c115 < clifford::clifford(unsigned char rl, const ex & metr, const exvector & v, bool discardable) : inherited(not_symmetric(), v, discardable), representation_label(rl), metric(metr) --- > clifford::clifford(unsigned char rl, const ex & metr, bool anticommut, const exvector & v, bool discardable) : inherited(not_symmetric(), v, discardable), representation_label(rl), metric(metr), anticommuting(anticommut) 120c120 < clifford::clifford(unsigned char rl, const ex & metr, std::auto_ptr vp) : inherited(not_symmetric(), vp), representation_label(rl), metric(metr) --- > clifford::clifford(unsigned char rl, const ex & metr, bool anticommut, std::auto_ptr vp) : inherited(not_symmetric(), vp), representation_label(rl), metric(metr), anticommuting(anticommut) 134a135 > n.find_bool("anticommuting", anticommuting); 141a143 > n.add_bool("anticommuting", anticommuting); 156c158 < ex clifford::get_metric(const ex & i, const ex & j) const --- > ex clifford::get_metric(const ex & i, const ex & j, bool symmetrised) const 158c160,170 < return indexed(metric, symmetric2(), i, j); --- > if (is_a(metric)) { > if (symmetrised && !(ex_to(ex_to(metric).get_symmetry()).has_symmetry())) { > if (is_a(metric.op(0))) > return indexed((ex_to(metric.op(0)).add(ex_to(metric.op(0)).transpose())).mul(numeric(1,2)), > symmetric2(), i, j); > else > return simplify_indexed(indexed(metric.op(0)*_ex1_2, i, j) + indexed(metric.op(0)*_ex1_2, j, i)); > } else > return indexed(metric.op(0), ex_to(ex_to(metric).get_symmetry()), i, j); > } else // should not really happen since all constructors but clifford() make the metric an indexed object > return indexed(metric, i, j); 164c176 < return get_metric().is_equal(ex_to(other).get_metric()); --- > return same_metric(ex_to(other).get_metric()); 378,384c390,396 < for (int i=0; i(v[i]) && is_a(v[i]) < && ex_to(c).same_metric(v[i]) < && (ex_to(c.op(1)) == ex_to(v[i]).get_indices()[0] < || ex_to(c.op(1)).toggle_variance() == ex_to(v[i]).get_indices()[0])) { < return ++i; // next to found < } --- > for (size_t i=0; i if (is_a(v[i]) && !is_a(v[i]) > && ((ex_to(c.op(1)) == ex_to(v[i]).get_indices()[0] > && ex_to(c.op(1)) == ex_to(v[i]).get_indices()[1]) > || (ex_to(c.op(1)).toggle_variance() == ex_to(v[i]).get_indices()[0] > && ex_to(c.op(1)).toggle_variance() == ex_to(v[i]).get_indices()[1]))) > return i; // the index of the found 386c398 < return 0; //nothing found --- > return -1; //nothing found 397c409 < --- > 406,408c418,430 < int prev_square = find_same_metric(v, self[0]); < varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to(self->op(1)).get_dim()); < ex squared_metric = unit.get_metric(self->op(1), d) * unit.get_metric(d.toggle_variance(), other->op(1)); --- > int prev_square = find_same_metric(v, *self); > const varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to(self->op(1)).get_dim()), > in1((new symbol)->setflag(status_flags::dynallocated), ex_to(self->op(1)).get_dim()), > in2((new symbol)->setflag(status_flags::dynallocated), ex_to(self->op(1)).get_dim()); > ex squared_metric; > if (prev_square > -1) > squared_metric = simplify_indexed(indexed(v[prev_square].op(0), in1, d) > * unit.get_metric(d.toggle_variance(), in2, true)).op(0); > > exvector::iterator before_other = other - 1; > const varidx & mu = ex_to(self->op(1)); > const varidx & mu_toggle = ex_to(other->op(1)); > const varidx & alpha = ex_to(before_other->op(1)); 412,414c434,436 < if (prev_square != 0) { < *self = squared_metric; < v[prev_square-1] = _ex1; --- > if (prev_square > -1) { > *self = indexed(squared_metric, mu, mu_toggle); > v[prev_square] = _ex1; 416c438 < *self = unit.get_metric(self->op(1), other->op(1)); --- > *self = unit.get_metric(mu, mu_toggle, true); 420,436c442,469 < // e~mu e~alpha e.mu = (2e~alpha^2-Tr) e~alpha < } else if (other - self == 2 < && is_a(self[1])) { < < const ex & ia = self[1].op(1); < const ex & ib = self[1].op(1); < if (is_a(unit.get_metric())) < *self = 2 - unit.get_metric(self->op(1), other->op(1)); < else if (prev_square != 0) { < *self = 2-squared_metric; < v[prev_square-1] = _ex1; < } else < *self = 2*unit.get_metric(ia, ib) - unit.get_metric(self->op(1), other->op(1)); < *other = _ex1; < return true; < < // e~mu S e~alpha e.mu = 2 e~alpha^3 S - e~mu S e.mu e~alpha --- > } else if (other - self == 2) { > if (is_a(*before_other) && ex_to(*before_other).get_representation_label() == rl) { > if (ex_to(*self).is_anticommuting()) { > // e~mu e~alpha e.mu = (2*pow(e~alpha, 2) -Tr(B)) e~alpha > if (prev_square > -1) { > *self = 2 * indexed(squared_metric, alpha, alpha) > - indexed(squared_metric, mu, mu_toggle); > v[prev_square] = _ex1; > } else > *self = 2 * unit.get_metric(alpha, alpha, true) - unit.get_metric(mu, mu_toggle, true); > *other = _ex1; > return true; > > } else { > // e~mu e~alpha e.mu = 2*e~mu B(alpha, mu.toggle_variance())-Tr(B) e~alpha > *self = 2 * (*self) * unit.get_metric(alpha, mu_toggle, true) - unit.get_metric(mu, mu_toggle, true) * (*before_other); > *before_other = _ex1; > *other = _ex1; > return true; > } > } else { > // e~mu S e.mu = Tr S ONE > *self = unit.get_metric(mu, mu_toggle, true); > *other = dirac_ONE(rl); > return true; > } > } else { > // e~mu S e~alpha e.mu = 2 e~mu S B(alpha, mu.toggle_variance()) - e~mu S e.mu e~alpha 439,452c472,475 < } else { < exvector::iterator it = self + 1, next_to_last = other - 1; < while (it != other) { < if (!is_a(*it)) < return false; < ++it; < } < < it = self + 1; < ex S = _ex1; < while (it != next_to_last) { < S *= *it; < *it++ = _ex1; < } --- > if (std::find_if(self + 1, other, is_not_a_clifford()) != other) > return false; > > ex S = ncmul(exvector(self + 1, before_other), true); 454,464c477,490 < const ex & ia = next_to_last->op(1); < const ex & ib = next_to_last->op(1); < if (is_a(unit.get_metric())) < *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last); < else if (prev_square != 0) { < *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last)*unit.get_metric(self->op(1),self->op(1)); < v[prev_square-1] = _ex1; < } else < *self = 2 * (*next_to_last) * S* unit.get_metric(ia,ib) - (*self) * S * (*other) * (*next_to_last); < *next_to_last = _ex1; < *other = _ex1; --- > if (is_a(*before_other) && ex_to(*before_other).get_representation_label() == rl) > if (ex_to(*self).is_anticommuting()) > if (prev_square > -1) > *self = 2 * (*before_other) * S * indexed(squared_metric, alpha, alpha) > - (*self) * S * (*other) * (*before_other); > else > *self = 2 * (*before_other) * S * unit.get_metric(alpha, alpha, true) - (*self) * S * (*other) * (*before_other); > else > *self = 2 * (*self) * S * unit.get_metric(alpha, mu_toggle, true) - (*self) * S * (*other) * (*before_other); > else > // simply commutes > *self = (*self) * S * (*other) * (*before_other); > > std::fill(self + 1, other + 1, _ex1); 467d492 < 469d493 < 583c607 < a = ex_to(a).get_metric(ia, ib); --- > a = ex_to(a).get_metric(ia, ib, true); 633c657 < return clifford(diracone(), representation_label) * sign; --- > return dirac_ONE(representation_label) * sign; 642c666 < return clifford(representation_label, get_metric(), v); --- > return clifford(representation_label, get_metric(), is_anticommuting(), v); 647c671 < return clifford(representation_label, get_metric(), vp); --- > return clifford(representation_label, get_metric(), is_anticommuting(), vp); 672c696 < return clifford(ONE, rl); --- > return clifford(ONE, rl, false); 675c699 < ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl) --- > ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticommuting) 679,680c703,704 < if (!is_a(mu)) < throw(std::invalid_argument("index of Clifford unit must be of type varidx")); --- > if (!is_a(mu)) > throw(std::invalid_argument("clifford_unit(): index of Clifford unit must be of type idx or varidx")); 682,687c706,739 < if (is_a(metr)) < return clifford(unit, mu, metr.op(0), rl); < else if(is_a(metr) || is_a(metr)) < return clifford(unit, mu, metr, rl); < else < throw(std::invalid_argument("metric for Clifford unit must be of type indexed, tensormetric or matrix")); --- > if (ex_to(mu).is_symbolic() && !is_a(mu)) > throw(std::invalid_argument("clifford_unit(): symbolic index of Clifford unit must be of type varidx (not idx)")); > > if (is_a(metr)) { > exvector indices = ex_to(metr).get_indices(); > if ((indices.size() == 2) && is_a(indices[0]) && is_a(indices[1])) > return clifford(unit, mu, metr, rl, anticommuting); > else > throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be indexed exactly by two indices of same type as the given index")); > } else if (is_a(metr)) { > static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to(mu).get_dim()), > chi((new symbol)->setflag(status_flags::dynallocated), ex_to(mu).get_dim()); > return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting); > } else if (is_a(metr)) { > matrix M = ex_to(metr); > unsigned n = M.rows(); > bool symmetric = true; > anticommuting = true; > > static varidx xi((new symbol)->setflag(status_flags::dynallocated), n), > chi((new symbol)->setflag(status_flags::dynallocated), n); > if ((n == M.cols()) && (n == ex_to(mu).get_dim())) { > for (unsigned i = 0; i < n; i++) > for (unsigned j = i+1; j < n; j++) { > if (M(i, j) != M(j, i)) > symmetric = false; > if (M(i, j) != -M(j, i)) > anticommuting = false; > } > return clifford(unit, mu, indexed(metr, symmetric?symmetric2():not_symmetric(), xi, chi), rl, anticommuting); > } else > throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be a square matrix with the same dimensions as index")); > } else > throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type indexed, tensormetric or matrix")); 695c747 < throw(std::invalid_argument("index of Dirac gamma must be of type varidx")); --- > throw(std::invalid_argument("dirac_gamma(): index of Dirac gamma must be of type varidx")); 697c749,751 < return clifford(gamma, mu, default_metric(), rl); --- > static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to(mu).get_dim()), > chi((new symbol)->setflag(status_flags::dynallocated), ex_to(mu).get_dim()); > return clifford(gamma, mu, indexed(default_metric(), symmetric2(), xi, chi), rl, true); 987c1041 < it[0] = (ex_to(save0).get_metric(i1, i2) * b1 * b2).simplify_indexed(); --- > it[0] = (ex_to(save0).get_metric(i1, i2, true) * b1 * b2).simplify_indexed(); 1019c1073 < ex remove_dirac_ONE(const ex & e, unsigned char rl) --- > ex remove_dirac_ONE(const ex & e, unsigned char rl) 1026c1080 < throw(std::invalid_argument("Expression is a non-scalar Clifford number!")); --- > throw(std::invalid_argument("remove_dirac_ONE(): expression is a non-scalar Clifford number!")); 1035a1090,1105 > char clifford_max_label(const ex & e, bool ignore_ONE) > { > if (is_a(e)) > if (ignore_ONE && is_a(e.op(0))) > return -1; > else > return ex_to(e).get_representation_label(); > else { > char rl = -1; > for (size_t i=0; i < e.nops(); i++) > rl = (rl > clifford_max_label(e.op(i), ignore_ONE)) ? rl : clifford_max_label(e.op(i), ignore_ONE); > return rl; > } > } > > 1047c1117 < throw(std::invalid_argument("Cannot find inverse of Clifford number with zero norm!")); --- > throw(std::invalid_argument("clifford_inverse(): cannot find inverse of Clifford number with zero norm!")); 1050c1120 < ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl) --- > ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl, bool anticommuting) 1053,1054c1123,1124 < throw(std::invalid_argument("Index should have a numeric dimension")); < ex e = clifford_unit(mu, metr, rl); --- > throw(std::invalid_argument("lst_to_clifford(): Index should have a numeric dimension")); > ex e = clifford_unit(mu, metr, rl, anticommuting); 1077c1147 < throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch")); --- > throw(std::invalid_argument("lst_to_clifford(): dimensions of vector and clifford unit mismatch")); 1079c1149 < throw(std::invalid_argument("First argument should be a vector vector")); --- > throw(std::invalid_argument("lst_to_clifford(): first argument should be a vector vector")); 1084c1154 < throw(std::invalid_argument("List length and dimension of clifford unit mismatch")); --- > throw(std::invalid_argument("lst_to_clifford(): list length and dimension of clifford unit mismatch")); 1086c1156 < throw(std::invalid_argument("Cannot construct from anything but list or vector")); --- > throw(std::invalid_argument("lst_to_clifford(): cannot construct from anything but list or vector")); 1088c1158 < throw(std::invalid_argument("The second argument should be a Clifford unit")); --- > throw(std::invalid_argument("lst_to_clifford(): the second argument should be a Clifford unit")); 1090c1160 < --- > 1109c1179 < throw(std::invalid_argument("Expression is a Clifford multi-vector")); --- > throw(std::invalid_argument("get_clifford_comp(): expression is a Clifford multi-vector")); 1134c1204 < throw(std::invalid_argument("Expression is not a Clifford vector to the given units")); --- > throw(std::invalid_argument("get_clifford_comp(): expression is not a Clifford vector to the given units")); 1144c1214 < throw(std::invalid_argument("Expression is not usable as a Clifford vector")); --- > throw(std::invalid_argument("get_clifford_comp(): expression is not usable as a Clifford vector")); 1153c1223 < throw(std::invalid_argument("Index should have a numeric dimension")); --- > throw(std::invalid_argument("clifford_to_lst(): index should have a numeric dimension")); 1176c1246 < ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl) --- > ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl, bool anticommuting) 1181c1251 < throw(std::invalid_argument("parameter v should be either vector or list")); --- > throw(std::invalid_argument("clifford_moebius_map(): parameter v should be either vector or list")); 1190c1260 < else throw(std::invalid_argument("metric should be an indexed object, matrix, or a Clifford unit")); --- > else throw(std::invalid_argument("clifford_moebius_map(): metric should be an indexed object, matrix, or a Clifford unit")); 1193c1263 < cu = clifford_unit(mu, G, rl); --- > cu = clifford_unit(mu, G, rl, anticommuting); 1195c1265 < --- > 1201c1271 < ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl) --- > ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl, bool anticommuting) 1205c1275 < ex_to(M)(1,0), ex_to(M)(1,1), v, G, rl); --- > ex_to(M)(1,0), ex_to(M)(1,1), v, G, rl, anticommuting); 1207c1277 < throw(std::invalid_argument("parameter M should be a matrix")); --- > throw(std::invalid_argument("clifford_moebius_map(): parameter M should be a matrix"));