Dear All,
I propose some further patches related to Clifford numbers. They
are
1. LaTeX printing of Clifford object includes the command
\clifford[rl] which make a use of the representation labels for
separation of different algebras.
2. Alternative forms for functions lst_to_clifford() and
clifford_moebius_map() which may got the structure of Clifford algebra
out of a sample Clifford unit.
The changes are reflected in documentation (which also slightly
polished) and in the exam_clifford.cpp.
All the best,
Vladimir
--
Vladimir V. Kisil email: kisilv(a)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.161
diff -r1.161 ginac.texi
3178,3179c3178,3188
< generators @samp{e~k} satisfying the identities
< @samp{e~i e~j + e~j e~i = B(i, j)} for some matrix (@code{metric})
---
> generators
> @tex $e_k$
> @end tex
> satisfying the identities
> @tex
> $e_i e_j + e_j e_i = B(i, j) $
> @end tex
> @ifnottex
> e~i e~j + e~j e~i = B(i, j)
> @end ifnottex
> for some matrix (@code{metric})
3223a3233,3236
> @tex
> $e_0^2=1 $, $e_1^2=-1$ and $e_2^2=0$.
> @end tex
> @ifnottex
3224a3238
> @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
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=0$
> @end tex
> @ifnottex
> @samp{(e c.k + c.k e)/pow(c.k, 2)}. If @samp{pow(c.k, 2) = 0}
> @end ifnottex
> 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
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}")
1046d1047
< unsigned min, max;
1049,1050c1050,1052
< 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,1063c1054,1071
< 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;
1065c1073,1078
< 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;
1067c1080
< throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch"));
---
> throw(std::invalid_argument("List length and dimension of clifford unit mismatch"));
1069,1074c1082
< 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"));
1076c1084
< throw(std::invalid_argument("Cannot construct from anything but list or vector"));
---
> throw(std::invalid_argument("The second argument should be a Clifford unit"));
1165,1171c1173
< 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,1174d1174
< varidx mu((new symbol)->setflag(status_flags::dynallocated), D);
<
1176a1177,1189
>
> 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);
> }
1178c1191
< x = lst_to_clifford(v, mu, G, rl);
---
> x = lst_to_clifford(v, cu);
1180d1192
< 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));
Hi,
I discovered that clifford_moebius_map() function was ignorant
of representative labels for Clifford numbers, which generates
misbehaviour. I include the cumulative patch which this issue along
with the previous one.
Best wishes,
Vladimir
--
Vladimir V. Kisil email: kisilv(a)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.159
diff -r1.159 ginac.texi
3179,3180c3179,3181
< @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
---
> @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
3194a3196,3204
> If the matrix @math{B(i, j)} is in fact symmetric you may prefer to create
> the Clifford algebra units with a call like that
>
> @example
> ex e = clifford_unit(mu, indexed(B, sy_symm(), i, j));
> @end example
>
> since this may yield some further automatic simplifications.
>
3336c3346,3347
< const ex & d, const ex & v, const ex & G);
---
> const ex & d, const ex & v, const ex & G, unsigned char rl = 0);
> ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl = 0);
3341c3352
< (av+b)/(cv+d)} defined by the matrix @samp{[[a, b], [c, d]]}. The last
---
> (av+b)/(cv+d)} defined by the matrix @samp{M = [[a, b], [c, d]]}. The
Index: ginac/clifford.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.h,v
retrieving revision 1.53
diff -r1.53 clifford.h
318,319c318,320
< * @param G Metric of the surrounding space */
< ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G);
---
> * @param G Metric of the surrounding space
> * @param rl Representation label*/
> ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl = 0);
326,327c327,329
< * @param G Metric of the surrounding space */
< ex clifford_moebius_map(const ex & M, const ex & v, const ex & G);
---
> * @param G Metric of the surrounding space
> * @param rl Representation label*/
> ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl = 0);
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.82
diff -r1.82 clifford.cpp
1163c1163
< ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G)
---
> ex clifford_moebius_map(const ex & a, const ex & b, const ex & c, const ex & d, const ex & v, const ex & G, unsigned char rl)
1178c1178
< x = lst_to_clifford(v, mu, G);
---
> x = lst_to_clifford(v, mu, G, rl);
1184c1184
< ex clifford_moebius_map(const ex & M, const ex & v, const ex & G)
---
> ex clifford_moebius_map(const ex & M, const ex & v, const ex & G,unsigned char rl)
1188c1188
< ex_to<matrix>(M)(1,0), ex_to<matrix>(M)(1,1), v, G);
---
> ex_to<matrix>(M)(1,0), ex_to<matrix>(M)(1,1), v, G, rl);
Dear developers,
We, of course, do not want zero as a coefficient in a power series.
However, my integral::series can give such a result. Here is a patch.
Best wishes,
Chris
Hi,
I am wondering is my patch submitted here on (Thu Dec 2 16:22:03
2004) was lost or rejected....
Best,
Vladimir
--
Vladimir V. Kisil email: kisilv(a)maths.leeds.ac.uk
-- www: http://maths.leeds.ac.uk/~kisilv/
Dear Chris,
On Thu, 20 Jan 2005, Chris Dams wrote:
[...]
> Okay, I can reproduce it now. The placement news that occured in my last
> patch appears to solve something, but not everything. Another problem are
> the refences _num_25 and so on. When are these going to be initialized?
> By the linker, I suppose.
Hmmm, good question.
> At least that would explain the point at which I
> am seeing segfaults now.
Are you saying your patch still segfaults?
> But how is the linker supposed to know where
> memory is going to be allocated? Here's a patch that also throws the
> references out of the library.
Could you please explain what you're doing in plain English? I'm sure
we'll all get some better understanding of the issues this way.
Anyways, you got me slabbing my forehead really hard with your way of
cheerfully writing
(_num0_p = new numeric(0))->setflag(status_flags::dynallocated);
instead of the more convoluted
_num0_p = static_cast<const numeric*>(&((new numeric(0))->setflag(status_flags::dynallocated)));
This looks good.
Regards
-richy.
--
Richard B. Kreckel
<http://www.ginac.de/~kreckel/>