[GiNaC-devel] Patches for clifford (cumulative)

Vladimir Kisil kisilv at maths.leeds.ac.uk
Tue Mar 29 13:34:13 CEST 2005


		Dear All,

		Here is a cumulative patch for clifford.cpp and related
  files. New features:
  
  1. clifford_to_lst() now checks that all e_j^2 are non zero and
  numeric in order to allow the algebraic method. For symbolic
  (non-numeric) values of e_j^2 later substitutions may produce a
  division by zero for algebraic answer.
  
  2. Further documentation improvement.

  This patch includes my previous patch from Feb 23 12:19:32 and Chris
  Dams patch from Mar 21 14:46:17. However I slightly altered Chris'
  addition by pushing the simplify_indexed() down after
  canonicalize_clifford() maps itself into all lists or matrices (since
  simplify_indexed() does not do it itself).

  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.162
diff -r1.162 ginac.texi
3178,3181c3178,3190
< generators @samp{e~k} satisfying the identities 
< @samp{e~i e~j + e~j e~i = B(i, j)} for some matrix (@code{metric})
< @math{B(i, j)}, which may be non-symmetric. Such generators are created
< by the function
---
> generators 
> @tex $e_k$
> @end tex 
> satisfying the identities 
> @tex
> $e_i e_j + e_j e_i = M(i, j) $
> @end tex
> @ifnottex
> e~i e~j + e~j e~i = M(i, j)
> @end ifnottex
> for some matrix (@code{metric})
> @math{M(i, j)}, which may be non-symmetric and containing symbolic
> entries. Such generators are created by the function
3188c3197
< generators, @code{metr} defines the metric @math{B(i, j)} and can be
---
> generators, @code{metr} defines the metric @math{M(i, j)} and can be
3196c3205
< If the matrix @math{B(i, j)} is in fact symmetric you may prefer to create
---
> If the matrix @math{M(i, j)} is in fact symmetric you may prefer to create
3200c3209
<     ex e = clifford_unit(mu, indexed(B, sy_symm(), i, j));
---
>     ex e = clifford_unit(mu, indexed(M, sy_symm(), i, j));
3211,3214c3220,3225
<     varidx nu(symbol("nu"), 3);
<     matrix M(3, 3) = 1, 0, 0,
<                      0,-1, 0,
<                      0, 0, 0;
---
>     varidx nu(symbol("nu"), 4);
>     realsymbol s("s");
>     matrix M(4, 4) = 1, 0, 0, 0,
>                      0,-1, 0, 0,
>                      0, 0, 0, 0,
>                      0, 0, 0, s;
3218a3230
>     ex e3 = e.subs(nu == 3);
3223,3224c3235,3241
< 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}. 
---
> will produce four generators of a Clifford algebra with properties
> @tex
> $e_0^2=1 $, $e_1^2=-1$,  $e_2^2=0$ and $e_3^2=s$.
> @end tex
> @ifnottex
> @code{pow(e0, 2) = 1},  @code{pow(e1, 2) = -1},   @code{pow(e2, 2) = 0} and   @code{pow(e3, 2) = s}. 
> @end ifnottex
3231a3249
>     ex lst_to_clifford(const ex & v, const ex & e);
3234,3237c3252,3271
< which converts a list or vector @samp{v = (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 the help of @code{lst_to_clifford()} as follows
---
> which converts a list or vector 
> @tex
> $v = (v^0, v^1, ..., v^n)$
> @end tex
> @ifnottex
> @samp{v = (v~0, v~1, ..., v~n)} 
> @end ifnottex
> into the
> Clifford number 
> @tex
> $v^0 e_0 + v^1 e_1 + ... + v^n e_n$
> @end tex
> @ifnottex
> @samp{v~0 e.0 + v~1 e.1 + ... + v~n e.n}
> @end ifnottex
> with @samp{e.k}
> directly supplied in the second form of the procedure. In the first form
> the Clifford unit @samp{e.k} is generated by the call of
> @code{clifford_unit(mu, metr, rl)}. The previous code may be rewritten
> with the help of @code{lst_to_clifford()} as follows
3242,3248c3276,3285
<     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);
---
>     varidx nu(symbol("nu"), 4);
>     realsymbol s("s");
>     matrix M(4, 4) = 1, 0, 0, 0,
>                      0,-1, 0, 0,
>                      0, 0, 0, 0,
>                      0, 0, 0, s;
>     ex e0 = lst_to_clifford(lst(1, 0, 0, 0), nu, M);
>     ex e1 = lst_to_clifford(lst(0, 1, 0, 0), nu, M);
>     ex e2 = lst_to_clifford(lst(0, 0, 1, 0), nu, M);
>     ex e3 = lst_to_clifford(lst(0, 0, 0, 1), nu, M);
3261,3262c3298,3311
< @samp{v = (v~0, v~1, ..., v~n)} such that @samp{e = v~0 c.0 + v~1 c.1 + ...
< + v~n c.n} with respect to the given Clifford units @code{c} and none of
---
> @tex
> $v = (v^0, v^1, ..., v^n)$
> @end tex
> @ifnottex
> @samp{v = (v~0, v~1, ..., v~n)} 
> @end ifnottex
> such that 
> @tex
> $e = v^0 c_0 + v^1 c_1 + ... + v^n c_n$
> @end tex
> @ifnottex
> @samp{e = v~0 c.0 + v~1 c.1 + ... + v~n c.n}
> @end ifnottex
> with respect to the given Clifford units @code{c} and none of
3266c3315,3321
< @samp{(e c.k + c.k e)/pow(c.k, 2)}.  If @samp{pow(c.k, 2) = 0} for some @samp{k}
---
> @tex
> $(e c_k + c_k e)/c_k^2$. If $c_k^2$
> @end tex
> @ifnottex
> @samp{(e c.k + c.k e)/pow(c.k, 2)}.   If @samp{pow(c.k, 2)} 
> @end ifnottex
> is zero or is not a @code{numeric} for some @samp{k}
3292a3348,3350
> @ifnottex
> e*
> @end ifnottex
3296a3355,3357
> @ifnottex
> @code{\bar@{e@}}
> @end ifnottex
3309c3370
< $||e||^2 = e\overline{e}$
---
> $||e||^2 = e\overline{e}$.
3311,3312c3372,3375
< . The inverse of a Clifford expression is returned
< by the function
---
> @ifnottex
> @code{||e||^2 = e \bar@{e@}}
> @end ifnottex
>  The inverse of a Clifford expression is returned by the function
3320c3383
< $e^{-1} = e/||e||^2$
---
> $e^{-1} = \overline{e}/||e||^2$.
3322c3385,3388
< . If
---
> @ifnottex
> @math{e^@{-1@} = \bar@{e@}/||e||^2}
> @end ifnottex
>  If
3325a3392,3394
> @ifnottex
> @math{||e||=0}
> @end ifnottex
3350,3354c3419,3424
< 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{M = [[a, b], [c, d]]}. The
< parameter @code{G} defines the metric of the surrounding
< (pseudo-)Euclidean space. The returned value of this function is a list
---
> 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{M = [[a, b], [c, d]]}. The parameter @code{G} defines
> the metric of the surrounding (pseudo-)Euclidean space. This can be a
> matrix or a Clifford unit, in the later case the parameter @code{rl} is
> ignored even if supplied.  The returned value of this function is a list
3356a3427,3459
> LaTeX output for Clifford units looks like @code{\clifford[1]@{e@}^@{@{\nu@}@}},
> where @code{1} is the @code{representation_label} and @code{\nu} is the
> index of the corresponding unit. This provides a flexible typesetting
> with a suitable defintion of the @code{\clifford} command. For example, the
> definition 
> @example
>     \newcommand@{\clifford@}[1][]@{@}
> @end example
> typesets all Clifford units identically, while the alternative definition
> @example
>     \newcommand@{\clifford@}[2][]@{\ifcase #1 #2\or \tilde@{#2@} \or \breve@{#2@} \fi@}
> @end example
> prints units with @code{representation_label=0} as 
> @tex
> $e$,
> @end tex
> @ifnottex
> @code{e},
> @end ifnottex
> with @code{representation_label=1} as 
> @tex
> $\tilde{e}$
> @end tex
> @ifnottex
> @code{\tilde@{e@}}
> @end ifnottex
>  and with @code{representation_label=2} as 
> @tex
> $\breve{e}$.
> @end tex
> @ifnottex
> @code{\breve@{e@}}.
> @end ifnottex
Index: ginac/clifford.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.h,v
retrieving revision 1.55
diff -r1.55 clifford.h
292a293
>  *  @param e Clifford unit object
294a296
> ex lst_to_clifford(const ex & v, const ex & e);
304c306,307
<  *  @param algebraic Use algebraic or symbolic algorithm for extractions */
---
>  *  @param algebraic Use algebraic or symbolic algorithm for extractions 
>  *  @return List of components of a Clifford vector*/
318,319c321,323
<  *  @param G Metric of the surrounding space
<  *  @param rl Representation label */
---
>  *  @param G Metric of the surrounding space, may be a Clifford unit then the next parameter is ignored
>  *  @param rl Representation label 
>  *  @return List of components of the transformed vector*/
327,328c331,333
<  *  @param G Metric of the surrounding space
<  *  @param rl Representation label */
---
>  *  @param G Metric of the surrounding space, may be a Clifford unit then the next parameter is ignored
>  *  @param rl Representation label 
>  *  @return List of components of the transformed vector*/
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.84
diff -r1.84 clifford.cpp
216c216,217
< 	} else
---
> 	} else {
> 		c.s << "\\clifford[" << int(representation_label) << "]";
217a219
> 	}
227c229
< DEFAULT_PRINT_LATEX(diracone, "ONE", "\\mathbb{1}")
---
> DEFAULT_PRINT_LATEX(diracone, "ONE", "\\mathbf{1}")
940c942
< ex canonicalize_clifford(const ex & e)
---
> ex canonicalize_clifford(const ex & e_)
944,946c946,948
< 	if (is_a<matrix>(e)    // || is_a<pseries>(e) || is_a<integral>(e)
< 		|| is_a<lst>(e)) {
< 		return e.map(fcn);
---
> 	if (is_a<matrix>(e_)    // || is_a<pseries>(e) || is_a<integral>(e)
> 		|| is_a<lst>(e_)) {
> 		return e_.map(fcn);
947a950
> 		ex e=simplify_indexed(e_);
1046d1048
< 	unsigned min, max;
1049,1050c1051,1053
< 	unsigned dim = (ex_to<numeric>(ex_to<idx>(mu).get_dim())).to_int();
< 	ex c = clifford_unit(mu, metr, rl);
---
> 	ex e = clifford_unit(mu, metr, rl);
> 	return lst_to_clifford(v, e);
> }
1052,1063c1055,1072
< 	if (is_a<matrix>(v)) {
< 		if (ex_to<matrix>(v).cols() > ex_to<matrix>(v).rows()) {
< 			min = ex_to<matrix>(v).rows();
< 			max = ex_to<matrix>(v).cols();
< 		} else {
< 			min = ex_to<matrix>(v).cols();
< 			max = ex_to<matrix>(v).rows();
< 		}
< 		if (min == 1) {
< 			if (dim == max)
< 				if (is_a<varidx>(mu)) // need to swap variance
< 					return indexed(v, ex_to<varidx>(mu).toggle_variance()) * c;
---
> ex lst_to_clifford(const ex & v, const ex & e) {
> 	unsigned min, max;
> 
> 	if (is_a<clifford>(e)) {
> 		varidx mu = ex_to<varidx>(e.op(1));
> 		unsigned dim = (ex_to<numeric>(mu.get_dim())).to_int();
> 
> 		if (is_a<matrix>(v)) {
> 			if (ex_to<matrix>(v).cols() > ex_to<matrix>(v).rows()) {
> 				min = ex_to<matrix>(v).rows();
> 				max = ex_to<matrix>(v).cols();
> 			} else {
> 				min = ex_to<matrix>(v).cols();
> 				max = ex_to<matrix>(v).rows();
> 			}
> 			if (min == 1) {
> 				if (dim == max)
> 					return indexed(v, ex_to<varidx>(mu).toggle_variance()) * e;
1065c1074,1079
< 					return indexed(v, mu) * c;
---
> 					throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch"));
> 			} else
> 				throw(std::invalid_argument("First argument should be a vector vector"));
> 		} else if (is_a<lst>(v)) {
> 			if (dim == ex_to<lst>(v).nops())
> 				return indexed(matrix(dim, 1, ex_to<lst>(v)), ex_to<varidx>(mu).toggle_variance()) * e;
1067c1081
< 				throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch"));
---
> 				throw(std::invalid_argument("List length and dimension of clifford unit mismatch"));
1069,1074c1083
< 			throw(std::invalid_argument("First argument should be a vector vector"));
< 	} else if (is_a<lst>(v)) {
< 		if (dim == ex_to<lst>(v).nops())
< 			return indexed(matrix(dim, 1, ex_to<lst>(v)), ex_to<varidx>(mu).toggle_variance()) * c;
< 		else
< 			throw(std::invalid_argument("List length and dimension of clifford unit mismatch"));
---
> 			throw(std::invalid_argument("Cannot construct from anything but list or vector"));
1076c1085
< 		throw(std::invalid_argument("Cannot construct from anything but list or vector"));
---
> 		throw(std::invalid_argument("The second argument should be a Clifford unit"));
1146c1155,1156
< 			if (pow(c.subs(mu == i), 2) == 0)
---
> 			if (pow(c.subs(mu == i), 2).is_zero() 
> 				or (not is_a<numeric>(pow(c.subs(mu == i), 2))))
1165,1171c1175
< 	ex x, D;
< 	if (is_a<indexed>(G)) 
< 		D = ex_to<varidx>(G.op(1)).get_dim();
< 	else if (is_a<matrix>(G)) 
< 		D = ex_to<matrix>(G).rows();
< 	else
< 		throw(std::invalid_argument("metric should be an indexed object or matrix"));
---
> 	ex x, D, cu;
1173,1174d1176
< 	varidx mu((new symbol)->setflag(status_flags::dynallocated), D);
< 		   
1176a1179,1191
> 	
> 	if (is_a<clifford>(G)) {
> 		cu = G;
> 	} else {
> 		if (is_a<indexed>(G)) 
> 			D = ex_to<varidx>(G.op(1)).get_dim();
> 		else if (is_a<matrix>(G)) 
> 			D = ex_to<matrix>(G).rows(); 
> 		else throw(std::invalid_argument("metric should be an indexed object, matrix, or a Clifford unit"));
> 		
> 		varidx mu((new symbol)->setflag(status_flags::dynallocated), D);
> 		cu = clifford_unit(mu, G, rl);
> 	}
1178c1193
< 	x = lst_to_clifford(v, mu, G, rl);
---
> 	x = lst_to_clifford(v, cu); 
1180d1194
< 	ex cu = clifford_unit(mu, G);
Index: check/exam_clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/check/exam_clifford.cpp,v
retrieving revision 1.23
diff -r1.23 exam_clifford.cpp
344c344,345
< 	e = lst_to_clifford(lst(t, x, y, z), mu, G) * lst_to_clifford(lst(1, 2, 3, 4), nu, G);
---
> 	ex c = clifford_unit(nu, G, 1);
> 	e = lst_to_clifford(lst(t, x, y, z), mu, G, 1) * lst_to_clifford(lst(1, 2, 3, 4), c);
346c347
< 	result += check_equal((e*e1).simplify_indexed().normal(), dirac_ONE());
---
> 	result += check_equal((e*e1).simplify_indexed().normal(), dirac_ONE(1));




More information about the GiNaC-devel mailing list