[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