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