Dear All, I wish to propose a further patches for clifford.cpp and clifford.h. Its make: 1. Fixes a nasty behaviour when a simplification creates nested indexed objects like (eta.psi.xi).nu.mu. 2. Contains two new functions described in the clifford.h. Hope they will be useful, at least I employ them to create some graphics of conformal maps already. 3. Other bits are small improvements and spaces fixed. I hope to contribute some documentation for expanded clifford.cpp as well. Best wishes, Vladimir -- Vladimir V. Kisil email: kisilv@maths.leeds.ac.uk -- www: http://maths.leeds.ac.uk/~kisilv/ Index: ginac/clifford.h =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.h,v retrieving revision 1.51 diff -r1.51 clifford.h 278c278 < ex delete_ONE(const ex &e); ---
ex delete_ONE(const ex & e); 294a295,318 /** 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 expresion 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 algorythm 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 buid 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 moebius(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G); Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.79 diff -r1.79 clifford.cpp 680c680,685 < return clifford(unit, mu, metr, rl);
if (is_a<indexed>(metr)) return clifford(unit, mu, metr.op(0), rl); else if(is_a<tensmetric>(metr) || is_a<matrix>(metr)) return clifford(unit, mu, metr, rl); else throw(std::invalid_argument("metric for Clifford unit must be of type indexed, tensormetric or matrix")); 990c995 < ex clifford_prime(const ex &e)
ex clifford_prime(const ex & e) 1005c1010 < ex delete_ONE(const ex &e)
ex delete_ONE(const ex & e) 1022c1027 < ex clifford_norm(const ex &e)
ex clifford_norm(const ex & e) 1024c1029 < return sqrt(delete_ONE((e * clifford_bar(e)).simplify_indexed()));
return sqrt(delete_ONE(canonicalize_clifford(e * clifford_bar(e)).simplify_indexed())); 1027c1032 < ex clifford_inverse(const ex &e)
ex clifford_inverse(const ex & e) 1031a1037,1038 else throw(std::invalid_argument("Cannot find inverse of Clifford number with zero norm!")); 1068a1076,1158 /** Auxiliary structure to define a function for striping one Clifford unit * from vectors. Used in clifford_to_lst(). */ ex get_clifford_comp(const ex & e, const ex & c) { pointer_to_map_function_1arg<const ex &> fcn(get_clifford_comp, c);
if (is_a<add>(e)) return e.map(fcn); else if (is_a<ncmul>(e) || is_a<mul>(e)) { //find a Clifford unit with the same metric, delete it and substitute its index size_t ind = e.nops() + 1; for (size_t j = 0; j < e.nops(); j++) if (is_a<clifford>(e.op(j)) && ex_to<clifford>(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<indexed>(e.op(j)).get_dummy_indices(ex_to<indexed>(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(ex_to<varidx>(*it) == ex_to<idx>(c.op(1)).get_value()); 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 { 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<clifford>(c)); varidx mu = ex_to<varidx>(c.op(1)); if (! mu.is_dim_numeric()) throw(std::invalid_argument("Index should have a numeric dimension")); unsigned int D = ex_to<numeric>(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(delete_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 moebius(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G) { ex x, D; if (is_a<indexed>(G)) D = ex_to<varidx>(G.op(1)); else throw(std::invalid_argument("metric should be an indexed object"));
varidx mu ((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(D).get_dim());
if (! is_a<matrix>(v) && ! is_a<lst>(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); }
participants (1)
-
Vladimir Kisil