[GiNaC-devel] clifford.cpp and ginac.texi patch

Vladimir Kisil kisilv at maths.leeds.ac.uk
Thu Oct 14 20:46:03 CEST 2004


		Dear All,

		I am sending once more patch to clifford.cpp. Now it closes all
  bugs which I was aware of in clifford_to_lst(). It also add some more
  flexibility to parameters of clifford_moebius_map(). 

  I think that it will be nice if  clifford_to_lst() can handle
  integrals and power series as well, but this requires some more includes to
  clifford.cpp. If there is no objection against it please uncomment
  this line in the patch:

  if (is_a<add>(e) || is_a<lst>(e) // || is_a<pseries>(e) ||  is_a<integral>(e)

  (and add includes by hands).

  I also finally wrote an addition to tutorial. This is my first
  experience with Texinfo, please feel free to edit it as you wish.

  Best wishes,
  Vladimir
-- 
Vladimir V. Kisil     email: kisilv at maths.leeds.ac.uk
--                      www: http://maths.leeds.ac.uk/~kisilv/


Index: doc/tutorial/ginac.texi
===================================================================
RCS file: /home/cvs/GiNaC/doc/tutorial/ginac.texi,v
retrieving revision 1.156
diff -r1.156 ginac.texi
2985a2986,2990
> 
> Clifford algebras are supported in two flavours: Dirac gamma
> matrices (more physical) and generic Clifford algebras (more
> mathematical). 
> 
2987,2990c2992,2997
< Clifford algebra elements (also called Dirac gamma matrices, although GiNaC
< doesn't treat them as matrices) are designated as @samp{gamma~mu} and satisfy
< @samp{gamma~mu*gamma~nu + gamma~nu*gamma~mu = 2*eta~mu~nu} where @samp{eta~mu~nu}
< is the Minkowski metric tensor. Dirac gammas are constructed by the function
---
> @subsubsection Dirac gamma matrices
> Dirac gamma matrices (note that GiNaC doesn't treat them
> as matrices) are designated as @samp{gamma~mu} and satisfy
> @samp{gamma~mu*gamma~nu + gamma~nu*gamma~mu = 2*eta~mu~nu} where
> @samp{eta~mu~nu} is the Minkowski metric tensor. Dirac gammas are
> constructed by the function
3161a3169,3321
> 
> @cindex @code{clifford_unit()}
> @subsubsection A generic Clifford algebra
> 
> A generic Clifford algebra, i.e. @math{2^n} dimensional algebra with
> generators @samp{e~k} satisfying the identities 
> @samp{e~i e~j+e~j e~i = B(i, j)} for some symmetric matrix (@code{metric})
> @math{B(i, j)}. Such generators are created by the function
> 
> @example
>     ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
> @end example
> 
> where @code{mu} should be @code{varidx} class object indexing the
> generators, @code{metr} defines the metric @math{B(i, j)} and can be
> represented by square @code{matrix}, @code{tensormetric} or @code{indexed} class
> object, optional parameter @code{rl} allows to distinguish different
> Clifford algebras (which will commute each other). Note that the call
> @code{clifford_unit(mu, minkmetric())} creates something very close to
> @code{dirac_gamma(mu)}. The method @code{clifford::get_metric()} returns
> metric defining this Clifford number.
> 
> Individual generators of a Clifford algebra can be accessed in several
> ways. For example 
> 
> @example
> @{
>     ... 
>     varidx nu(symbol(``nu''), 3);
>     matrix M(3, 3) = 1, 0, 0,
>                     0, -1, 0,
>                     0, 0, 0;
>     ex e = clifford_unit(nu, M);
>     ex e0 = e.subs(nu == 0);
>     ex e1 = e.subs(nu == 1);
>     ex e2 = e.subs(nu == 2);
>     ...
> @}
> @end example
> 
> will produce three generators of a Clifford algebra with properties
> @code{pow(e0, 2) = 1},  @code{pow(e1, 2) = -1} and   @code{pow(e2, 2) = 0}. 
> 
> @cindex @code{lst_to_clifford()}
> A similar effect can be achieved from the function
> 
> @example
>     ex lst_to_clifford(const ex & v, const ex & mu,  const ex & metr, unsigned char rl = 0);
> @end example
> 
> which converts a list or vector @code{v}@samp{ = (v~0, v~1, ..., v~n)} into
> the Clifford number @samp{v~0 e.0+v~1 e.1+... + v~n e.n} with @samp{e.k}
> being created by @code{clifford_unit(mu, metr, rl)}. The previous code
> may be rewritten with help of @code{lst_to_clifford()} as follows
> 
> @example
> @{
>     ...
>     varidx nu(symbol(``nu''), 3);
>     matrix M(3, 3) = 1, 0, 0,
>                     0, -1, 0,
>                     0, 0, 0;
>     ex e0 = lst_to_clifford(lst(1, 0, 0), nu, M);
>     ex e1 = lst_to_clifford(lst(0, 1, 0), nu, M);
>     ex e2 = lst_to_clifford(lst(0, 0, 1), nu, M);
>   ...
> @}
> @end example
> 
> @cindex @code{clifford_to_lst()}
> There is the inverse function 
> 
> @example
>     lst clifford_to_lst(const ex & e, const ex & c, bool algebraic = true);
> @end example
> 
> which took an expression @code{e} and tries to find such a list
> @code{v}@samp{ = (v~0, v~1, ..., v~n)} that @samp{e = v~0c.0 + v~1c.1 + ...
> + v~nc.n} with respect to given Clifford units @code{c} and none of
> @samp{v~k} contains the Clifford units @code{c} (of course, this
> may be impossible). This function can use an @code{algebraic} method
> (default) or a symbolic one. In @code{algebraic} method @samp{v~k} are calculated as
> @samp{(e c.k + c.k e)/pow(c.k, 2)}.  If @samp{pow(c.k, 2) = 0} for some @samp{k}
> then the method will be automatically changed to symbolic. The same effect
> is obtained by the assignment (@code{algebraic = false}) in the procedure call.
> 
> @cindex @code{clifford_prime()}
> @cindex @code{clifford_star()}
> @cindex @code{clifford_bar()}
> There are several functions for (anti-)automorphisms of Clifford algebras:
> 
> @example
>     ex clifford_prime(const ex & e)
>     inline ex clifford_star(const ex & e) @{ return e.conjugate(); @} 
>     inline ex clifford_bar(const ex & e) @{ return   clifford_prime(e.conjugate()); @}
> @end example
> 
> The automorphism of a Clifford algebra @code{clifford_prime()} simply
> changes signs of all Clifford units in the expression. The reversion
> of a Clifford algebra @code{clifford_star()} coincides with
> @code{conjugate()} method and effectively reverses the order of Clifford
> units in any product. Finally the main anti-automorphism
> of a Clifford algebra @code{clifford_bar()} is the composition of two
> previous, i.e. makes the reversion and changes signs of all Clifford units
> in a product. Names for this functions corresponds to notations
> @math{e'}, @math{e^*} and @math{\bar{e}} used in Clifford algebra
> textbooks.
> 
> @cindex @code{clifford_norm()}
> The function
> 
> @example
>     ex clifford_norm(const ex & e);
> @end example
> 
> @cindex @code{clifford_inverse()}
> calculates the  norm of Clifford number from the expression
> @math{||e||^2 = e\bar{e}}. The inverse of a Clifford expression is returned
> by the function
> 
> @example
>     ex clifford_inverse(const ex & e);
> @end example
> 
> which calculates it as @math{e^{-1} = e/||e||^2}. If @math{||e|| = 0} then an
> exception is raised.
> 
> @cindex @code{remove_dirac_ONE()}
> If a Clifford number happens to be a factor of
> @code{dirac_ONE()} then we can convert it to a ``real'' (non-Clifford)
> expression by the function
> 
> @example
>     ex remove_dirac_ONE(const ex & e);
> @end example
> 
> @cindex @code{canonicalize_clifford()}
> The function @code{canonicalize_clifford()} works for a
> generic Clifford algebra in a similar way as for Dirac gammas.
> 
> The last provided function is
> 
> @cindex @code{clifford_moebius_map()}
> @example
>     ex clifford_moebius_map(const ex & a, const ex & b, const ex & c,   const ex & d, const ex & v, const ex & G);
> @end example 
> 
> It takes a list or vector @code{v} and makes the Moebius
> (conformal or linear-fractional) transformation @samp{v ->
> (av+b)/(cv+d)} defined by the matrix @samp{[[a, b], [c, d]]}. The last
> parameter @code{G} define the metric of the surrounding
> (pseudo-)Euclidean space. The returned value of this function is a list
> of components of the resulting vector.
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.80
diff -r1.80 clifford.cpp
1080a1081
> 	int ival = ex_to<numeric>(ex_to<varidx>(c.op(1)).get_value()).to_int();
1082c1083,1084
< 	if (is_a<add>(e)) 
---
> 	if (is_a<add>(e) || is_a<lst>(e) // || is_a<pseries>(e) || is_a<integral>(e)
> 		|| is_a<matrix>(e)) 
1086d1087
< 		int ival = ex_to<numeric>(ex_to<varidx>(c.op(1)).get_value()).to_int();
1095a1097,1100
> 			bool same_value_index, found_dummy;
> 			same_value_index = ( ex_to<varidx>(e.op(ind).op(1)).is_numeric()
> 								 &&  (ival == ex_to<numeric>(ex_to<varidx>(e.op(ind).op(1)).get_value()).to_int()) );
> 			found_dummy  = same_value_index;
1097,1105c1102,1103
< 				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
---
> 				if (j != ind) 
> 					if (same_value_index) 
1107,1108c1105,1117
< 				}
< 			return S;
---
> 					else {
> 						exvector ind_vec = ex_to<indexed>(e.op(j)).get_dummy_indices(ex_to<indexed>(e.op(ind)));
> 						if (ind_vec.size() > 0) {
> 							found_dummy = true;
> 							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 (found_dummy? S : 0);
1113c1122,1128
< 	else 
---
> 	else if (is_a<clifford>(e))
> 		if ( ex_to<varidx>(e.op(1)).is_numeric() &&
> 			 (ival != ex_to<numeric>(ex_to<varidx>(e.op(1)).get_value()).to_int()) )
> 			return 0;
> 		else 
> 			return 1;
> 	else
1115d1129
< 	
1150c1164,1166
< 		D = ex_to<varidx>(G.op(1));
---
> 		D = ex_to<varidx>(G.op(1)).get_dim();
> 	else if (is_a<matrix>(G)) 
> 		D = ex_to<matrix>(G).rows();
1152c1168
< 		throw(std::invalid_argument("metric should be an indexed object"));
---
> 		throw(std::invalid_argument("metric should be an indexed object or matrix"));
1154c1170
< 	varidx mu ((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(D).get_dim());
---
> 	varidx mu ((new symbol)->setflag(status_flags::dynallocated), D);
1157a1174
> 



More information about the GiNaC-devel mailing list