From C.Dams at science.ru.nl Mon Mar 21 14:46:17 2005 From: C.Dams at science.ru.nl (Chris Dams) Date: Mon, 21 Mar 2005 14:46:17 +0100 (CET) Subject: [GiNaC-devel] patch for canonicalize_clifford Message-ID: Dear developers, I found out that the result of ex f=dirac_gamma(varidx(nu,dim)) *dirac_slash(k,dim) *dirac_gamma(varidx(mu,dim)) *indexed(n,varidx(nu,dim,true)) *indexed(k,varidx(mu,dim,true)); cout << "before canon_cl: " << f << endl; f=canonicalize_clifford(f); cout << "after canon_cl: " << f << endl; is before canon_cl: n.nu*(gamma~nu*k\*gamma~mu)*k.mu after canon_cl: 2*n\*k.mu*k~mu-2*n~mu*k.mu*k\+k\*n\*k\ I think it is strange that canonicalize_clifford can return something that contains k\*n\*k\ because this looks particularly uncanonicalized. I suggest the patch Index: ginac/clifford.cpp =================================================================== RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v retrieving revision 1.84 diff -r1.84 clifford.cpp 940c940 < ex canonicalize_clifford(const ex & e) --- > ex canonicalize_clifford(const ex & e_) 941a942 > ex e=simplify_indexed(e_); With this patch the test program gives before canon_cl: n.nu*(gamma~nu*k\*gamma~mu)*k.mu after canon_cl: n\*k.symbol8*k~symbol8 Best wishes, Chris From kisilv at maths.leeds.ac.uk Tue Mar 29 13:34:13 2005 From: kisilv at maths.leeds.ac.uk (Vladimir Kisil) Date: Tue, 29 Mar 2005 12:34:13 +0100 Subject: [GiNaC-devel] Patches for clifford (cumulative) Message-ID: 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(e) // || is_a(e) || is_a(e) < || is_a(e)) { < return e.map(fcn); --- > if (is_a(e_) // || is_a(e) || is_a(e) > || is_a(e_)) { > return e_.map(fcn); 947a950 > ex e=simplify_indexed(e_); 1046d1048 < unsigned min, max; 1049,1050c1051,1053 < unsigned dim = (ex_to(ex_to(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(v)) { < if (ex_to(v).cols() > ex_to(v).rows()) { < min = ex_to(v).rows(); < max = ex_to(v).cols(); < } else { < min = ex_to(v).cols(); < max = ex_to(v).rows(); < } < if (min == 1) { < if (dim == max) < if (is_a(mu)) // need to swap variance < return indexed(v, ex_to(mu).toggle_variance()) * c; --- > ex lst_to_clifford(const ex & v, const ex & e) { > unsigned min, max; > > if (is_a(e)) { > varidx mu = ex_to(e.op(1)); > unsigned dim = (ex_to(mu.get_dim())).to_int(); > > if (is_a(v)) { > if (ex_to(v).cols() > ex_to(v).rows()) { > min = ex_to(v).rows(); > max = ex_to(v).cols(); > } else { > min = ex_to(v).cols(); > max = ex_to(v).rows(); > } > if (min == 1) { > if (dim == max) > return indexed(v, ex_to(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(v)) { > if (dim == ex_to(v).nops()) > return indexed(matrix(dim, 1, ex_to(v)), ex_to(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(v)) { < if (dim == ex_to(v).nops()) < return indexed(matrix(dim, 1, ex_to(v)), ex_to(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(pow(c.subs(mu == i), 2)))) 1165,1171c1175 < ex x, D; < if (is_a(G)) < D = ex_to(G.op(1)).get_dim(); < else if (is_a(G)) < D = ex_to(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(G)) { > cu = G; > } else { > if (is_a(G)) > D = ex_to(G.op(1)).get_dim(); > else if (is_a(G)) > D = ex_to(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)); From kisilv at maths.leeds.ac.uk Thu Mar 31 16:00:48 2005 From: kisilv at maths.leeds.ac.uk (Vladimir Kisil) Date: Thu, 31 Mar 2005 15:00:48 +0100 Subject: [GiNaC-devel] (no subject) Message-ID: Dear All, Apologies for flooding this list, but 1. I found one more bug in clifford_prime(): it did not map itself on the usual (commutative) products "mul". 2. I also changed the behaviour of remove_dirac_ONE() slightly: it is now aware of representation_label for Clifford numbers. API and default behaviour remain the same (but not a binary compatibility). So here is the cumulative patch to my previous post on Tue Mar 29 13:34:13. 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,3222 < 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"); > ex M = diag_matrix(lst(1, -1, 0, s)); 3218a3227 > ex e3 = e.subs(nu == 3); 3223,3224c3232,3238 < 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 anti-commuting 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 3231a3246 > ex lst_to_clifford(const ex & v, const ex & e); 3234,3237c3249,3268 < 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,3248c3273,3279 < 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"); > ex M = diag_matrix(lst(1, -1, 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,3262c3292,3305 < @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 3266c3309,3315 < @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} 3292a3342,3344 > @ifnottex > e* > @end ifnottex 3296a3349,3351 > @ifnottex > @code{\bar@{e@}} > @end ifnottex 3309c3364 < $||e||^2 = e\overline{e}$ --- > $||e||^2 = e\overline{e}$. 3311,3312c3366,3369 < . 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 3320c3377 < $e^{-1} = e/||e||^2$ --- > $e^{-1} = \overline{e}/||e||^2$. 3322c3379,3382 < . If --- > @ifnottex > @math{e^@{-1@} = \bar@{e@}/||e||^2} > @end ifnottex > If 3325a3386,3388 > @ifnottex > @math{||e||=0} > @end ifnottex 3350,3354c3413,3418 < 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 3356a3421,3453 > 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 278,279c278,284 < /** Replaces all dirac_ONE's in e with 1 (effectively removing them). */ < ex remove_dirac_ONE(const ex & e); --- > /** Replaces dirac_ONE's (with a representation_label no less than rl) in e with 1. > * For the default value rl = 0 remove all of them. Aborts if e contains any > * clifford_unit with representation_label to be removed. > * > * @param e Expression to be processed > * @param rl Value of representation label */ > ex remove_dirac_ONE(const ex & e, unsigned char rl = 0); 292a298 > * @param e Clifford unit object 294a301 > ex lst_to_clifford(const ex & v, const ex & e); 304c311,312 < * @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,319c326,328 < * @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,328c336,338 < * @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(e) // || is_a(e) || is_a(e) < || is_a(e)) { < return e.map(fcn); --- > if (is_a(e_) // || is_a(e) || is_a(e) > || is_a(e_)) { > return e_.map(fcn); 947a950 > ex e=simplify_indexed(e_); 1007,1008c1010,1011 < } else if (is_a(e) || is_a(e) // || is_a(e) || is_a(e) < || is_a(e) || is_a(e)) { --- > } else if (is_a(e) || is_a(e) || is_a(e) //|| is_a(e) || is_a(e) > || is_a(e) || is_a(e)) { 1016c1019 < ex remove_dirac_ONE(const ex & e) --- > ex remove_dirac_ONE(const ex & e, unsigned char rl) 1018,1020c1021,1026 < pointer_to_map_function fcn(remove_dirac_ONE); < if (is_a(e) && is_a(e.op(0))) { < return 1; --- > pointer_to_map_function_1arg fcn(remove_dirac_ONE, rl); > if (is_a(e) && ex_to(e).get_representation_label() >= rl) { > if (is_a(e.op(0))) > return 1; > else > throw(std::invalid_argument("Expression is a non-scalar Clifford number!")); 1022c1028 < || is_a(e) || is_a(e)) { --- > || is_a(e) || is_a(e)) { 1046d1051 < unsigned min, max; 1049,1050c1054,1056 < unsigned dim = (ex_to(ex_to(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,1063c1058,1075 < if (is_a(v)) { < if (ex_to(v).cols() > ex_to(v).rows()) { < min = ex_to(v).rows(); < max = ex_to(v).cols(); < } else { < min = ex_to(v).cols(); < max = ex_to(v).rows(); < } < if (min == 1) { < if (dim == max) < if (is_a(mu)) // need to swap variance < return indexed(v, ex_to(mu).toggle_variance()) * c; --- > ex lst_to_clifford(const ex & v, const ex & e) { > unsigned min, max; > > if (is_a(e)) { > varidx mu = ex_to(e.op(1)); > unsigned dim = (ex_to(mu.get_dim())).to_int(); > > if (is_a(v)) { > if (ex_to(v).cols() > ex_to(v).rows()) { > min = ex_to(v).rows(); > max = ex_to(v).cols(); > } else { > min = ex_to(v).cols(); > max = ex_to(v).rows(); > } > if (min == 1) { > if (dim == max) > return indexed(v, ex_to(mu).toggle_variance()) * e; 1065c1077,1082 < 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(v)) { > if (dim == ex_to(v).nops()) > return indexed(matrix(dim, 1, ex_to(v)), ex_to(mu).toggle_variance()) * e; 1067c1084 < throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch")); --- > throw(std::invalid_argument("List length and dimension of clifford unit mismatch")); 1069,1074c1086 < throw(std::invalid_argument("First argument should be a vector vector")); < } else if (is_a(v)) { < if (dim == ex_to(v).nops()) < return indexed(matrix(dim, 1, ex_to(v)), ex_to(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")); 1076c1088 < throw(std::invalid_argument("Cannot construct from anything but list or vector")); --- > throw(std::invalid_argument("The second argument should be a Clifford unit")); 1146c1158,1159 < if (pow(c.subs(mu == i), 2) == 0) --- > if (pow(c.subs(mu == i), 2).is_zero() > or (not is_a(pow(c.subs(mu == i), 2)))) 1165,1171c1178 < ex x, D; < if (is_a(G)) < D = ex_to(G.op(1)).get_dim(); < else if (is_a(G)) < D = ex_to(G).rows(); < else < throw(std::invalid_argument("metric should be an indexed object or matrix")); --- > ex x, D, cu; 1173,1174d1179 < varidx mu((new symbol)->setflag(status_flags::dynallocated), D); < 1176a1182,1194 > > if (is_a(G)) { > cu = G; > } else { > if (is_a(G)) > D = ex_to(G.op(1)).get_dim(); > else if (is_a(G)) > D = ex_to(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); > } 1178c1196 < x = lst_to_clifford(v, mu, G, rl); --- > x = lst_to_clifford(v, cu); 1180d1197 < 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));