[GiNaC-list] Geometric Algebra

Vladimir Kisil kisilv at maths.leeds.ac.uk
Wed Sep 28 19:26:19 CEST 2005


Alan Bromborsky (AB) wrote:
  AB>  To do this I must do a grade decomposition of multivectors. 

  I attach a sample program which defines a function to this end:

lst clifford_multi_decomp(const ex & e, const ex & c)

  For Clifford algebra in N dimensional space it returns a list of 2^n
coefficients in the standard Clifford algebra basis, i.e. element of the
list with the binary number 101 corresponds to e~2e~0, 110 -- to e~2e~1,
010 -- to e~1, etc. Please note, that the ordering of the units in the
poducts like e~2e~0 is determined by GiNaC in canonicalize_clifford()
procedure.

  Once clifford_multi_decomp() will be sufficiently tested I can prepare a
patch for its inclusion to the GiNaC core library.

      Best,
      	   Vladimir
--
Vladimir V. Kisil     email: kisilv at maths.leeds.ac.uk
--                      www: http://maths.leeds.ac.uk/~kisilv/

#include <stdexcept>
using namespace std;
#include <math.h>
#include <ginac/ginac.h>
using namespace GiNaC;

#define _ex2 numeric(2)

/* 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)
{
	// Remember whether the product was commutative or noncommutative
	// (because we chop it into factors and need to reassemble later)
	non_commutative = is_exactly_a<ncmul>(e);

	// Collect factors in an exvector, store squares twice
	v.reserve(e.nops() * 2);

	if (is_exactly_a<power>(e)) {
		// We only get called for simple squares, split a^2 -> a*a
		GINAC_ASSERT(e.op(1).is_equal(_ex2));
		v.push_back(e.op(0));
		v.push_back(e.op(0));
	} else {
		for (size_t i=0; i<e.nops(); i++) {
			ex f = e.op(i);
			if (is_exactly_a<power>(f) && f.op(1).is_equal(_ex2)) {
				v.push_back(f.op(0));
				v.push_back(f.op(0));
			} else if (is_exactly_a<ncmul>(f)) {
				// Noncommutative factor found, split it as well
				non_commutative = true; // everything becomes noncommutative, ncmul will sort out the commutative factors later
				for (size_t j=0; j<f.nops(); j++)
					v.push_back(f.op(j));
			} else
				v.push_back(f);
		}
	}
}

void product_to_blade(const ex & f, const ex & c, lst & res) {
	int  num = 0;
	// Collect factors in an exvector
	exvector v, s;
	unsigned char rl = ex_to<clifford>(c).get_representation_label();
	
	// 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(f, v, non_commutative);

	exvector::const_iterator cit = v.begin(), citend = v.end();
	while (cit != citend) {
		if (is_a<clifford>(*cit) && is_a<cliffordunit>(cit->op(0)) && (ex_to<clifford>(*cit).get_representation_label() == rl) 
			&& ex_to<clifford>(*cit).same_metric(c)) {
			if (ex_to<varidx>(cit->op(1)).is_numeric())
				num = num + (int)exp2(ex_to<numeric>(ex_to<varidx>(cit->op(1)).get_value()).to_int());
			else
				throw(std::invalid_argument("product_toblade(): cannot decompose into blades with symbolic indices"));
		} else if (is_a<ncmul>(*cit))
			product_to_blade(*cit, c, res);
		else
			s.push_back(*cit);
		cit++;
	}
	res.let_op(num) = res.op(num) + remove_dirac_ONE(non_commutative ? ex(ncmul(s)) : ex(mul(s)), rl);
}


lst clifford_multi_decomp(const ex & e, const ex & c) {
	if(!ex_to<varidx>(c.op(1)).is_dim_numeric())
		throw(std::invalid_argument("clifford_multi_decom (): cannot decompose into blades with symbolic dimension"));

	int D = ex_to<numeric>(ex_to<varidx>(c.op(1)).get_dim()).to_int();
	lst res;
	for(size_t i=0; i < exp2(D); i++)
		res.append(0);

	ex e_exp = canonicalize_clifford(expand_dummy_sum(e, true));

	if (is_a<mul>(e_exp) || is_a<ncmul>(e_exp))
		product_to_blade(e_exp, c, res);
	else if (is_a<add>(e_exp))
		for (size_t i=0; i < e_exp.nops(); i++)
			product_to_blade(e_exp.op(i), c, res);
	else
		throw(std::invalid_argument("clifford_multi_decom (): cannot decompose into blades this object"));

	return res;
}

int main() {
	realsymbol a("a"), s("s");
	symbol x("x"), y("y");
	varidx mu(symbol("mu"), 3),  nu(symbol("nu"), 3);
	ex M = diag_matrix(lst(-1,-1,s));
	ex c = clifford_unit(mu, M, 1);

	ex e; 
	e = 2*clifford_unit(varidx(1, 3), M, 1)+x*clifford_unit(varidx(1, 3), M)*clifford_unit(varidx(2, 3, 1), M);
	cout << clifford_multi_decomp(e, c) << endl  << endl;
	e = 2*a*dirac_gamma(varidx(2,3))*dirac_gamma(varidx(1,3))*
		clifford_unit(varidx(2,3), M, 1)*clifford_unit(varidx(1,3), M, 1)
		+x*clifford_unit(mu, M, 1)*clifford_unit(mu.toggle_variance(), M, 1)
		+clifford_unit(varidx(0,3), M, 1)*clifford_unit(varidx(1,3), M)
		+y*clifford_unit(mu, M, 1)*indexed(matrix(1,3,lst(1,-1,1)),mu.toggle_variance())
		+5*clifford_unit(varidx(0,3), M, 1)*clifford_unit(varidx(1,3), M, 1)*clifford_unit(varidx(2,3), M, 1);
	cout << clifford_multi_decomp(e, c) << endl  << endl;

}




More information about the GiNaC-list mailing list