[GiNaC-devel] clifford patches
Vladimir Kisil
kisilv at maths.leeds.ac.uk
Tue Oct 5 19:38:03 CEST 2004
Dear All,
Here is a cumulative patch to clifford.cpp and
clifford.h. The previous version overlook a possibility of zero
expression in clifford_to_lst.
Best,
--
Vladimir V. Kisil email: kisilv at maths.leeds.ac.uk
-- www: http://maths.leeds.ac.uk/~kisilv/
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.
Some comments:
1. I set the default method in clifford_to_lst() to be algebraic since
its more mathematically transparent, but it seems to be by almost twice slower
than non-algebraic one. Thus moebius() use non-algebraic approach for speed.
2. I found that GiNaC always return expression
ex_to<varidx>(*it) as ".mu" even if in fact it is "~mu". Thus I used
the substitution argument like
lst(ex_to<varidx>(*it) == ival, ex_to<varidx>(*it).toggle_variance() == ival)
instead of a simple expression
ex_to<varidx>(*it) == ival
Probably this would be better to change to the expected behaviour.
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,1161
> /** 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
> int ival = ex_to<numeric>(ex_to<varidx>(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<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(lst(ex_to<varidx>(*it) == ival, ex_to<varidx>(*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<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, false);
> }
More information about the GiNaC-devel
mailing list