- added Clifford contractions:
[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 "archive.h"
28 #include "debugmsg.h"
29 #include "utils.h"
30
31 #include <stdexcept>
32
33 namespace GiNaC {
34
35 GINAC_IMPLEMENT_REGISTERED_CLASS(clifford, indexed)
36 GINAC_IMPLEMENT_REGISTERED_CLASS(diracone, tensor)
37 GINAC_IMPLEMENT_REGISTERED_CLASS(diracgamma, tensor)
38
39 //////////
40 // default constructor, destructor, copy constructor assignment operator and helpers
41 //////////
42
43 clifford::clifford()
44 {
45         debugmsg("clifford default constructor", LOGLEVEL_CONSTRUCT);
46         tinfo_key = TINFO_clifford;
47 }
48
49 DEFAULT_COPY(clifford)
50 DEFAULT_DESTROY(clifford)
51 DEFAULT_CTORS(diracone)
52 DEFAULT_CTORS(diracgamma)
53
54 //////////
55 // other constructors
56 //////////
57
58 /** Construct object with one Lorentz index. This constructor is for internal
59  *  use only. Use the dirac_gamma() function instead.
60  *  @see dirac_gamma */
61 clifford::clifford(const ex & b, const ex & mu) : inherited(b, mu)
62 {
63         debugmsg("clifford constructor from ex,ex", LOGLEVEL_CONSTRUCT);
64         GINAC_ASSERT(is_ex_of_type(mu, varidx));
65         tinfo_key = TINFO_clifford;
66 }
67
68 /** Construct object without any indices. This constructor is for internal
69  *  use only. Use the dirac_one() function instead.
70  *  @see dirac_one */
71 clifford::clifford(const ex & b) : inherited(b)
72 {
73         debugmsg("clifford constructor from ex", LOGLEVEL_CONSTRUCT);
74         tinfo_key = TINFO_clifford;
75 }
76
77 clifford::clifford(const exvector & v, bool discardable) : inherited(indexed::unknown, v, discardable)
78 {
79         debugmsg("clifford constructor from exvector", LOGLEVEL_CONSTRUCT);
80         tinfo_key = TINFO_clifford;
81 }
82
83 clifford::clifford(exvector * vp) : inherited(indexed::unknown, vp)
84 {
85         debugmsg("clifford constructor from exvector *", LOGLEVEL_CONSTRUCT);
86         tinfo_key = TINFO_clifford;
87 }
88
89 //////////
90 // archiving
91 //////////
92
93 DEFAULT_ARCHIVING(clifford)
94 DEFAULT_ARCHIVING(diracone)
95 DEFAULT_ARCHIVING(diracgamma)
96
97 //////////
98 // functions overriding virtual functions from bases classes
99 //////////
100
101 int clifford::compare_same_type(const basic & other) const
102 {
103         return inherited::compare_same_type(other);
104 }
105
106 DEFAULT_COMPARE(diracone)
107 DEFAULT_COMPARE(diracgamma)
108 DEFAULT_PRINT(diracone, "ONE")
109 DEFAULT_PRINT(diracgamma, "gamma")
110
111 /** Contraction of a gamma matrix with something else. */
112 bool diracgamma::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
113 {
114         GINAC_ASSERT(is_ex_of_type(*self, indexed));
115         GINAC_ASSERT(is_ex_of_type(*other, indexed));
116         GINAC_ASSERT(is_ex_of_type(self->op(0), diracgamma));
117
118         if (is_ex_of_type(other->op(0), diracgamma)) {
119
120                 ex dim = ex_to_idx(self->op(1)).get_dim();
121
122                 // gamma~mu*gamma.mu = dim*ONE
123                 if (other - self == 1) {
124                         *self = dim;
125                         *other = dirac_one();
126                         return true;
127
128                 // gamma~mu*gamma~alpha*gamma.mu = (2-dim)*gamma~alpha
129                 } else if (other - self == 2
130                         && is_ex_of_type(self[1], clifford)) {
131                         *self = 2 - dim;
132                         *other = _ex1();
133                         return true;
134
135                 // gamma~mu*gamma~alpha*gamma~beta*gamma.mu = 4*g~alpha~beta+(dim-4)*gamam~alpha*gamma~beta
136                 } else if (other - self == 3
137                         && is_ex_of_type(self[1], clifford)
138                         && is_ex_of_type(self[2], clifford)) {
139                         *self = 4 * metric_tensor(self[1].op(1), self[2].op(1)) * dirac_one() + (dim - 4) * self[1] * self[2];
140                         self[1] = _ex1();
141                         self[2] = _ex1();
142                         *other = _ex1();
143                         return true;
144
145                 // 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
146                 } else if (other - self == 4
147                         && is_ex_of_type(self[1], clifford)
148                         && is_ex_of_type(self[2], clifford)
149                         && is_ex_of_type(self[3], clifford)) {
150                         *self = -2 * self[3] * self[2] * self[1] + (4 - dim) * self[1] * self[2] * self[3];
151                         self[1] = _ex1();
152                         self[2] = _ex1();
153                         self[3] = _ex1();
154                         *other = _ex1();
155                         return true;
156                 }
157         }
158
159         return false;
160 }
161
162 /** Perform automatic simplification on noncommutative product of clifford
163  *  objects. This removes superfluous ONEs. */
164 ex clifford::simplify_ncmul(const exvector & v) const
165 {
166         exvector s;
167         s.reserve(v.size());
168
169         exvector::const_iterator it = v.begin(), itend = v.end();
170         while (it != itend) {
171                 if (!is_ex_of_type(it->op(0), diracone))
172                         s.push_back(*it);
173                 it++;
174         }
175
176         if (s.size() == 0)
177                 return clifford(diracone());
178         else if (s.size() == v.size())
179                 return simplified_ncmul(v);
180         else
181                 return simplified_ncmul(s);
182 }
183
184 ex clifford::thisexprseq(const exvector & v) const
185 {
186         return clifford(v);
187 }
188
189 ex clifford::thisexprseq(exvector * vp) const
190 {
191         return clifford(vp);
192 }
193
194 //////////
195 // global functions
196 //////////
197
198 ex dirac_one(void)
199 {
200         return clifford(diracone());
201 }
202
203 ex dirac_gamma(const ex & mu)
204 {
205         if (!is_ex_of_type(mu, varidx))
206                 throw(std::invalid_argument("index of Dirac gamma must be of type varidx"));
207
208         return clifford(diracgamma(), mu);
209 }
210
211 } // namespace GiNaC