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@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));
participants (1)
-
Vladimir Kisil