[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