From: Chris Dams Date: Wed, 24 May 2006 19:04:18 +0000 (+0000) Subject: Allow for more general expressions for clifford metrics. Patch by Vladimir. X-Git-Tag: release_1-4-0~88 X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=commitdiff_plain;h=aa378587448168767c40dcfc4c819d2893fc24a5 Allow for more general expressions for clifford metrics. Patch by Vladimir. --- diff --git a/check/exam_clifford.cpp b/check/exam_clifford.cpp index 53b57906..5a365d33 100644 --- a/check/exam_clifford.cpp +++ b/check/exam_clifford.cpp @@ -457,13 +457,10 @@ static unsigned clifford_check7(const ex & G, const symbol & dim) 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(G)) - G_base = G.op(0); - else - G_base = G; - + ex e; + clifford unit = ex_to(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 @@ static unsigned clifford_check7(const ex & G, const symbol & dim) 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(ex_to(ex_to(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 @@ static unsigned clifford_check7(const ex & G, const symbol & dim) - 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 @@ static unsigned clifford_check7(const ex & G, const symbol & dim) - 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 @@ unsigned exam_clifford() 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; diff --git a/doc/tutorial/ginac.texi b/doc/tutorial/ginac.texi index 76c20742..26f004ed 100644 --- a/doc/tutorial/ginac.texi +++ b/doc/tutorial/ginac.texi @@ -3307,7 +3307,11 @@ generators, an index @code{mu} with a numeric value may be of type @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 +@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. diff --git a/ginac/clifford.cpp b/ginac/clifford.cpp index e306be8e..97b503b8 100644 --- a/ginac/clifford.cpp +++ b/ginac/clifford.cpp @@ -158,29 +158,39 @@ ex clifford::get_metric(const ex & i, const ex & j, bool symmetrised) const if (is_a(metric)) { if (symmetrised && !(ex_to(ex_to(metric).get_symmetry()).has_symmetry())) { if (is_a(metric.op(0))) { - return indexed((ex_to(metric.op(0)).add(ex_to(metric.op(0)).transpose())).mul(numeric(1,2)), + return indexed((ex_to(metric.op(0)).add(ex_to(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(ex_to(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(other)) { - return same_metric(ex_to(other).get_metric()); - } else if (is_a(other)) { - return get_metric(other.op(1), other.op(2)).is_equal(other); - } else - return false; + ex metr; + if (is_a(other)) + metr = ex_to(other).get_metric(); + else + metr = other; + + if (is_a(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 @@ static int find_same_metric(exvector & v, ex & c) && ex_to(c.op(1)) == ex_to(v[i]).get_indices()[1]) || (ex_to(c.op(1)).toggle_variance() == ex_to(v[i]).get_indices()[0] && ex_to(c.op(1)).toggle_variance() == ex_to(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 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticomm if (ex_to(mu).is_symbolic() && !is_a(mu)) throw(std::invalid_argument("clifford_unit(): symbolic index of Clifford unit must be of type varidx (not idx)")); - if (is_a(metr)) { - exvector indices = ex_to(metr).get_indices(); - if ((indices.size() == 2) && is_a(indices[0]) && is_a(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(metr)) { - static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to(mu).get_dim()), - chi((new symbol)->setflag(status_flags::dynallocated), ex_to(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(indices[0]) && is_a(indices[1])) { + return clifford(unit, mu, metr, rl, anticommuting); } else if (is_a(metr)) { matrix M = ex_to(metr); unsigned n = M.rows(); @@ -792,9 +795,12 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticomm } 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(mu).get_dim()), + chi((new symbol)->setflag(status_flags::dynallocated), ex_to(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)