[GiNaC-devel] Extending clifford.cpp

Vladimir Kisil kisilv at maths.leeds.ac.uk
Fri May 19 17:47:26 CEST 2006


		Dear All,

		I discovered recently that it is not easy to create a Clifford
  unit in the Euclidean space with symbolic dimension. The natural
  attempt was to supply -tensdelta as the metric, however when GiNaC
  wrap it into an indexed object it automatically put minus outside of
  it. Then the result is of type mul, not indexed, as was previously
  assumed in clifford.cpp. 

  Summing up: the previous assumption that metric of clifford units can
  and should be always an indexed object is rather
  restrictive. Fortunately, it was not difficult to patch clifford.cpp
  to work without this assumption. I include the patch as well as extend
  the exam_clifford.cpp to check such cases as well. I also add a word
  into the tutorial about this new possibility.

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

-------------- next part --------------
/home/amsta/kisilv/GiNaC
Index: doc/tutorial/ginac.texi
===================================================================
RCS file: /home/cvs/GiNaC/doc/tutorial/ginac.texi,v
retrieving revision 1.186
diff -u -r1.186 ginac.texi
--- doc/tutorial/ginac.texi	16 May 2006 15:27:20 -0000	1.186
+++ doc/tutorial/ginac.texi	19 May 2006 15:41:41 -0000
@@ -3307,7 +3307,11 @@
 @code{idx} as well.
 Parameter @code{metr} defines the metric @math{M(i, j)} and can be
 represented by a square @code{matrix}, @code{tensormetric} or @code{indexed} class
-object. Optional parameter @code{rl} allows to distinguish different
+object. In fact, any expression either with two free indices or without
+indices at all is admitted as @code{metr}. In the later case an @code{indexed}
+object with two newly created indices with @code{metr} as its
+ at code{op(0)} will be used.
+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.
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.96
diff -u -r1.96 clifford.cpp
--- ginac/clifford.cpp	16 May 2006 15:27:21 -0000	1.96
+++ ginac/clifford.cpp	19 May 2006 15:41:41 -0000
@@ -158,29 +158,39 @@
 	if (is_a<indexed>(metric)) {
 		if (symmetrised && !(ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()).has_symmetry())) {
 			if (is_a<matrix>(metric.op(0))) {
-				return indexed((ex_to<matrix>(metric.op(0)).add(ex_to<matrix>(metric.op(0)).transpose())).mul(numeric(1,2)),
+				return indexed((ex_to<matrix>(metric.op(0)).add(ex_to<matrix>(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<symmetry>(ex_to<indexed>(metric).get_symmetry()), i, j);
 			return metric.subs(lst(metric.op(1) == i, metric.op(2) == j), subs_options::no_pattern);
 		}
 	} else {
-		// should not really happen since all constructors but clifford() make the metric an indexed object
-		return indexed(metric, i, j);
+		exvector indices = metric.get_free_indices();
+		if (symmetrised)
+			return _ex1_2*simplify_indexed(metric.subs(lst(indices[0] == i, indices[1] == j), subs_options::no_pattern)
+									+ metric.subs(lst(indices[0] == j, indices[1] == i), subs_options::no_pattern));
+		else
+			return metric.subs(lst(indices[0] == i, indices[1] == j), subs_options::no_pattern);
 	}
 }
 
 bool clifford::same_metric(const ex & other) const
 {
-	if (is_a<clifford>(other)) {
-		return same_metric(ex_to<clifford>(other).get_metric());
-	} else if (is_a<indexed>(other)) {
-		return get_metric(other.op(1), other.op(2)).is_equal(other);
-	} else
-		return false;
+	ex metr;
+	if (is_a<clifford>(other)) 
+		metr = ex_to<clifford>(other).get_metric();
+	else 
+		metr = other;
+
+	if (is_a<indexed>(metr))
+		return metr.op(0).is_equal(get_metric().op(0));
+	else {
+		exvector indices = metr.get_free_indices();
+		return  (indices.size() == 2) 
+			&& simplify_indexed(get_metric(indices[0], indices[1])-metr).is_zero();
+	}
 }
 
 //////////
@@ -436,7 +446,7 @@
 		    && ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[1])
 		    || (ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[0]
 		    && ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[1]))) {
-			return i; // the index of the found
+			return i; // the index of the found term
 		}
 	}
 	return -1; //nothing found
@@ -758,17 +768,10 @@
 	if (ex_to<idx>(mu).is_symbolic() && !is_a<varidx>(mu))
 		throw(std::invalid_argument("clifford_unit(): symbolic index of Clifford unit must be of type varidx (not idx)"));
 
-	if (is_a<indexed>(metr)) {
-		exvector indices = ex_to<indexed>(metr).get_indices();
-		if ((indices.size() == 2) && is_a<varidx>(indices[0]) && is_a<varidx>(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<tensor>(metr)) {
-		static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
-			chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
-		return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting);
+	exvector indices = metr.get_free_indices();
+
+	if ((indices.size() == 2) && is_a<varidx>(indices[0]) && is_a<varidx>(indices[1])) {
+		return clifford(unit, mu, metr, rl, anticommuting);
 	} else if (is_a<matrix>(metr)) {
 		matrix M = ex_to<matrix>(metr);
 		unsigned n = M.rows();
@@ -792,9 +795,12 @@
 		} 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, tensor or matrix"));
-	}
+	} else if (indices.size() == 0) { // a tensor or other expression without indices
+		static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
+			chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
+		return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting);
+	}  else 
+		throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type tensor, matrix or an expression with two free indices"));
 }
 
 ex dirac_gamma(const ex & mu, unsigned char rl)
Index: check/exam_clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/check/exam_clifford.cpp,v
retrieving revision 1.29
diff -u -r1.29 exam_clifford.cpp
--- check/exam_clifford.cpp	19 Jan 2006 16:37:16 -0000	1.29
+++ check/exam_clifford.cpp	19 May 2006 15:41:41 -0000
@@ -457,13 +457,10 @@
 	varidx mu(symbol("mu"), dim), nu(symbol("nu"), dim), rho(symbol("rho"), dim),
 	       psi(symbol("psi"),dim), lam(symbol("lambda"), dim), xi(symbol("xi"), dim);
 
-	ex e, G_base;
-
-	if (is_a<indexed>(G))
-		G_base = G.op(0);
-	else
-		G_base = G;
-
+	ex e;
+	clifford unit = ex_to<clifford>(clifford_unit(mu, G));
+	ex scalar = unit.get_metric(varidx(0, dim), varidx(0, dim));
+	
 	e = dirac_ONE() * dirac_ONE();
 	result += check_equal(e, dirac_ONE());
 
@@ -472,25 +469,25 @@
 
 	e = clifford_unit(varidx(2, dim), G) * clifford_unit(varidx(1, dim), G)
 	  * clifford_unit(varidx(1, dim), G) * clifford_unit(varidx(2, dim), G);
-	result += check_equal(e, dirac_ONE());
+	result += check_equal(e, dirac_ONE()*pow(scalar, 2));
 
 	e = clifford_unit(mu, G) * clifford_unit(nu, G)
 	  * clifford_unit(nu.toggle_variance(), G) * clifford_unit(mu.toggle_variance(), G);
-	result += check_equal_simplify(e, pow(dim, 2) * dirac_ONE());
+	result += check_equal_simplify(e, pow(dim*scalar, 2) * dirac_ONE());
 
 	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*dim*dirac_ONE() - pow(dim, 2)*dirac_ONE());
+	result += check_equal_simplify(e, (2*dim - pow(dim, 2))*pow(scalar,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(2 - dim, 2).expand() * clifford_unit(mu, G));
+	result += check_equal(e, pow(scalar*(dim-2), 2).expand() * clifford_unit(mu, G));
 
 	// canonicalize_clifford() checks, only for symmetric metrics
 	if (ex_to<symmetry>(ex_to<indexed>(ex_to<clifford>(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));
+		result += check_equal(canonicalize_clifford(e), 2*dirac_ONE()*unit.get_metric(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)
@@ -498,14 +495,14 @@
 			 - 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)
+			+ unit.get_metric(mu, nu) * clifford_unit(lam, G)
+			- unit.get_metric(mu, lam) * clifford_unit(nu, G)
+			+ unit.get_metric(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)));
+		result += check_equal(canonicalize_clifford(e), dirac_ONE()*(unit.get_metric(mu, nu) + unit.get_metric(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)
@@ -513,9 +510,9 @@
 			 - 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)
+			+ half * (unit.get_metric(mu, nu) + unit.get_metric(nu, mu)) * clifford_unit(lam, G)
+			- half * (unit.get_metric(mu, lam) + unit.get_metric(lam, mu)) * clifford_unit(nu, G)
+			+ half * (unit.get_metric(nu, lam) + unit.get_metric(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);
 	}
@@ -580,8 +577,13 @@
 	result += clifford_check7(minkmetric(), dim); cout << '.' << flush;
 
 	varidx chi(symbol("chi"), dim), xi(symbol("xi"), dim);
+	result += clifford_check7(delta_tensor(xi, chi), dim); cout << '.' << flush;
+
 	result += clifford_check7(lorentz_g(xi, chi), dim); cout << '.' << flush;
 
+	result += clifford_check7(indexed(-2*minkmetric(), sy_symm(), xi, chi), dim); cout << '.' << flush;
+	result += clifford_check7(-2*delta_tensor(xi, chi), dim); cout << '.' << flush;
+
 	if (!result) {
 		cout << " passed " << endl;
 		clog << "(no output)" << endl;


More information about the GiNaC-devel mailing list