fb8185b6a3a118a4c2a49d20cd76f979034db264
[ginac.git] / ginac / tensor.h
1 /** @file tensor.h
2  *
3  *  Interface to GiNaC's special tensors. */
4
5 /*
6  *  GiNaC Copyright (C) 1999-2011 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 #include "archive.h"
28
29 namespace GiNaC {
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         // functions overriding virtual functions from base classes
39 protected:
40         unsigned return_type() const { return return_types::noncommutative_composite; }
41
42         // non-virtual functions in this class
43 public:
44         /** Replace dummy index in contracted-with object by the contracting
45          *  object's second index (used internally for delta and metric tensor
46          *  contractions. */
47         bool replace_contr_index(exvector::iterator self, exvector::iterator other) const;
48 };
49
50
51 /** This class represents the delta tensor. If indexed, it must have exactly
52  *  two indices of the same type. */
53 class tensdelta : public tensor
54 {
55         GINAC_DECLARE_REGISTERED_CLASS(tensdelta, tensor)
56
57         // functions overriding virtual functions from base classes
58 public:
59         bool info(unsigned inf) const;
60         ex eval_indexed(const basic & i) const;
61         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
62
63         // non-virtual functions in this class
64 protected:
65         unsigned return_type() const { return return_types::commutative; }
66         void do_print(const print_context & c, unsigned level) const;
67         void do_print_latex(const print_latex & c, unsigned level) const;
68 };
69 GINAC_DECLARE_UNARCHIVER(tensdelta);
70
71
72 /** This class represents a general metric tensor which can be used to
73  *  raise/lower indices. If indexed, it must have exactly two indices of the
74  *  same type which must be of class varidx or a subclass. */
75 class tensmetric : public tensor
76 {
77         GINAC_DECLARE_REGISTERED_CLASS(tensmetric, tensor)
78
79         // functions overriding virtual functions from base classes
80 public:
81         bool info(unsigned inf) const;
82         ex eval_indexed(const basic & i) const;
83         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
84
85         // non-virtual functions in this class
86 protected:
87         unsigned return_type() const { return return_types::commutative; }
88         void do_print(const print_context & c, unsigned level) const;
89 };
90 GINAC_DECLARE_UNARCHIVER(tensmetric);
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         bool info(unsigned inf) const;
108         ex eval_indexed(const basic & i) const;
109
110         /** Save (a.k.a. serialize) object into archive. */
111         void archive(archive_node& n) const;
112         /** Read (a.k.a. deserialize) object from archive. */
113         void read_archive(const archive_node& n, lst& syms);
114         // non-virtual functions in this class
115 protected:
116         unsigned return_type() const { return return_types::commutative; }
117         void do_print(const print_context & c, unsigned level) const;
118         void do_print_latex(const print_latex & c, unsigned level) const;
119
120         // member variables
121 private:
122         bool pos_sig; /**< If true, the metric is diag(-1,1,1...). Otherwise it is diag(1,-1,-1,...). */
123 };
124 GINAC_DECLARE_UNARCHIVER(minkmetric); 
125
126
127 /** This class represents an antisymmetric spinor metric tensor which
128  *  can be used to raise/lower indices of 2-component Weyl spinors. If
129  *  indexed, it must have exactly two indices of the same type which
130  *  must be of class spinidx or a subclass and have dimension 2. */
131 class spinmetric : public tensmetric
132 {
133         GINAC_DECLARE_REGISTERED_CLASS(spinmetric, tensmetric)
134
135         // functions overriding virtual functions from base classes
136 public:
137         bool info(unsigned inf) const;
138         ex eval_indexed(const basic & i) const;
139         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
140
141 protected:
142         void do_print(const print_context & c, unsigned level) const;
143         void do_print_latex(const print_latex & c, unsigned level) const;
144 };
145 GINAC_DECLARE_UNARCHIVER(spinmetric);
146
147
148 /** This class represents the totally antisymmetric epsilon tensor. If
149  *  indexed, all indices must be of the same type and their number must
150  *  be equal to the dimension of the index space. */
151 class tensepsilon : public tensor
152 {
153         GINAC_DECLARE_REGISTERED_CLASS(tensepsilon, tensor)
154
155         // other constructors
156 public:
157         tensepsilon(bool minkowski, bool pos_sig);
158
159         // functions overriding virtual functions from base classes
160 public:
161         bool info(unsigned inf) const;
162         ex eval_indexed(const basic & i) const;
163         bool contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const;
164
165         /** Save (a.k.a. serialize) object into archive. */
166         void archive(archive_node& n) const;
167         /** Read (a.k.a. deserialize) object from archive. */
168         void read_archive(const archive_node& n, lst& syms);
169         // non-virtual functions in this class
170 protected:
171         unsigned return_type() const { return return_types::commutative; }
172         void do_print(const print_context & c, unsigned level) const;
173         void do_print_latex(const print_latex & c, unsigned level) const;
174
175         // member variables
176 private:
177         bool minkowski; /**< If true, tensor is in Minkowski-type space. Otherwise it is in a Euclidean space. */
178         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. */
179 };
180 GINAC_DECLARE_UNARCHIVER(tensepsilon); 
181
182
183 // utility functions
184
185 /** Create a delta tensor with specified indices. The indices must be of class
186  *  idx or a subclass. The delta tensor is always symmetric and its trace is
187  *  the dimension of the index space.
188  *
189  *  @param i1 First index
190  *  @param i2 Second index
191  *  @return newly constructed delta tensor */
192 ex delta_tensor(const ex & i1, const ex & i2);
193
194 /** Create a symmetric metric tensor with specified indices. The indices
195  *  must be of class varidx or a subclass. A metric tensor with one
196  *  covariant and one contravariant index is equivalent to the delta tensor.
197  *
198  *  @param i1 First index
199  *  @param i2 Second index
200  *  @return newly constructed metric tensor */
201 ex metric_tensor(const ex & i1, const ex & i2);
202
203 /** Create a Minkowski metric tensor with specified indices. The indices
204  *  must be of class varidx or a subclass. The Lorentz metric is a symmetric
205  *  tensor with a matrix representation of diag(1,-1,-1,...) (negative
206  *  signature, the default) or diag(-1,1,1,...) (positive signature).
207  *
208  *  @param i1 First index
209  *  @param i2 Second index
210  *  @param pos_sig Whether the signature is positive
211  *  @return newly constructed Lorentz metric tensor */
212 ex lorentz_g(const ex & i1, const ex & i2, bool pos_sig = false);
213
214 /** Create a spinor metric tensor with specified indices. The indices must be
215  *  of class spinidx or a subclass and have a dimension of 2. The spinor
216  *  metric is an antisymmetric tensor with a matrix representation of
217  *  [[ [[ 0, 1 ]], [[ -1, 0 ]] ]].
218  *
219  *  @param i1 First index
220  *  @param i2 Second index
221  *  @return newly constructed spinor metric tensor */
222 ex spinor_metric(const ex & i1, const ex & i2);
223
224 /** Create an epsilon tensor in a Euclidean space with two indices. The
225  *  indices must be of class idx or a subclass, and have a dimension of 2.
226  *
227  *  @param i1 First index
228  *  @param i2 Second index
229  *  @return newly constructed epsilon tensor */
230 ex epsilon_tensor(const ex & i1, const ex & i2);
231
232 /** Create an epsilon tensor in a Euclidean space with three indices. The
233  *  indices must be of class idx or a subclass, and have a dimension of 3.
234  *
235  *  @param i1 First index
236  *  @param i2 Second index
237  *  @param i3 Third index
238  *  @return newly constructed epsilon tensor */
239 ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3);
240
241 /** Create an epsilon tensor in a Minkowski space with four indices. The
242  *  indices must be of class varidx or a subclass, and have a dimension of 4.
243  *
244  *  @param i1 First index
245  *  @param i2 Second index
246  *  @param i3 Third index
247  *  @param i4 Fourth index
248  *  @param pos_sig Whether the signature of the metric is positive
249  *  @return newly constructed epsilon tensor */
250 ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig = false);
251
252 } // namespace GiNaC
253
254 #endif // ndef GINAC_TENSOR_H