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@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);