[GiNaC-devel] A patch for add::coeff() and new clifford_max_label()
Vladimir Kisil
kisilv at maths.leeds.ac.uk
Wed Apr 20 12:07:29 CEST 2005
Dear All,
Working on further patches to clifford.cpp I found that such a
simple program
#include <iostream>
#include <ginac/ginac.h>
using namespace std;
using namespace GiNaC;
#include <stdexcept>
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<clifford>(e))
> if (ignore_ONE && is_a<diracone>(e.op(0)))
> return _ex_1;
> else
> return ex_to<clifford>(e).get_representation_label();
> else {
> ex rl = _ex_1;
> for (size_t i=0; i < e.nops(); i++)
> rl = ex_to<numeric>(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<epvector> 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<numeric>(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);
More information about the GiNaC-devel
mailing list