- replaced the various print*() member functions by a single print() that
[ginac.git] / ginac / clifford.cpp
1 /** @file clifford.cpp
2  *
3  *  Implementation of GiNaC's clifford algebra (Dirac gamma) objects. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany
7  *
8  *  This program is free software; you can redistribute it and/or modify
9  *  it under the terms of the GNU General Public License as published by
10  *  the Free Software Foundation; either version 2 of the License, or
11  *  (at your option) any later version.
12  *
13  *  This program is distributed in the hope that it will be useful,
14  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16  *  GNU General Public License for more details.
17  *
18  *  You should have received a copy of the GNU General Public License
19  *  along with this program; if not, write to the Free Software
20  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
21  */
22
23 #include "clifford.h"
24 #include "ex.h"
25 #include "idx.h"
26 #include "ncmul.h"
27 #include "print.h"
28 #include "archive.h"
29 #include "debugmsg.h"
30 #include "utils.h"
31
32 #include <stdexcept>
33
34 namespace GiNaC {
35
36 GINAC_IMPLEMENT_REGISTERED_CLASS(clifford, indexed)
37 GINAC_IMPLEMENT_REGISTERED_CLASS(diracone, tensor)
38 GINAC_IMPLEMENT_REGISTERED_CLASS(diracgamma, tensor)
39
40 //////////
41 // default constructor, destructor, copy constructor assignment operator and helpers
42 //////////
43
44 clifford::clifford()
45 {
46         debugmsg("clifford default constructor", LOGLEVEL_CONSTRUCT);
47         tinfo_key = TINFO_clifford;
48 }
49
50 DEFAULT_COPY(clifford)
51 DEFAULT_DESTROY(clifford)
52 DEFAULT_CTORS(diracone)
53 DEFAULT_CTORS(diracgamma)
54
55 //////////
56 // other constructors
57 //////////
58
59 /** Construct object with one Lorentz index. This constructor is for internal
60  *  use only. Use the dirac_gamma() function instead.
61  *  @see dirac_gamma */
62 clifford::clifford(const ex & b, const ex & mu) : inherited(b, mu)
63 {
64         debugmsg("clifford constructor from ex,ex", LOGLEVEL_CONSTRUCT);
65         GINAC_ASSERT(is_ex_of_type(mu, varidx));
66         tinfo_key = TINFO_clifford;
67 }
68
69 /** Construct object without any indices. This constructor is for internal
70  *  use only. Use the dirac_one() function instead.
71  *  @see dirac_one */
72 clifford::clifford(const ex & b) : inherited(b)
73 {
74         debugmsg("clifford constructor from ex", LOGLEVEL_CONSTRUCT);
75         tinfo_key = TINFO_clifford;
76 }
77
78 clifford::clifford(const exvector & v, bool discardable) : inherited(indexed::unknown, v, discardable)
79 {
80         debugmsg("clifford constructor from exvector", LOGLEVEL_CONSTRUCT);
81         tinfo_key = TINFO_clifford;
82 }
83
84 clifford::clifford(exvector * vp) : inherited(indexed::unknown, vp)
85 {
86         debugmsg("clifford constructor from exvector *", LOGLEVEL_CONSTRUCT);
87         tinfo_key = TINFO_clifford;
88 }
89
90 //////////
91 // archiving
92 //////////
93
94 DEFAULT_ARCHIVING(clifford)
95 DEFAULT_ARCHIVING(diracone)
96 DEFAULT_ARCHIVING(diracgamma)
97
98 //////////
99 // functions overriding virtual functions from bases classes
100 //////////
101
102 int clifford::compare_same_type(const basic & other) const
103 {
104         return inherited::compare_same_type(other);
105 }
106
107 DEFAULT_COMPARE(diracone)
108 DEFAULT_COMPARE(diracgamma)
109 DEFAULT_PRINT(diracone, "ONE")
110 DEFAULT_PRINT(diracgamma, "gamma")
111
112 /** Contraction of a gamma matrix with something else. */
113 bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
114 {
115         GINAC_ASSERT(is_ex_of_type(*self, indexed));
116         GINAC_ASSERT(is_ex_of_type(*other, indexed));
117         GINAC_ASSERT(is_ex_of_type(self->op(0), diracgamma));
118
119         if (is_ex_of_type(other->op(0), diracgamma)) {
120
121                 ex dim = ex_to_idx(self->op(1)).get_dim();
122
123                 // gamma~mu*gamma.mu = dim*ONE
124                 if (other - self == 1) {
125                         *self = dim;
126                         *other = dirac_one();
127                         return true;
128
129                 // gamma~mu*gamma~alpha*gamma.mu = (2-dim)*gamma~alpha
130                 } else if (other - self == 2
131                         && is_ex_of_type(self[1], clifford)) {
132                         *self = 2 - dim;
133                         *other = _ex1();
134                         return true;
135
136                 // gamma~mu*gamma~alpha*gamma~beta*gamma.mu = 4*g~alpha~beta+(dim-4)*gamam~alpha*gamma~beta
137                 } else if (other - self == 3
138                         && is_ex_of_type(self[1], clifford)
139                         && is_ex_of_type(self[2], clifford)) {
140                         *self = 4 * metric_tensor(self[1].op(1), self[2].op(1)) * dirac_one() + (dim - 4) * self[1] * self[2];
141                         self[1] = _ex1();
142                         self[2] = _ex1();
143                         *other = _ex1();
144                         return true;
145
146                 // gamma~mu*gamma~alpha*gamma~beta*gamma~delta*gamma.mu = -2*gamma~delta*gamma~beta*gamma~alpha+(4-dim)*gamma~alpha*gamma~beta*gamma~delta
147                 } else if (other - self == 4
148                         && is_ex_of_type(self[1], clifford)
149                         && is_ex_of_type(self[2], clifford)
150                         && is_ex_of_type(self[3], clifford)) {
151                         *self = -2 * self[3] * self[2] * self[1] + (4 - dim) * self[1] * self[2] * self[3];
152                         self[1] = _ex1();
153                         self[2] = _ex1();
154                         self[3] = _ex1();
155                         *other = _ex1();
156                         return true;
157                 }
158         }
159
160         return false;
161 }
162
163 /** Perform automatic simplification on noncommutative product of clifford
164  *  objects. This removes superfluous ONEs. */
165 ex clifford::simplify_ncmul(const exvector & v) const
166 {
167         exvector s;
168         s.reserve(v.size());
169
170         exvector::const_iterator it = v.begin(), itend = v.end();
171         while (it != itend) {
172                 if (!is_ex_of_type(it->op(0), diracone))
173                         s.push_back(*it);
174                 it++;
175         }
176
177         if (s.size() == 0)
178                 return clifford(diracone());
179         else if (s.size() == v.size())
180                 return simplified_ncmul(v);
181         else
182                 return simplified_ncmul(s);
183 }
184
185 ex clifford::thisexprseq(const exvector & v) const
186 {
187         return clifford(v);
188 }
189
190 ex clifford::thisexprseq(exvector * vp) const
191 {
192         return clifford(vp);
193 }
194
195 //////////
196 // global functions
197 //////////
198
199 ex dirac_one(void)
200 {
201         return clifford(diracone());
202 }
203
204 ex dirac_gamma(const ex & mu)
205 {
206         if (!is_ex_of_type(mu, varidx))
207                 throw(std::invalid_argument("index of Dirac gamma must be of type varidx"));
208
209         return clifford(diracgamma(), mu);
210 }
211
212 } // namespace GiNaC