b424cedf4f47f28af1dd6207b78e4b4e75728941
[ginac.git] / ginac / tensor.h
1 /** @file tensor.h
2  *
3  *  Interface to GiNaC's special tensors. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2005 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
21  */
22
23 #ifndef __GINAC_TENSOR_H__
24 #define __GINAC_TENSOR_H__
25
26 #include "ex.h"
27
28 namespace GiNaC {
29
30
31 /** This class holds one of GiNaC's predefined special tensors such as the
32  *  delta and the metric tensors. They are represented without indices.
33  *  To attach indices to them, wrap them in an object of class indexed. */
34 class tensor : public basic
35 {
36         GINAC_DECLARE_REGISTERED_CLASS(tensor, basic)
37
38         // other constructors
39 protected:
40         tensor(tinfo_t ti) : inherited(ti) {}
41
42         // functions overriding virtual functions from base classes
43 protected:
44         unsigned return_type() const { return return_types::noncommutative_composite; }
45
46         // non-virtual functions in this class
47 public:
48         /** Replace dummy index in contracted-with object by the contracting
49          *  object's second index (used internally for delta and metric tensor
50          *  contractions. */
51         bool replace_contr_index(exvector::iterator self, exvector::iterator other) const;
52 };
53
54
55 /** This class represents the delta tensor. If indexed, it must have exactly
56  *  two indices of the same type. */
57 class tensdelta : public tensor
58 {
59         GINAC_DECLARE_REGISTERED_CLASS(tensdelta, tensor)
60
61         // functions overriding virtual functions from base classes
62 public:
63         ex eval_indexed(const basic & i) const;
64         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
65
66         // non-virtual functions in this class
67 protected:
68         unsigned return_type() const { return return_types::commutative; }
69         void do_print(const print_context & c, unsigned level) const;
70         void do_print_latex(const print_latex & c, unsigned level) const;
71 };
72
73
74 /** This class represents a general metric tensor which can be used to
75  *  raise/lower indices. If indexed, it must have exactly two indices of the
76  *  same type which must be of class varidx or a subclass. */
77 class tensmetric : public tensor
78 {
79         GINAC_DECLARE_REGISTERED_CLASS(tensmetric, tensor)
80
81         // functions overriding virtual functions from base classes
82 public:
83         ex eval_indexed(const basic & i) const;
84         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
85
86         // non-virtual functions in this class
87 protected:
88         unsigned return_type() const { return return_types::commutative; }
89         void do_print(const print_context & c, unsigned level) const;
90 };
91
92
93 /** This class represents a Minkowski metric tensor. It has all the
94  *  properties of a metric tensor and is (as a matrix) equal to
95  *  diag(1,-1,-1,...) or diag(-1,1,1,...). */
96 class minkmetric : public tensmetric
97 {
98         GINAC_DECLARE_REGISTERED_CLASS(minkmetric, tensmetric)
99
100         // other constructors
101 public:
102         /** Construct Lorentz metric tensor with given signature. */
103         minkmetric(bool pos_sig);
104
105         // functions overriding virtual functions from base classes
106 public:
107         ex eval_indexed(const basic & i) const;
108
109         // non-virtual functions in this class
110 protected:
111         unsigned return_type() const { return return_types::commutative; }
112         void do_print(const print_context & c, unsigned level) const;
113         void do_print_latex(const print_latex & c, unsigned level) const;
114
115         // member variables
116 private:
117         bool pos_sig; /**< If true, the metric is diag(-1,1,1...). Otherwise it is diag(1,-1,-1,...). */
118 };
119
120
121 /** This class represents an antisymmetric spinor metric tensor which
122  *  can be used to raise/lower indices of 2-component Weyl spinors. If
123  *  indexed, it must have exactly two indices of the same type which
124  *  must be of class spinidx or a subclass and have dimension 2. */
125 class spinmetric : public tensmetric
126 {
127         GINAC_DECLARE_REGISTERED_CLASS(spinmetric, tensmetric)
128
129         // functions overriding virtual functions from base classes
130 public:
131         ex eval_indexed(const basic & i) const;
132         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
133
134         // non-virtual functions in this class
135 protected:
136         void do_print(const print_context & c, unsigned level) const;
137         void do_print_latex(const print_latex & c, unsigned level) const;
138 };
139
140
141 /** This class represents the totally antisymmetric epsilon tensor. If
142  *  indexed, all indices must be of the same type and their number must
143  *  be equal to the dimension of the index space. */
144 class tensepsilon : public tensor
145 {
146         GINAC_DECLARE_REGISTERED_CLASS(tensepsilon, tensor)
147
148         // other constructors
149 public:
150         tensepsilon(bool minkowski, bool pos_sig);
151
152         // functions overriding virtual functions from base classes
153 public:
154         ex eval_indexed(const basic & i) const;
155         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
156
157         // non-virtual functions in this class
158 protected:
159         unsigned return_type() const { return return_types::commutative; }
160         void do_print(const print_context & c, unsigned level) const;
161         void do_print_latex(const print_latex & c, unsigned level) const;
162
163         // member variables
164 private:
165         bool minkowski; /**< If true, tensor is in Minkowski-type space. Otherwise it is in a Euclidean space. */
166         bool pos_sig;   /**< If true, the metric is assumed to be diag(-1,1,1...). Otherwise it is diag(1,-1,-1,...). This is only relevant if minkowski = true. */
167 };
168
169
170 // utility functions
171
172 /** Create a delta tensor with specified indices. The indices must be of class
173  *  idx or a subclass. The delta tensor is always symmetric and its trace is
174  *  the dimension of the index space.
175  *
176  *  @param i1 First index
177  *  @param i2 Second index
178  *  @return newly constructed delta tensor */
179 ex delta_tensor(const ex & i1, const ex & i2);
180
181 /** Create a symmetric metric tensor with specified indices. The indices
182  *  must be of class varidx or a subclass. A metric tensor with one
183  *  covariant and one contravariant index is equivalent to the delta tensor.
184  *
185  *  @param i1 First index
186  *  @param i2 Second index
187  *  @return newly constructed metric tensor */
188 ex metric_tensor(const ex & i1, const ex & i2);
189
190 /** Create a Minkowski metric tensor with specified indices. The indices
191  *  must be of class varidx or a subclass. The Lorentz metric is a symmetric
192  *  tensor with a matrix representation of diag(1,-1,-1,...) (negative
193  *  signature, the default) or diag(-1,1,1,...) (positive signature).
194  *
195  *  @param i1 First index
196  *  @param i2 Second index
197  *  @param pos_sig Whether the signature is positive
198  *  @return newly constructed Lorentz metric tensor */
199 ex lorentz_g(const ex & i1, const ex & i2, bool pos_sig = false);
200
201 /** Create a spinor metric tensor with specified indices. The indices must be
202  *  of class spinidx or a subclass and have a dimension of 2. The spinor
203  *  metric is an antisymmetric tensor with a matrix representation of
204  *  [[ [[ 0, 1 ]], [[ -1, 0 ]] ]].
205  *
206  *  @param i1 First index
207  *  @param i2 Second index
208  *  @return newly constructed spinor metric tensor */
209 ex spinor_metric(const ex & i1, const ex & i2);
210
211 /** Create an epsilon tensor in a Euclidean space with two indices. The
212  *  indices must be of class idx or a subclass, and have a dimension of 2.
213  *
214  *  @param i1 First index
215  *  @param i2 Second index
216  *  @return newly constructed epsilon tensor */
217 ex epsilon_tensor(const ex & i1, const ex & i2);
218
219 /** Create an epsilon tensor in a Euclidean space with three indices. The
220  *  indices must be of class idx or a subclass, and have a dimension of 3.
221  *
222  *  @param i1 First index
223  *  @param i2 Second index
224  *  @param i3 Third index
225  *  @return newly constructed epsilon tensor */
226 ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3);
227
228 /** Create an epsilon tensor in a Minkowski space with four indices. The
229  *  indices must be of class varidx or a subclass, and have a dimension of 4.
230  *
231  *  @param i1 First index
232  *  @param i2 Second index
233  *  @param i3 Third index
234  *  @param i4 Fourth index
235  *  @param pos_sig Whether the signature of the metric is positive
236  *  @return newly constructed epsilon tensor */
237 ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig = false);
238
239 } // namespace GiNaC
240
241 #endif // ndef __GINAC_TENSOR_H__