- added Clifford algebra unity element
[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                 // gamma~mu*gamma.mu = dim*ONE
121                 if (other - self == 1) {
122                         *self = ex_to_idx(self->op(1)).get_dim();
123                         *other = dirac_one();
124                         return true;
125
126                 // gamma~mu*gamma~alpha*gamma.mu = (2-dim)*gamma~alpha
127                 } else if (other - self == 2) {
128                         *self = 2 - ex_to_idx(self->op(1)).get_dim();
129                         *other = _ex1();
130                         return true;
131                 }
132         }
133
134         return false;
135 }
136
137 /** Perform automatic simplification on noncommutative product of clifford
138  *  objects. This removes superfluous ONEs. */
139 ex clifford::simplify_ncmul(const exvector & v) const
140 {
141         exvector s;
142         s.reserve(v.size());
143
144         exvector::const_iterator it = v.begin(), itend = v.end();
145         while (it != itend) {
146                 if (!is_ex_of_type(it->op(0), diracone))
147                         s.push_back(*it);
148                 it++;
149         }
150
151         if (s.size() == 0)
152                 return clifford(diracone());
153         else if (s.size() == v.size())
154                 return simplified_ncmul(v);
155         else
156                 return simplified_ncmul(s);
157 }
158
159 ex clifford::thisexprseq(const exvector & v) const
160 {
161         return clifford(v);
162 }
163
164 ex clifford::thisexprseq(exvector * vp) const
165 {
166         return clifford(vp);
167 }
168
169 //////////
170 // global functions
171 //////////
172
173 ex dirac_one(void)
174 {
175         return clifford(diracone());
176 }
177
178 ex dirac_gamma(const ex & mu)
179 {
180         if (!is_ex_of_type(mu, varidx))
181                 throw(std::invalid_argument("index of Dirac gamma must be of type varidx"));
182
183         return clifford(diracgamma(), mu);
184 }
185
186 } // namespace GiNaC