From b4631c1661b1945c85b3ea2e8ce1d3e58d1e6e79 Mon Sep 17 00:00:00 2001 From: Jens Vollinga Date: Tue, 12 Oct 2004 13:35:18 +0000 Subject: [PATCH] Various bug-fixes and enhancements (new moebius transformation). --- ginac/clifford.cpp | 113 +++++++++++++++++++++++++++++++++++++++++---- ginac/clifford.h | 27 ++++++++++- 2 files changed, 130 insertions(+), 10 deletions(-) diff --git a/ginac/clifford.cpp b/ginac/clifford.cpp index b2e56224..da638b2c 100644 --- a/ginac/clifford.cpp +++ b/ginac/clifford.cpp @@ -402,7 +402,7 @@ bool cliffordunit::contract_with(exvector::iterator self, exvector::iterator oth // Find if a previous contraction produces the square of self int prev_square = find_same_metric(v, self[0]); - varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to(ex_to(self->op(1)).get_dim())); + varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to(self->op(1)).get_dim()); ex squared_metric = unit.get_metric(self->op(1), d) * unit.get_metric(d.toggle_variance(), other->op(1)); // e~mu e.mu = Tr ONE @@ -677,7 +677,12 @@ ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl) if (!is_a(mu)) throw(std::invalid_argument("index of Clifford unit must be of type varidx")); - return clifford(unit, mu, metr, rl); + if (is_a(metr)) + return clifford(unit, mu, metr.op(0), rl); + else if(is_a(metr) || is_a(metr)) + return clifford(unit, mu, metr, rl); + else + throw(std::invalid_argument("metric for Clifford unit must be of type indexed, tensormetric or matrix")); } ex dirac_gamma(const ex & mu, unsigned char rl) @@ -987,7 +992,7 @@ next_sym: ; return aux.subs(srl, subs_options::no_pattern).simplify_indexed(); } -ex clifford_prime(const ex &e) +ex clifford_prime(const ex & e) { pointer_to_map_function fcn(clifford_prime); if (is_a(e) && is_a(e.op(0))) { @@ -1002,9 +1007,9 @@ ex clifford_prime(const ex &e) return e; } -ex delete_ONE(const ex &e) +ex remove_dirac_ONE(const ex & e) { - pointer_to_map_function fcn(delete_ONE); + pointer_to_map_function fcn(remove_dirac_ONE); if (is_a(e) && is_a(e.op(0))) { return 1; } else if (is_a(e)) { @@ -1014,21 +1019,23 @@ ex delete_ONE(const ex &e) } else if (is_a(e)) { return e.map(fcn); } else if (is_a(e)) { - return pow(delete_ONE(e.op(0)), e.op(1)); + return pow(remove_dirac_ONE(e.op(0)), e.op(1)); } else return e; } -ex clifford_norm(const ex &e) +ex clifford_norm(const ex & e) { - return sqrt(delete_ONE((e * clifford_bar(e)).simplify_indexed())); + return sqrt(remove_dirac_ONE(canonicalize_clifford(e * clifford_bar(e)).simplify_indexed())); } -ex clifford_inverse(const ex &e) +ex clifford_inverse(const ex & e) { ex norm = clifford_norm(e); if (!norm.is_zero()) return clifford_bar(e) / pow(norm, 2); + else + throw(std::invalid_argument("Cannot find inverse of Clifford number with zero norm!")); } ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl) @@ -1066,4 +1073,92 @@ ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char r throw(std::invalid_argument("Cannot construct from anything but list or vector")); } +/** Auxiliary structure to define a function for striping one Clifford unit + * from vectors. Used in clifford_to_lst(). */ +static ex get_clifford_comp(const ex & e, const ex & c) +{ + pointer_to_map_function_1arg fcn(get_clifford_comp, c); + + if (is_a(e)) + return e.map(fcn); + else if (is_a(e) || is_a(e)) { + //find a Clifford unit with the same metric, delete it and substitute its index + int ival = ex_to(ex_to(c.op(1)).get_value()).to_int(); + size_t ind = e.nops() + 1; + for (size_t j = 0; j < e.nops(); j++) + if (is_a(e.op(j)) && ex_to(c).same_metric(e.op(j))) + if (ind > e.nops()) + ind = j; + else + throw(std::invalid_argument("Expression is a Clifford multi-vector")); + if (ind < e.nops()) { + ex S = 1; + for(size_t j=0; j < e.nops(); j++) + if (j != ind) { + exvector ind_vec = ex_to(e.op(j)).get_dummy_indices(ex_to(e.op(ind))); + if (ind_vec.size() > 0) { + exvector::const_iterator it = ind_vec.begin(), itend = ind_vec.end(); + while (it != itend) { + S = S * e.op(j).subs(lst(ex_to(*it) == ival, ex_to(*it).toggle_variance() == ival), subs_options::no_pattern); + it++; + } + } else + S = S * e.op(j); + } + return S; + } else + throw(std::invalid_argument("Expression is not a Clifford vector to the given units")); + } else if (e.is_zero()) + return e; + else + throw(std::invalid_argument("Expression is not handlable as a Clifford vector")); + +} + + +lst clifford_to_lst (const ex & e, const ex & c, bool algebraic) +{ + GINAC_ASSERT(is_a(c)); + varidx mu = ex_to(c.op(1)); + if (! mu.is_dim_numeric()) + throw(std::invalid_argument("Index should have a numeric dimension")); + unsigned int D = ex_to(mu.get_dim()).to_int(); + + if (algebraic) // check if algebraic method is applicable + for (unsigned int i = 0; i < D; i++) + if (pow(c.subs(mu == i), 2) == 0) + algebraic = false; + lst V; + if (algebraic) + for (unsigned int i = 0; i < D; i++) + V.append(remove_dirac_ONE( + simplify_indexed(canonicalize_clifford(e * c.subs(mu == i) + c.subs(mu == i) * e)) + / (2*pow(c.subs(mu == i), 2)))); + else { + ex e1 = canonicalize_clifford(e); + for (unsigned int i = 0; i < D; i++) + V.append(get_clifford_comp(e1, c.subs(c.op(1) == i))); + } + return V; +} + + +ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G) +{ + ex x, D; + if (is_a(G)) + D = ex_to(G.op(1)); + else + throw(std::invalid_argument("metric should be an indexed object")); + + varidx mu ((new symbol)->setflag(status_flags::dynallocated), ex_to(D).get_dim()); + + if (! is_a(v) && ! is_a(v)) + throw(std::invalid_argument("parameter v should be either vector or list")); + + x = lst_to_clifford(v, mu, G); + ex e = simplify_indexed(canonicalize_clifford((a * x + b) * clifford_inverse(c * x + d))); + ex cu = clifford_unit(mu, G); + return clifford_to_lst(e, cu, false); +} } // namespace GiNaC diff --git a/ginac/clifford.h b/ginac/clifford.h index 81abd9f5..d68a18bf 100644 --- a/ginac/clifford.h +++ b/ginac/clifford.h @@ -275,7 +275,8 @@ inline ex clifford_bar(const ex & e) { return clifford_prime(e.conjugate()); } /** Reversion of the Clifford algebra, coincides with the conjugate(). */ inline ex clifford_star(const ex & e) { return e.conjugate(); } -ex delete_ONE(const ex &e); +/** Replaces all dirac_ONE's in e with 1 (effectively removing them). */ +ex remove_dirac_ONE(const ex & e); /** Calculation of the norm in the Clifford algebra. */ ex clifford_norm(const ex & e); @@ -292,6 +293,30 @@ ex clifford_inverse(const ex & e); * @return Clifford vector with given components */ ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0); +/** An inverse function to lst_to_clifford(). For given Clifford vector extracts + * its components with respect to given Clifford unit. Obtained components may + * contain Clifford units with a different metric. Extraction is based on + * the algebraic formula (e * c.i + c.i * e)/ pow(e.i, 2) for non-degenerate cases + * (i.e. neither pow(e.i, 2) = 0). + * + * @param e Clifford expression to be decomposed into components + * @param c Clifford unit defining the metric for splitting (should have numeric dimension of indices) + * @param algebraic Use algebraic or symbolic algorithm for extractions */ +lst clifford_to_lst(const ex & e, const ex & c, bool algebraic=true); + +/** Calculations of Moebius transformations (conformal map) defined by a 2x2 Clifford matrix + * (a b\\c d) in linear spaces with arbitrary signature. The expression is + * (a * x + b)/(c * x + d), where x is a vector build from list v with metric G. + * (see Jan Cnops. An introduction to {D}irac operators on manifolds, v.24 of + * Progress in Mathematical Physics. Birkhauser Boston Inc., Boston, MA, 2002.) + * + * @param a (1,1) entry of the defining matrix + * @param b (1,2) entry of the defining matrix + * @param c (2,1) entry of the defining matrix + * @param d (2,2) entry of the defining matrix + * @param v Vector to be transformed + * @param G Metric of the surrounding space */ +ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G); } // namespace GiNaC #endif // ndef __GINAC_CLIFFORD_H__ -- 2.31.1