[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