[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