[GiNaC-devel] Clifford patch
Vladimir Kisil
kisilv at maths.leeds.ac.uk
Thu Apr 28 18:17:55 CEST 2005
Dear All,
Here is a new patch for the clifford.cpp, which is even too
large to fin in one message. Thus the tail is sent separately.
It relays on two other additions:
1. A patch to add.cpp, which I posted here on Wed Apr 20 12:07:29 CEST
2005. It seems that a more fundamental solutions is required here, so
my code is only a temporary one.
2. An additional function expand_dummy_sum() in indexed.cpp. It shares
a portion of common code with simplify_indexed() and I put this piece
into a separate auxiliary procedure product_to_exvector().
The main changes to clifford.cpp itself are as follows:
1. There are now two different simplifications paths in
clifford::contract_with() depending on if Clifford units are
anticommuting or not. This information is now stored in a new member
variable
bool anticommuting;
The difference in results of contractions can be seen from
exam_clifford.cpp.
2. The present code should work now with non-symmetric metric as
well. At present it always result in a symmetrised metric
M(i,j)+M(j,i), but this should change when more functions from
geometric algebras will be added.
3. Exams in exam_clifford.cpp cover now all defined functions in the
majority of possible parameter variations.
4. Many small corrections.
5. Those changes are reflected in ginac.texi
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.165
diff -r1.165 ginac.texi
2569a2570,2610
> @cindex @code{expand_dummy_sum()}
> A dummy index summation like
> @tex
> $ a_i b^i$
> @end tex
> @ifnottex
> a.i b~i
> @end ifnottex
> can be expanded for indexes with numeric
> dimensions (e.g. 3) into the explicit sum like
> @tex
> $a_1b^1+a_2b^2+a_3b^3 $.
> @end tex
> @ifnottex
> a.1 b~1 + a.2 b~2 + a.3 b~3.
> @end ifnottex
> This performed by the function
>
> @example
> ex expand_dummy_sum(const ex & e, bool subs_idx = false);
> @end example
>
> which takes an expression @code{e} and returns the expanded sum for all
> dummy indexes with numeric dimensions. If the parameter @code{subs_idx}
> is set to @code{true} then all substitutions are made by @code{idx} class
> indexes, i.e. without variance. In this case the above sum
> @tex
> $ a_i b^i$
> @end tex
> @ifnottex
> a.i b~i
> @end ifnottex
> will be expanded to
> @tex
> $a_1b_1+a_2b_2+a_3b_3 $.
> @end tex
> @ifnottex
> a.1 b.1 + a.2 b.2 + a.3 b.3.
> @end ifnottex
>
>
3192c3233
< $e_i e_j + e_j e_i = M(i, j) $
---
> $e_i e_j + e_j e_i = M(i, j) + M(j, i) $
3195c3236
< e~i e~j + e~j e~i = M(i, j)
---
> e~i e~j + e~j e~i = M(i, j) + M(j, i)
3197,3199c3238,3241
< 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
---
> for some bilinear form (@code{metric})
> @math{M(i, j)}, which may be non-symmetric (see arXiv:math.QA/9911180)
> and contain symbolic entries. Such generators are created by the
> function
3202c3244,3245
< ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
---
> ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0,
> bool anticommuting = false);
3206c3249,3251
< generators, @code{metr} defines the metric @math{M(i, j)} and can be
---
> generators, an index @code{mu} with a numeric value may be of type
> @code{idx} as well.
> Parameter @code{metr} defines the metric @math{M(i, j)} and can be
3208,3212c3253,3277
< object, optional parameter @code{rl} allows to distinguish different
< Clifford algebras (which will commute with each other). Note that the call
< @code{clifford_unit(mu, minkmetric())} creates something very close to
< @code{dirac_gamma(mu)}. The method @code{clifford::get_metric()} returns a
< metric defining this Clifford number.
---
> object. Optional parameter @code{rl} allows to distinguish different
> Clifford algebras, which will commute with each other. The last
> optional parameter @code{anticommuting} defines if the anticommuting
> assumption (i.e.
> @tex
> $e_i e_j + e_j e_i = 0$)
> @end tex
> @ifnottex
> e~i e~j + e~j e~i = 0)
> @end ifnottex
> will be used for contraction of Clifford units. If the @code{metric} is
> supplied by a @code{matrix} object, then the value of
> @code{anticommuting} is calculated automatically and the supplied one
> will be ignored. One can overcome this by giving @code{metric} through
> matrix wrapped into an @code{indexed} object.
>
> Note that the call @code{clifford_unit(mu, minkmetric())} creates
> something very close to @code{dirac_gamma(mu)}, although
> @code{dirac_gamma} have more efficient simplification mechanism.
> @cindex @code{clifford::get_metric()}
> The method @code{clifford::get_metric()} returns a metric defining this
> Clifford number.
> @cindex @code{clifford::is_anticommuting()}
> The method @code{clifford::is_anticommuting()} returns the
> @code{anticommuting} property of a unit.
3221c3286,3288
< since this may yield some further automatic simplifications.
---
> since this may yield some further automatic simplifications. Again, for a
> metric defined through a @code{matrix} such a symmetry is detected
> automatically.
3246c3313,3314
< @code{pow(e0, 2) = 1}, @code{pow(e1, 2) = -1}, @code{pow(e2, 2) = 0} and @code{pow(e3, 2) = s}.
---
> @code{pow(e0, 2) = 1}, @code{pow(e1, 2) = -1}, @code{pow(e2, 2) = 0} and
> @code{pow(e3, 2) = s}.
3254c3322
< unsigned char rl = 0);
---
> unsigned char rl = 0, bool anticommuting = false);
3276c3344
< @code{clifford_unit(mu, metr, rl)}. The previous code may be rewritten
---
> @code{clifford_unit(mu, metr, rl, anticommuting)}. The previous code may be rewritten
3324c3392
< is zero or is not a @code{numeric} for some @samp{k}
---
> is zero or is not @code{numeric} for some @samp{k}
3413c3481
< The last provided function is
---
> The next provided function is
3419c3487
< unsigned char rl = 0);
---
> unsigned char rl = 0, bool anticommuting = false);
3421c3489
< unsigned char rl = 0);
---
> unsigned char rl = 0, bool anticommuting = false);
3427,3436c3495,3518
< 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
< of components of the resulting vector.
<
< 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
---
> the metric of the surrounding (pseudo-)Euclidean space. This can be an
> indexed object, tensormetric, matrix or a Clifford unit, in the later
> case the optional parameters @code{rl} and @code{anticommuting} are ignored
> even if supplied. The returned value of this function is a list of
> components of the resulting vector.
>
> @cindex @code{clifford_max_label()}
> Finally the function
>
> @example
> char clifford_max_label(const ex & e, bool ignore_ONE = false);
> @end example
>
> can detect a presence of Clifford objects in the expression @code{e}: if
> such objects are found it returns the maximal
> @code{representation_label} of them, otherwise @code{-1}. The optional
> parameter @code{ignore_ONE} indicates if @code{dirac_ONE} objects should
> be ignored during the search.
>
> 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
Index: ginac/add.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/add.cpp,v
retrieving revision 1.76
diff -r1.76 add.cpp
31a32,33
> #include "clifford.h"
> #include "ncmul.h"
293a296,298
> std::auto_ptr<epvector> coeffseq_cliff(new epvector);
> char rl = clifford_max_label(s);
> bool do_clifford = (rl != -1), nonscalar = false;
299c304,311
< if (!restcoeff.is_zero())
---
> if (!restcoeff.is_zero()) {
> if (do_clifford)
> if (clifford_max_label(restcoeff) == -1)
> coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(ncmul(restcoeff, dirac_ONE(rl)), i->coeff));
> else {
> coeffseq_cliff->push_back(combine_ex_with_coeff_to_pair(restcoeff, i->coeff));
> nonscalar = true;
> }
300a313
> }
304c317,318
< return (new add(coeffseq, n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
---
> return (new add(nonscalar? coeffseq_cliff : coeffseq,
> n==0 ? overall_coeff : _ex0))->setflag(status_flags::dynallocated);
Index: ginac/indexed.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/indexed.h,v
retrieving revision 1.50
diff -r1.50 indexed.h
252a253,263
> /** This function returns the given expression with expanded sums
> * for all dummy indexes summation, where dimensionality of
> * the dummy index is numeric.
> * Optionally all indexes with a variance will be substituted by
> * indices with the corresponding numeric values without variance.
> *
> * @param e the given expression
> * @param subs_idx indicates if variance of dummy indixes should be neglected
> */
> ex expand_dummy_sum(const ex & e, bool subs_idx = false);
>
Index: ginac/indexed.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/indexed.cpp,v
retrieving revision 1.94
diff -r1.94 indexed.cpp
672,674c672,674
< /** Simplify product of indexed expressions (commutative, noncommutative and
< * simple squares), return list of free indices. */
< ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & dummy_indices, const scalar_products & sp)
---
> /* An auxiliary function used by simplify_indexed() and expand_dummy_sum()
> * It returns an exvector of factors from the supplied product*/
> static void product_to_exvector(const ex &e, exvector &v, bool &non_commutative)
678c678
< bool non_commutative = is_exactly_a<ncmul>(e);
---
> non_commutative = is_exactly_a<ncmul>(e);
681d680
< exvector v;
703a703,715
> }
>
> /** Simplify product of indexed expressions (commutative, noncommutative and
> * simple squares), return list of free indices. */
> ex simplify_indexed_product(const ex & e, exvector & free_indices, exvector & dummy_indices, const scalar_products & sp)
> {
> // Collect factors in an exvector
> exvector v;
>
> // Remember whether the product was commutative or noncommutative
> // (because we chop it into factors and need to reassemble later)
> bool non_commutative;
> product_to_exvector(e, v, non_commutative);
1278a1291,1352
> }
>
> ex expand_dummy_sum(const ex &e, bool subs_idx)
> {
> ex e_expanded = e.expand();
> pointer_to_map_function_1arg<bool> fcn(expand_dummy_sum, subs_idx);
> if (is_a<add>(e_expanded))
> return e_expanded.map(fcn);
> else if (is_a<ncmul>(e_expanded) || is_a<mul>(e_expanded) || is_a<power>(e_expanded)) {
> exvector p;
> bool nc;
> product_to_exvector(e_expanded, p, nc);
> exvector::const_iterator ip = p.begin(), ipend = p.end();
> exvector v;
> while (ip != ipend) {
> if (is_a<indexed>(*ip)) {
> v = ex_to<indexed>(*ip).get_dummy_indices();
> exvector::const_iterator ip1 = ip+1;
> while (ip1 != ipend) {
> if (is_a<indexed>(*ip1)) {
> exvector v1 = ex_to<indexed>(*ip).get_dummy_indices(ex_to<indexed>(*ip1));
> v.insert(v.end(), v1.begin(), v1.end());
> }
> ip1++;
> }
> exvector::const_iterator it = v.begin(), itend = v.end();
> while (it != itend) {
> varidx nu = ex_to<varidx>(*it);
> if (nu.is_dim_numeric()) {
> ex en = 0;
> for (int i=0; i < ex_to<numeric>(nu.get_dim()).to_int(); i++)
> if (is_a<varidx>(nu) && !subs_idx)
> en += e_expanded.subs(lst(nu == varidx(i, nu.get_dim(), true), nu.toggle_variance() == varidx(i, nu.get_dim())));
> else
> en += e_expanded.subs(lst(nu == idx(i, nu.get_dim()), nu.toggle_variance() == idx(i, nu.get_dim())));
> return expand_dummy_sum(en, subs_idx);
> }
> it++;
> }
> }
> ip++;
> }
> return e;
> } else if (is_a<indexed>(e_expanded)) {
> exvector v = ex_to<indexed>(e_expanded).get_dummy_indices();
> exvector::const_iterator it = v.begin(), itend = v.end();
> while (it != itend) {
> varidx nu = ex_to<varidx>(*it);
> if (nu.is_dim_numeric()) {
> ex en = 0;
> for (int i=0; i < ex_to<numeric>(nu.get_dim()).to_int(); i++)
> if (is_a<varidx>(nu) && !subs_idx)
> en += e_expanded.subs(lst(nu == varidx(i, nu.get_dim(), true), nu.toggle_variance() == varidx(i, nu.get_dim())));
> else
> en += e_expanded.subs(lst(nu == idx(i, nu.get_dim()), nu.toggle_variance() == idx(i, nu.get_dim())));
> return expand_dummy_sum(en, subs_idx);
> }
> it++;
> }
> return e;
> } else
> return e;
Index: ginac/clifford.h
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.h,v
retrieving revision 1.57
diff -r1.57 clifford.h
47,48c47,48
< clifford(const ex & b, unsigned char rl = 0);
< clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl = 0);
---
> clifford(const ex & b, unsigned char rl = 0, bool anticommut = false);
> clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommut = false);
51,52c51,52
< clifford(unsigned char rl, const ex & metr, const exvector & v, bool discardable = false);
< clifford(unsigned char rl, const ex & metr, std::auto_ptr<exvector> vp);
---
> clifford(unsigned char rl, const ex & metr, bool anticommut, const exvector & v, bool discardable = false);
> clifford(unsigned char rl, const ex & metr, bool anticommut, std::auto_ptr<exvector> vp);
69c69
< ex get_metric(const ex & i, const ex & j) const;
---
> ex get_metric(const ex & i, const ex & j, bool symmetrised = false) const;
70a71
> bool is_anticommuting() const { return anticommuting; } //**< See the member variable anticommuting */
79c80,81
< ex metric;
---
> ex metric; /**< Metric of the space, all constructors make it an indexed object */
> bool anticommuting; /**< Simplifications for anticommuting units is much simpler and we need this info readily available */
196c198
< * @param metr Metric (should be of class tensmetric or a derived class, or a matrix)
---
> * @param metr Metric (should be indexed, tensmetric or a derived class, or a matrix)
199c201
< ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0);
---
> ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommuting = false);
287a290,296
> /** Returns the maximal representation label of a clifford object
> * if e contains at least one, otherwise returns -1
> *
> * @param e Expression to be processed
> * @ignore_ONE defines if clifford_ONE should be ignored in the search*/
> char clifford_max_label(const ex & e, bool ignore_ONE = false);
>
298c307
< * @param metr Metric (should be of class tensmetric or a derived class, or a matrix)
---
> * @param metr Metric (should be indexed, tensmetric or a derived class, or a matrix)
302c311
< ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0);
---
> ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl = 0, bool anticommuting = false);
329a339
> * @param anticommuting indicates if Clifford units anticommutes
331c341
< 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);
---
> 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, bool anticommuting = false);
339a350
> * @param anticommuting indicates if Clifford units anticommutes
341c352
< ex clifford_moebius_map(const ex & M, 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, bool anticommuting = false);
Index: ginac/clifford.cpp
===================================================================
RCS file: /home/cvs/GiNaC/ginac/clifford.cpp,v
retrieving revision 1.88
diff -r1.88 clifford.cpp
80,81c80,81
<
< clifford::clifford() : representation_label(0), metric(default_metric())
---
>
> clifford::clifford() : representation_label(0), metric(default_metric()), anticommuting(false)
100c100
< clifford::clifford(const ex & b, unsigned char rl) : inherited(b), representation_label(rl), metric(0)
---
> clifford::clifford(const ex & b, unsigned char rl, bool anticommut) : inherited(b), representation_label(rl), metric(0), anticommuting(anticommut)
109c109
< clifford::clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl) : inherited(b, mu), representation_label(rl), metric(metr)
---
> clifford::clifford(const ex & b, const ex & mu, const ex & metr, unsigned char rl, bool anticommut) : inherited(b, mu), representation_label(rl), metric(metr), anticommuting(anticommut)
115c115
< clifford::clifford(unsigned char rl, const ex & metr, const exvector & v, bool discardable) : inherited(not_symmetric(), v, discardable), representation_label(rl), metric(metr)
---
> clifford::clifford(unsigned char rl, const ex & metr, bool anticommut, const exvector & v, bool discardable) : inherited(not_symmetric(), v, discardable), representation_label(rl), metric(metr), anticommuting(anticommut)
120c120
< clifford::clifford(unsigned char rl, const ex & metr, std::auto_ptr<exvector> vp) : inherited(not_symmetric(), vp), representation_label(rl), metric(metr)
---
> clifford::clifford(unsigned char rl, const ex & metr, bool anticommut, std::auto_ptr<exvector> vp) : inherited(not_symmetric(), vp), representation_label(rl), metric(metr), anticommuting(anticommut)
134a135
> n.find_bool("anticommuting", anticommuting);
141a143
> n.add_bool("anticommuting", anticommuting);
156c158
< ex clifford::get_metric(const ex & i, const ex & j) const
---
> ex clifford::get_metric(const ex & i, const ex & j, bool symmetrised) const
158c160,170
< return indexed(metric, symmetric2(), i, j);
---
> if (is_a<indexed>(metric)) {
> if (symmetrised && !(ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()).has_symmetry())) {
> if (is_a<matrix>(metric.op(0)))
> return indexed((ex_to<matrix>(metric.op(0)).add(ex_to<matrix>(metric.op(0)).transpose())).mul(numeric(1,2)),
> symmetric2(), i, j);
> else
> return simplify_indexed(indexed(metric.op(0)*_ex1_2, i, j) + indexed(metric.op(0)*_ex1_2, j, i));
> } else
> return indexed(metric.op(0), ex_to<symmetry>(ex_to<indexed>(metric).get_symmetry()), i, j);
> } else // should not really happen since all constructors but clifford() make the metric an indexed object
> return indexed(metric, i, j);
164c176
< return get_metric().is_equal(ex_to<clifford>(other).get_metric());
---
> return same_metric(ex_to<clifford>(other).get_metric());
378,384c390,396
< for (int i=0; i<v.size();i++) {
< if (!is_a<clifford>(v[i]) && is_a<indexed>(v[i])
< && ex_to<clifford>(c).same_metric(v[i])
< && (ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[0]
< || ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[0])) {
< return ++i; // next to found
< }
---
> for (size_t i=0; i<v.size(); i++) {
> if (is_a<indexed>(v[i]) && !is_a<clifford>(v[i])
> && ((ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[0]
> && ex_to<varidx>(c.op(1)) == ex_to<indexed>(v[i]).get_indices()[1])
> || (ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[0]
> && ex_to<varidx>(c.op(1)).toggle_variance() == ex_to<indexed>(v[i]).get_indices()[1])))
> return i; // the index of the found
386c398
< return 0; //nothing found
---
> return -1; //nothing found
397c409
<
---
>
406,408c418,430
< int prev_square = find_same_metric(v, self[0]);
< varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim());
< ex squared_metric = unit.get_metric(self->op(1), d) * unit.get_metric(d.toggle_variance(), other->op(1));
---
> int prev_square = find_same_metric(v, *self);
> const varidx d((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim()),
> in1((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim()),
> in2((new symbol)->setflag(status_flags::dynallocated), ex_to<idx>(self->op(1)).get_dim());
> ex squared_metric;
> if (prev_square > -1)
> squared_metric = simplify_indexed(indexed(v[prev_square].op(0), in1, d)
> * unit.get_metric(d.toggle_variance(), in2, true)).op(0);
>
> exvector::iterator before_other = other - 1;
> const varidx & mu = ex_to<varidx>(self->op(1));
> const varidx & mu_toggle = ex_to<varidx>(other->op(1));
> const varidx & alpha = ex_to<varidx>(before_other->op(1));
412,414c434,436
< if (prev_square != 0) {
< *self = squared_metric;
< v[prev_square-1] = _ex1;
---
> if (prev_square > -1) {
> *self = indexed(squared_metric, mu, mu_toggle);
> v[prev_square] = _ex1;
416c438
< *self = unit.get_metric(self->op(1), other->op(1));
---
> *self = unit.get_metric(mu, mu_toggle, true);
420,436c442,469
< // e~mu e~alpha e.mu = (2e~alpha^2-Tr) e~alpha
< } else if (other - self == 2
< && is_a<clifford>(self[1])) {
<
< const ex & ia = self[1].op(1);
< const ex & ib = self[1].op(1);
< if (is_a<tensmetric>(unit.get_metric()))
< *self = 2 - unit.get_metric(self->op(1), other->op(1));
< else if (prev_square != 0) {
< *self = 2-squared_metric;
< v[prev_square-1] = _ex1;
< } else
< *self = 2*unit.get_metric(ia, ib) - unit.get_metric(self->op(1), other->op(1));
< *other = _ex1;
< return true;
<
< // e~mu S e~alpha e.mu = 2 e~alpha^3 S - e~mu S e.mu e~alpha
---
> } else if (other - self == 2) {
> if (is_a<clifford>(*before_other) && ex_to<clifford>(*before_other).get_representation_label() == rl) {
> if (ex_to<clifford>(*self).is_anticommuting()) {
> // e~mu e~alpha e.mu = (2*pow(e~alpha, 2) -Tr(B)) e~alpha
> if (prev_square > -1) {
> *self = 2 * indexed(squared_metric, alpha, alpha)
> - indexed(squared_metric, mu, mu_toggle);
> v[prev_square] = _ex1;
> } else
> *self = 2 * unit.get_metric(alpha, alpha, true) - unit.get_metric(mu, mu_toggle, true);
> *other = _ex1;
> return true;
>
> } else {
> // e~mu e~alpha e.mu = 2*e~mu B(alpha, mu.toggle_variance())-Tr(B) e~alpha
> *self = 2 * (*self) * unit.get_metric(alpha, mu_toggle, true) - unit.get_metric(mu, mu_toggle, true) * (*before_other);
> *before_other = _ex1;
> *other = _ex1;
> return true;
> }
> } else {
> // e~mu S e.mu = Tr S ONE
> *self = unit.get_metric(mu, mu_toggle, true);
> *other = dirac_ONE(rl);
> return true;
> }
> } else {
> // e~mu S e~alpha e.mu = 2 e~mu S B(alpha, mu.toggle_variance()) - e~mu S e.mu e~alpha
439,452c472,475
< } else {
< exvector::iterator it = self + 1, next_to_last = other - 1;
< while (it != other) {
< if (!is_a<clifford>(*it))
< return false;
< ++it;
< }
<
< it = self + 1;
< ex S = _ex1;
< while (it != next_to_last) {
< S *= *it;
< *it++ = _ex1;
< }
---
> if (std::find_if(self + 1, other, is_not_a_clifford()) != other)
> return false;
>
> ex S = ncmul(exvector(self + 1, before_other), true);
454,464c477,490
< const ex & ia = next_to_last->op(1);
< const ex & ib = next_to_last->op(1);
< if (is_a<tensmetric>(unit.get_metric()))
< *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last);
< else if (prev_square != 0) {
< *self = 2 * (*next_to_last) * S - (*self) * S * (*other) * (*next_to_last)*unit.get_metric(self->op(1),self->op(1));
< v[prev_square-1] = _ex1;
< } else
< *self = 2 * (*next_to_last) * S* unit.get_metric(ia,ib) - (*self) * S * (*other) * (*next_to_last);
< *next_to_last = _ex1;
< *other = _ex1;
---
> if (is_a<clifford>(*before_other) && ex_to<clifford>(*before_other).get_representation_label() == rl)
> if (ex_to<clifford>(*self).is_anticommuting())
> if (prev_square > -1)
> *self = 2 * (*before_other) * S * indexed(squared_metric, alpha, alpha)
> - (*self) * S * (*other) * (*before_other);
> else
> *self = 2 * (*before_other) * S * unit.get_metric(alpha, alpha, true) - (*self) * S * (*other) * (*before_other);
> else
> *self = 2 * (*self) * S * unit.get_metric(alpha, mu_toggle, true) - (*self) * S * (*other) * (*before_other);
> else
> // simply commutes
> *self = (*self) * S * (*other) * (*before_other);
>
> std::fill(self + 1, other + 1, _ex1);
467d492
<
469d493
<
583c607
< a = ex_to<clifford>(a).get_metric(ia, ib);
---
> a = ex_to<clifford>(a).get_metric(ia, ib, true);
633c657
< return clifford(diracone(), representation_label) * sign;
---
> return dirac_ONE(representation_label) * sign;
642c666
< return clifford(representation_label, get_metric(), v);
---
> return clifford(representation_label, get_metric(), is_anticommuting(), v);
647c671
< return clifford(representation_label, get_metric(), vp);
---
> return clifford(representation_label, get_metric(), is_anticommuting(), vp);
672c696
< return clifford(ONE, rl);
---
> return clifford(ONE, rl, false);
675c699
< ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl)
---
> ex clifford_unit(const ex & mu, const ex & metr, unsigned char rl, bool anticommuting)
679,680c703,704
< if (!is_a<varidx>(mu))
< throw(std::invalid_argument("index of Clifford unit must be of type varidx"));
---
> if (!is_a<idx>(mu))
> throw(std::invalid_argument("clifford_unit(): index of Clifford unit must be of type idx or varidx"));
682,687c706,739
< if (is_a<indexed>(metr))
< return clifford(unit, mu, metr.op(0), rl);
< else if(is_a<tensmetric>(metr) || is_a<matrix>(metr))
< return clifford(unit, mu, metr, rl);
< else
< throw(std::invalid_argument("metric for Clifford unit must be of type indexed, tensormetric or matrix"));
---
> if (ex_to<idx>(mu).is_symbolic() && !is_a<varidx>(mu))
> throw(std::invalid_argument("clifford_unit(): symbolic index of Clifford unit must be of type varidx (not idx)"));
>
> if (is_a<indexed>(metr)) {
> exvector indices = ex_to<indexed>(metr).get_indices();
> if ((indices.size() == 2) && is_a<varidx>(indices[0]) && is_a<varidx>(indices[1]))
> return clifford(unit, mu, metr, rl, anticommuting);
> else
> throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be indexed exactly by two indices of same type as the given index"));
> } else if (is_a<tensmetric>(metr)) {
> static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
> chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
> return clifford(unit, mu, indexed(metr, xi, chi), rl, anticommuting);
> } else if (is_a<matrix>(metr)) {
> matrix M = ex_to<matrix>(metr);
> unsigned n = M.rows();
> bool symmetric = true;
> anticommuting = true;
>
> static varidx xi((new symbol)->setflag(status_flags::dynallocated), n),
> chi((new symbol)->setflag(status_flags::dynallocated), n);
> if ((n == M.cols()) && (n == ex_to<varidx>(mu).get_dim())) {
> for (unsigned i = 0; i < n; i++)
> for (unsigned j = i+1; j < n; j++) {
> if (M(i, j) != M(j, i))
> symmetric = false;
> if (M(i, j) != -M(j, i))
> anticommuting = false;
> }
> return clifford(unit, mu, indexed(metr, symmetric?symmetric2():not_symmetric(), xi, chi), rl, anticommuting);
> } else
> throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be a square matrix with the same dimensions as index"));
> } else
> throw(std::invalid_argument("clifford_unit(): metric for Clifford unit must be of type indexed, tensormetric or matrix"));
695c747
< throw(std::invalid_argument("index of Dirac gamma must be of type varidx"));
---
> throw(std::invalid_argument("dirac_gamma(): index of Dirac gamma must be of type varidx"));
697c749,751
< return clifford(gamma, mu, default_metric(), rl);
---
> static varidx xi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim()),
> chi((new symbol)->setflag(status_flags::dynallocated), ex_to<varidx>(mu).get_dim());
> return clifford(gamma, mu, indexed(default_metric(), symmetric2(), xi, chi), rl, true);
987c1041
< it[0] = (ex_to<clifford>(save0).get_metric(i1, i2) * b1 * b2).simplify_indexed();
---
> it[0] = (ex_to<clifford>(save0).get_metric(i1, i2, true) * b1 * b2).simplify_indexed();
1019c1073
< ex remove_dirac_ONE(const ex & e, unsigned char rl)
---
> ex remove_dirac_ONE(const ex & e, unsigned char rl)
1026c1080
< throw(std::invalid_argument("Expression is a non-scalar Clifford number!"));
---
> throw(std::invalid_argument("remove_dirac_ONE(): expression is a non-scalar Clifford number!"));
1035a1090,1105
> char clifford_max_label(const ex & e, bool ignore_ONE)
> {
> if (is_a<clifford>(e))
> if (ignore_ONE && is_a<diracone>(e.op(0)))
> return -1;
> else
> return ex_to<clifford>(e).get_representation_label();
> else {
> char rl = -1;
> for (size_t i=0; i < e.nops(); i++)
> rl = (rl > clifford_max_label(e.op(i), ignore_ONE)) ? rl : clifford_max_label(e.op(i), ignore_ONE);
> return rl;
> }
> }
>
>
1047c1117
< throw(std::invalid_argument("Cannot find inverse of Clifford number with zero norm!"));
---
> throw(std::invalid_argument("clifford_inverse(): cannot find inverse of Clifford number with zero norm!"));
1050c1120
< ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl)
---
> ex lst_to_clifford(const ex & v, const ex & mu, const ex & metr, unsigned char rl, bool anticommuting)
1053,1054c1123,1124
< throw(std::invalid_argument("Index should have a numeric dimension"));
< ex e = clifford_unit(mu, metr, rl);
---
> throw(std::invalid_argument("lst_to_clifford(): Index should have a numeric dimension"));
> ex e = clifford_unit(mu, metr, rl, anticommuting);
1077c1147
< throw(std::invalid_argument("Dimensions of vector and clifford unit mismatch"));
---
> throw(std::invalid_argument("lst_to_clifford(): dimensions of vector and clifford unit mismatch"));
1079c1149
< throw(std::invalid_argument("First argument should be a vector vector"));
---
> throw(std::invalid_argument("lst_to_clifford(): first argument should be a vector vector"));
1084c1154
< throw(std::invalid_argument("List length and dimension of clifford unit mismatch"));
---
> throw(std::invalid_argument("lst_to_clifford(): list length and dimension of clifford unit mismatch"));
1086c1156
< throw(std::invalid_argument("Cannot construct from anything but list or vector"));
---
> throw(std::invalid_argument("lst_to_clifford(): cannot construct from anything but list or vector"));
1088c1158
< throw(std::invalid_argument("The second argument should be a Clifford unit"));
---
> throw(std::invalid_argument("lst_to_clifford(): the second argument should be a Clifford unit"));
1090c1160
<
---
>
1109c1179
< throw(std::invalid_argument("Expression is a Clifford multi-vector"));
---
> throw(std::invalid_argument("get_clifford_comp(): expression is a Clifford multi-vector"));
1134c1204
< throw(std::invalid_argument("Expression is not a Clifford vector to the given units"));
---
> throw(std::invalid_argument("get_clifford_comp(): expression is not a Clifford vector to the given units"));
1144c1214
< throw(std::invalid_argument("Expression is not usable as a Clifford vector"));
---
> throw(std::invalid_argument("get_clifford_comp(): expression is not usable as a Clifford vector"));
1153c1223
< throw(std::invalid_argument("Index should have a numeric dimension"));
---
> throw(std::invalid_argument("clifford_to_lst(): index should have a numeric dimension"));
1176c1246
< 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)
---
> 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, bool anticommuting)
1181c1251
< throw(std::invalid_argument("parameter v should be either vector or list"));
---
> throw(std::invalid_argument("clifford_moebius_map(): parameter v should be either vector or list"));
1190c1260
< else throw(std::invalid_argument("metric should be an indexed object, matrix, or a Clifford unit"));
---
> else throw(std::invalid_argument("clifford_moebius_map(): metric should be an indexed object, matrix, or a Clifford unit"));
1193c1263
< cu = clifford_unit(mu, G, rl);
---
> cu = clifford_unit(mu, G, rl, anticommuting);
1195c1265
<
---
>
1201c1271
< ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl)
---
> ex clifford_moebius_map(const ex & M, const ex & v, const ex & G, unsigned char rl, bool anticommuting)
1205c1275
< ex_to<matrix>(M)(1,0), ex_to<matrix>(M)(1,1), v, G, rl);
---
> ex_to<matrix>(M)(1,0), ex_to<matrix>(M)(1,1), v, G, rl, anticommuting);
1207c1277
< throw(std::invalid_argument("parameter M should be a matrix"));
---
> throw(std::invalid_argument("clifford_moebius_map(): parameter M should be a matrix"));
More information about the GiNaC-devel
mailing list