GiNaC 1.8.7
tensor.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2023 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#include "tensor.h"
24#include "idx.h"
25#include "indexed.h"
26#include "symmetry.h"
27#include "relational.h"
28#include "operators.h"
29#include "lst.h"
30#include "numeric.h"
31#include "matrix.h"
32#include "archive.h"
33#include "utils.h"
34
35#include <iostream>
36#include <stdexcept>
37#include <vector>
38
39namespace GiNaC {
40
42
44 print_func<print_dflt>(&tensdelta::do_print).
45 print_func<print_latex>(&tensdelta::do_print_latex))
46
48 print_func<print_dflt>(&tensmetric::do_print).
49 print_func<print_latex>(&tensmetric::do_print))
50
52 print_func<print_dflt>(&minkmetric::do_print).
53 print_func<print_latex>(&minkmetric::do_print_latex))
54
56 print_func<print_dflt>(&spinmetric::do_print).
57 print_func<print_latex>(&spinmetric::do_print_latex))
58
60 print_func<print_dflt>(&tensepsilon::do_print).
61 print_func<print_latex>(&tensepsilon::do_print_latex))
62
64// constructors
66
68{
70}
71
72DEFAULT_CTOR(tensdelta)
73DEFAULT_CTOR(tensmetric)
74
75minkmetric::minkmetric() : pos_sig(false)
76{
77}
78
79spinmetric::spinmetric()
80{
81}
82
83minkmetric::minkmetric(bool ps) : pos_sig(ps)
84{
85}
86
87tensepsilon::tensepsilon() : minkowski(false), pos_sig(false)
88{
89}
90
91tensepsilon::tensepsilon(bool mink, bool ps) : minkowski(mink), pos_sig(ps)
92{
93}
94
96// archiving
98
100{
101 inherited::read_archive(n, sym_lst);
102 n.find_bool("pos_sig", pos_sig);
103}
105
107{
108 inherited::archive(n);
109 n.add_bool("pos_sig", pos_sig);
110}
111
113{
114 inherited::read_archive(n, sym_lst);
115 n.find_bool("minkowski", minkowski);
116 n.find_bool("pos_sig", pos_sig);
117}
119
121{
122 inherited::archive(n);
123 n.add_bool("minkowski", minkowski);
124 n.add_bool("pos_sig", pos_sig);
125}
126
130
132// functions overriding virtual functions from base classes
134
139
140bool tensdelta::info(unsigned inf) const
141{
142 if(inf == info_flags::real)
143 return true;
144
145 return false;
146}
147
148bool tensmetric::info(unsigned inf) const
149{
150 if(inf == info_flags::real)
151 return true;
152
153 return false;
154}
155
156int minkmetric::compare_same_type(const basic & other) const
157{
158 GINAC_ASSERT(is_a<minkmetric>(other));
159 const minkmetric &o = static_cast<const minkmetric &>(other);
160
161 if (pos_sig != o.pos_sig)
162 return pos_sig ? -1 : 1;
163 else
164 return inherited::compare_same_type(other);
165}
166
167bool minkmetric::info(unsigned inf) const
168{
169 if(inf == info_flags::real)
170 return true;
171
172 return false;
173}
174
175int tensepsilon::compare_same_type(const basic & other) const
176{
177 GINAC_ASSERT(is_a<tensepsilon>(other));
178 const tensepsilon &o = static_cast<const tensepsilon &>(other);
179
180 if (minkowski != o.minkowski)
181 return minkowski ? -1 : 1;
182 else if (pos_sig != o.pos_sig)
183 return pos_sig ? -1 : 1;
184 else
185 return inherited::compare_same_type(other);
186}
187
188bool tensepsilon::info(unsigned inf) const
189{
190 if(inf == info_flags::real)
191 return true;
192
193 return false;
194}
195
196bool spinmetric::info(unsigned inf) const
197{
198 if(inf == info_flags::real)
199 return true;
200
201 return false;
202}
203
204DEFAULT_PRINT_LATEX(tensdelta, "delta", "\\delta")
206DEFAULT_PRINT_LATEX(minkmetric, "eta", "\\eta")
207DEFAULT_PRINT_LATEX(spinmetric, "eps", "\\varepsilon")
208DEFAULT_PRINT_LATEX(tensepsilon, "eps", "\\varepsilon")
209
211ex tensdelta::eval_indexed(const basic & i) const
212{
213 GINAC_ASSERT(is_a<indexed>(i));
214 GINAC_ASSERT(i.nops() == 3);
215 GINAC_ASSERT(is_a<tensdelta>(i.op(0)));
216
217 const idx & i1 = ex_to<idx>(i.op(1));
218 const idx & i2 = ex_to<idx>(i.op(2));
219
220 // The dimension of the indices must be equal, otherwise we use the minimal
221 // dimension
222 if (!i1.get_dim().is_equal(i2.get_dim())) {
223 ex min_dim = i1.minimal_dim(i2);
224 exmap m;
225 m[i1] = i1.replace_dim(min_dim);
226 m[i2] = i2.replace_dim(min_dim);
228 }
229
230 // Trace of delta tensor is the (effective) dimension of the space
231 if (is_dummy_pair(i1, i2)) {
232 try {
233 return i1.minimal_dim(i2);
234 } catch (std::exception &e) {
235 return i.hold();
236 }
237 }
238
239 // Numeric evaluation
240 if (static_cast<const indexed &>(i).all_index_values_are(info_flags::integer)) {
241 int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
242 if (n1 == n2)
243 return _ex1;
244 else
245 return _ex0;
246 }
247
248 // No further simplifications
249 return i.hold();
250}
251
254{
255 GINAC_ASSERT(is_a<indexed>(i));
256 GINAC_ASSERT(i.nops() == 3);
257 GINAC_ASSERT(is_a<tensmetric>(i.op(0)));
258 GINAC_ASSERT(is_a<varidx>(i.op(1)));
259 GINAC_ASSERT(is_a<varidx>(i.op(2)));
260
261 const varidx & i1 = ex_to<varidx>(i.op(1));
262 const varidx & i2 = ex_to<varidx>(i.op(2));
263
264 // The dimension of the indices must be equal, otherwise we use the minimal
265 // dimension
266 if (!i1.get_dim().is_equal(i2.get_dim())) {
267 ex min_dim = i1.minimal_dim(i2);
268 exmap m;
269 m[i1] = i1.replace_dim(min_dim);
270 m[i2] = i2.replace_dim(min_dim);
272 }
273
274 // A metric tensor with one covariant and one contravariant index gets
275 // replaced by a delta tensor
276 if (i1.is_covariant() != i2.is_covariant())
277 return delta_tensor(i1, i2);
278
279 // No further simplifications
280 return i.hold();
281}
282
285{
286 GINAC_ASSERT(is_a<indexed>(i));
287 GINAC_ASSERT(i.nops() == 3);
288 GINAC_ASSERT(is_a<minkmetric>(i.op(0)));
289 GINAC_ASSERT(is_a<varidx>(i.op(1)));
290 GINAC_ASSERT(is_a<varidx>(i.op(2)));
291
292 const varidx & i1 = ex_to<varidx>(i.op(1));
293 const varidx & i2 = ex_to<varidx>(i.op(2));
294
295 // Numeric evaluation
296 if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
297 int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
298 if (n1 != n2)
299 return _ex0;
300 else if (n1 == 0)
301 return pos_sig ? _ex_1 : _ex1;
302 else
303 return pos_sig ? _ex1 : _ex_1;
304 }
305
306 // Perform the usual evaluations of a metric tensor
307 return inherited::eval_indexed(i);
308}
309
312{
313 GINAC_ASSERT(is_a<indexed>(i));
314 GINAC_ASSERT(i.nops() == 3);
315 GINAC_ASSERT(is_a<spinmetric>(i.op(0)));
316 GINAC_ASSERT(is_a<spinidx>(i.op(1)));
317 GINAC_ASSERT(is_a<spinidx>(i.op(2)));
318
319 const spinidx & i1 = ex_to<spinidx>(i.op(1));
320 const spinidx & i2 = ex_to<spinidx>(i.op(2));
321
322 // Convolutions are zero
323 if (!(static_cast<const indexed &>(i).get_dummy_indices().empty()))
324 return _ex0;
325
326 // Numeric evaluation
327 if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
328 int n1 = ex_to<numeric>(i1.get_value()).to_int(), n2 = ex_to<numeric>(i2.get_value()).to_int();
329 if (n1 == n2)
330 return _ex0;
331 else if (n1 < n2)
332 return _ex1;
333 else
334 return _ex_1;
335 }
336
337 // No further simplifications
338 return i.hold();
339}
340
343{
344 GINAC_ASSERT(is_a<indexed>(i));
345 GINAC_ASSERT(i.nops() > 1);
346 GINAC_ASSERT(is_a<tensepsilon>(i.op(0)));
347
348 // Convolutions are zero
349 if (!(static_cast<const indexed &>(i).get_dummy_indices().empty()))
350 return _ex0;
351
352 // Numeric evaluation
353 if (static_cast<const indexed &>(i).all_index_values_are(info_flags::nonnegint)) {
354
355 // Get sign of index permutation (the indices should already be in
356 // a canonic order but we can't assume what exactly that order is)
357 std::vector<int> v;
358 v.reserve(i.nops() - 1);
359 for (size_t j=1; j<i.nops(); j++)
360 v.push_back(ex_to<numeric>(ex_to<idx>(i.op(j)).get_value()).to_int());
361 int sign = permutation_sign(v.begin(), v.end());
362
363 // In a Minkowski space, check for covariant indices
364 if (minkowski) {
365 for (size_t j=1; j<i.nops(); j++) {
366 const ex & x = i.op(j);
367 if (!is_a<varidx>(x)) {
368 throw(std::runtime_error("indices of epsilon tensor in Minkowski space must be of type varidx"));
369 }
370 if (ex_to<varidx>(x).is_covariant()) {
371 if (ex_to<idx>(x).get_value().is_zero()) {
372 sign = (pos_sig ? -sign : sign);
373 }
374 else {
375 sign = (pos_sig ? sign : -sign);
376 }
377 }
378 }
379 }
380
381 return sign;
382 }
383
384 // No further simplifications
385 return i.hold();
386}
387
388bool tensor::replace_contr_index(exvector::iterator self, exvector::iterator other) const
389{
390 // Try to contract the first index
391 const idx *self_idx = &ex_to<idx>(self->op(1));
392 const idx *free_idx = &ex_to<idx>(self->op(2));
393 bool first_index_tried = false;
394
395again:
396 if (self_idx->is_symbolic()) {
397 for (size_t i=1; i<other->nops(); i++) {
398 if (! is_a<idx>(other->op(i)))
399 continue;
400 const idx &other_idx = ex_to<idx>(other->op(i));
401 if (is_dummy_pair(*self_idx, other_idx)) {
402
403 // Contraction found, remove this tensor and substitute the
404 // index in the second object
405 try {
406 // minimal_dim() throws an exception when index dimensions are not comparable
407 ex min_dim = self_idx->minimal_dim(other_idx);
408 *other = other->subs(other_idx == free_idx->replace_dim(min_dim));
409 *self = _ex1; // *other is assigned first because assigning *self invalidates free_idx
410 return true;
411 } catch (std::exception &e) {
412 return false;
413 }
414 }
415 }
416 }
417
418 if (!first_index_tried) {
419
420 // No contraction with the first index found, try the second index
421 self_idx = &ex_to<idx>(self->op(2));
422 free_idx = &ex_to<idx>(self->op(1));
423 first_index_tried = true;
424 goto again;
425 }
426
427 return false;
428}
429
431bool tensdelta::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
432{
433 GINAC_ASSERT(is_a<indexed>(*self));
434 GINAC_ASSERT(is_a<indexed>(*other));
435 GINAC_ASSERT(self->nops() == 3);
436 GINAC_ASSERT(is_a<tensdelta>(self->op(0)));
437
438 // Replace the dummy index with this tensor's other index and remove
439 // the tensor (this is valid for contractions with all other tensors)
440 return replace_contr_index(self, other);
441}
442
444bool tensmetric::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
445{
446 GINAC_ASSERT(is_a<indexed>(*self));
447 GINAC_ASSERT(is_a<indexed>(*other));
448 GINAC_ASSERT(self->nops() == 3);
449 GINAC_ASSERT(is_a<tensmetric>(self->op(0)));
450
451 // If contracting with the delta tensor, let the delta do it
452 // (don't raise/lower delta indices)
453 if (is_a<tensdelta>(other->op(0)))
454 return false;
455
456 // Replace the dummy index with this tensor's other index and remove
457 // the tensor
458 return replace_contr_index(self, other);
459}
460
462bool spinmetric::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
463{
464 GINAC_ASSERT(is_a<indexed>(*self));
465 GINAC_ASSERT(is_a<indexed>(*other));
466 GINAC_ASSERT(self->nops() == 3);
467 GINAC_ASSERT(is_a<spinmetric>(self->op(0)));
468
469 // Contractions between spinor metrics
470 if (is_a<spinmetric>(other->op(0))) {
471 const idx &self_i1 = ex_to<idx>(self->op(1));
472 const idx &self_i2 = ex_to<idx>(self->op(2));
473 const idx &other_i1 = ex_to<idx>(other->op(1));
474 const idx &other_i2 = ex_to<idx>(other->op(2));
475
476 if (is_dummy_pair(self_i1, other_i1)) {
477 if (is_dummy_pair(self_i2, other_i2))
478 *self = _ex2;
479 else
480 *self = delta_tensor(self_i2, other_i2);
481 *other = _ex1;
482 return true;
483 } else if (is_dummy_pair(self_i1, other_i2)) {
484 if (is_dummy_pair(self_i2, other_i1))
485 *self = _ex_2;
486 else
487 *self = -delta_tensor(self_i2, other_i1);
488 *other = _ex1;
489 return true;
490 } else if (is_dummy_pair(self_i2, other_i1)) {
491 *self = -delta_tensor(self_i1, other_i2);
492 *other = _ex1;
493 return true;
494 } else if (is_dummy_pair(self_i2, other_i2)) {
495 *self = delta_tensor(self_i1, other_i1);
496 *other = _ex1;
497 return true;
498 }
499 }
500
501 // If contracting with the delta tensor, let the delta do it
502 // (don't raise/lower delta indices)
503 if (is_a<tensdelta>(other->op(0)))
504 return false;
505
506 // Try to contract first index
507 const idx *self_idx = &ex_to<idx>(self->op(1));
508 const idx *free_idx = &ex_to<idx>(self->op(2));
509 bool first_index_tried = false;
510 int sign = 1;
511
512again:
513 if (self_idx->is_symbolic()) {
514 for (size_t i=1; i<other->nops(); i++) {
515 const idx &other_idx = ex_to<idx>(other->op(i));
516 if (is_dummy_pair(*self_idx, other_idx)) {
517
518 // Contraction found, remove metric tensor and substitute
519 // index in second object (assign *self last because this
520 // invalidates free_idx)
521 *other = other->subs(other_idx == *free_idx);
522 *self = (static_cast<const spinidx *>(self_idx)->is_covariant() ? sign : -sign);
523 return true;
524 }
525 }
526 }
527
528 if (!first_index_tried) {
529
530 // No contraction with first index found, try second index
531 self_idx = &ex_to<idx>(self->op(2));
532 free_idx = &ex_to<idx>(self->op(1));
533 first_index_tried = true;
534 sign = -sign;
535 goto again;
536 }
537
538 return false;
539}
540
542bool tensepsilon::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
543{
544 GINAC_ASSERT(is_a<indexed>(*self));
545 GINAC_ASSERT(is_a<indexed>(*other));
546 GINAC_ASSERT(is_a<tensepsilon>(self->op(0)));
547 size_t num = self->nops() - 1;
548
549 if (is_exactly_a<tensepsilon>(other->op(0)) && num+1 == other->nops()) {
550
551 // Contraction of two epsilon tensors is a determinant
552 bool variance = is_a<varidx>(self->op(1));
553 matrix M(num, num);
554 for (size_t i=0; i<num; i++) {
555 for (size_t j=0; j<num; j++) {
556 if (minkowski)
557 M(i, j) = lorentz_g(self->op(i+1), other->op(j+1), pos_sig);
558 else if (variance)
559 M(i, j) = metric_tensor(self->op(i+1), other->op(j+1));
560 else
561 M(i, j) = delta_tensor(self->op(i+1), other->op(j+1));
562 }
563 }
564 int sign = minkowski ? -1 : 1;
565 *self = sign * M.determinant().simplify_indexed();
566 *other = _ex1;
567 return true;
568 }
569
570 return false;
571}
572
574// global functions
576
577ex delta_tensor(const ex & i1, const ex & i2)
578{
579 static ex delta = dynallocate<tensdelta>();
580
581 if (!is_a<idx>(i1) || !is_a<idx>(i2))
582 throw(std::invalid_argument("indices of delta tensor must be of type idx"));
583
584 return indexed(delta, symmetric2(), i1, i2);
585}
586
587ex metric_tensor(const ex & i1, const ex & i2)
588{
589 static ex metric = dynallocate<tensmetric>();
590
591 if (!is_a<varidx>(i1) || !is_a<varidx>(i2))
592 throw(std::invalid_argument("indices of metric tensor must be of type varidx"));
593
594 return indexed(metric, symmetric2(), i1, i2);
595}
596
597ex lorentz_g(const ex & i1, const ex & i2, bool pos_sig)
598{
599 static ex metric_neg = dynallocate<minkmetric>(false);
600 static ex metric_pos = dynallocate<minkmetric>(true);
601
602 if (!is_a<varidx>(i1) || !is_a<varidx>(i2))
603 throw(std::invalid_argument("indices of metric tensor must be of type varidx"));
604
605 return indexed(pos_sig ? metric_pos : metric_neg, symmetric2(), i1, i2);
606}
607
608ex spinor_metric(const ex & i1, const ex & i2)
609{
610 static ex metric = dynallocate<spinmetric>();
611
612 if (!is_a<spinidx>(i1) || !is_a<spinidx>(i2))
613 throw(std::invalid_argument("indices of spinor metric must be of type spinidx"));
614 if (!ex_to<idx>(i1).get_dim().is_equal(2) || !ex_to<idx>(i2).get_dim().is_equal(2))
615 throw(std::runtime_error("index dimension for spinor metric must be 2"));
616
617 return indexed(metric, antisymmetric2(), i1, i2);
618}
619
620ex epsilon_tensor(const ex & i1, const ex & i2)
621{
622 static ex epsilon = dynallocate<tensepsilon>();
623
624 if (!is_a<idx>(i1) || !is_a<idx>(i2))
625 throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
626
627 ex dim = ex_to<idx>(i1).get_dim();
628 if (!dim.is_equal(ex_to<idx>(i2).get_dim()))
629 throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
630 if (!ex_to<idx>(i1).get_dim().is_equal(_ex2))
631 throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
632
633 if(is_a<wildcard>(i1.op(0))||is_a<wildcard>(i2.op(0)))
634 return indexed(epsilon, antisymmetric2(), i1, i2).hold();
635
636 return indexed(epsilon, antisymmetric2(), i1, i2);
637}
638
639ex epsilon_tensor(const ex & i1, const ex & i2, const ex & i3)
640{
641 static ex epsilon = dynallocate<tensepsilon>();
642
643 if (!is_a<idx>(i1) || !is_a<idx>(i2) || !is_a<idx>(i3))
644 throw(std::invalid_argument("indices of epsilon tensor must be of type idx"));
645
646 ex dim = ex_to<idx>(i1).get_dim();
647 if (!dim.is_equal(ex_to<idx>(i2).get_dim()) || !dim.is_equal(ex_to<idx>(i3).get_dim()))
648 throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
649 if (!ex_to<idx>(i1).get_dim().is_equal(_ex3))
650 throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
651
652 if(is_a<wildcard>(i1.op(0))||is_a<wildcard>(i2.op(0))||is_a<wildcard>(i3.op(0)))
653 return indexed(epsilon, antisymmetric3(), i1, i2, i3).hold();
654
655 return indexed(epsilon, antisymmetric3(), i1, i2, i3);
656}
657
658ex lorentz_eps(const ex & i1, const ex & i2, const ex & i3, const ex & i4, bool pos_sig)
659{
660 static ex epsilon_neg = dynallocate<tensepsilon>(true, false);
661 static ex epsilon_pos = dynallocate<tensepsilon>(true, true);
662
663 if (!is_a<varidx>(i1) || !is_a<varidx>(i2) || !is_a<varidx>(i3) || !is_a<varidx>(i4))
664 throw(std::invalid_argument("indices of Lorentz epsilon tensor must be of type varidx"));
665
666 ex dim = ex_to<idx>(i1).get_dim();
667 if (!dim.is_equal(ex_to<idx>(i2).get_dim()) || !dim.is_equal(ex_to<idx>(i3).get_dim()) || !dim.is_equal(ex_to<idx>(i4).get_dim()))
668 throw(std::invalid_argument("all indices of epsilon tensor must have the same dimension"));
669 if (!ex_to<idx>(i1).get_dim().is_equal(_ex4))
670 throw(std::runtime_error("index dimension of epsilon tensor must match number of indices"));
671
672 if(is_a<wildcard>(i1.op(0))||is_a<wildcard>(i2.op(0))||is_a<wildcard>(i3.op(0))||is_a<wildcard>(i4.op(0)))
673 return indexed(pos_sig ? epsilon_pos : epsilon_neg, antisymmetric4(), i1, i2, i3, i4).hold();
674
675 return indexed(pos_sig ? epsilon_pos : epsilon_neg, antisymmetric4(), i1, i2, i3, i4);
676}
677
678} // namespace GiNaC
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition: assertion.h:33
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
Definition: archive.h:49
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition: basic.h:105
virtual size_t nops() const
Number of operands/members.
Definition: basic.cpp:229
virtual ex op(size_t i) const
Return operand/member at position i.
Definition: basic.cpp:238
const basic & hold() const
Stop further evaluation.
Definition: basic.cpp:887
virtual ex subs(const exmap &m, unsigned options=0) const
Substitute a set of objects by arbitrary expressions.
Definition: basic.cpp:607
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition: basic.cpp:719
Wrapper template for making GiNaC classes out of STL containers.
Definition: container.h:73
Lightweight wrapper for GiNaC's symbolic objects.
Definition: ex.h:72
bool is_equal(const ex &other) const
Definition: ex.h:345
ex simplify_indexed(unsigned options=0) const
Simplify/canonicalize expression containing indexed objects.
Definition: indexed.cpp:1256
ex subs(const exmap &m, unsigned options=0) const
Definition: ex.h:841
ex op(size_t i) const
Definition: ex.h:136
This class holds one index of an indexed object.
Definition: idx.h:36
ex replace_dim(const ex &new_dim) const
Make a new index with the same value but a different dimension.
Definition: idx.cpp:460
ex get_dim() const
Get dimension of index space.
Definition: idx.h:80
bool is_symbolic() const
Check whether the index is symbolic.
Definition: idx.h:77
ex minimal_dim(const idx &other) const
Return the minimum of the dimensions of this and another index.
Definition: idx.cpp:468
ex get_value() const
Get value of index.
Definition: idx.h:71
This class holds an indexed expression.
Definition: indexed.h:40
Symbolic matrices.
Definition: matrix.h:38
ex determinant(unsigned algo=determinant_algo::automatic) const
Determinant of square matrix.
Definition: matrix.cpp:737
This class represents a Minkowski metric tensor.
Definition: tensor.h:99
minkmetric(bool pos_sig)
Construct Lorentz metric tensor with given signature.
Definition: tensor.cpp:75
ex eval_indexed(const basic &i) const override
Automatic symbolic evaluation of an indexed Lorentz metric tensor.
Definition: tensor.cpp:284
bool pos_sig
If true, the metric is diag(-1,1,1...).
Definition: tensor.h:126
void archive(archive_node &n) const override
Save (a.k.a.
Definition: tensor.cpp:106
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
Definition: tensor.cpp:99
bool info(unsigned inf) const override
Information about the object.
Definition: tensor.cpp:167
Context for default (ginsh-parsable) output.
Definition: print.h:115
Context for latex-parsable output.
Definition: print.h:123
This class holds a spinor index that can be dotted or undotted and that also has a variance.
Definition: idx.h:160
This class represents an antisymmetric spinor metric tensor which can be used to raise/lower indices ...
Definition: tensor.h:136
bool info(unsigned inf) const override
Information about the object.
Definition: tensor.cpp:196
ex eval_indexed(const basic &i) const override
Automatic symbolic evaluation of an indexed metric tensor.
Definition: tensor.cpp:311
bool contract_with(exvector::iterator self, exvector::iterator other, exvector &v) const override
Contraction of an indexed spinor metric with something else.
Definition: tensor.cpp:462
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
Definition: flags.h:204
@ evaluated
.eval() has already done its job
Definition: flags.h:203
@ no_pattern
disable pattern matching
Definition: flags.h:51
This class represents the delta tensor.
Definition: tensor.h:54
bool contract_with(exvector::iterator self, exvector::iterator other, exvector &v) const override
Contraction of an indexed delta tensor with something else.
Definition: tensor.cpp:431
This class represents the totally antisymmetric epsilon tensor.
Definition: tensor.h:156
bool minkowski
If true, tensor is in Minkowski-type space.
Definition: tensor.h:183
bool pos_sig
If true, the metric is assumed to be diag(-1,1,1...).
Definition: tensor.h:184
void read_archive(const archive_node &n, lst &syms) override
Read (a.k.a.
Definition: tensor.cpp:112
bool contract_with(exvector::iterator self, exvector::iterator other, exvector &v) const override
Contraction of epsilon tensor with something else.
Definition: tensor.cpp:542
bool info(unsigned inf) const override
Information about the object.
Definition: tensor.cpp:188
tensepsilon(bool minkowski, bool pos_sig)
Definition: tensor.cpp:87
void archive(archive_node &n) const override
Save (a.k.a.
Definition: tensor.cpp:120
ex eval_indexed(const basic &i) const override
Automatic symbolic evaluation of an indexed epsilon tensor.
Definition: tensor.cpp:342
This class represents a general metric tensor which can be used to raise/lower indices.
Definition: tensor.h:77
bool info(unsigned inf) const override
Information about the object.
Definition: tensor.cpp:148
ex eval_indexed(const basic &i) const override
Automatic symbolic evaluation of an indexed metric tensor.
Definition: tensor.cpp:253
bool contract_with(exvector::iterator self, exvector::iterator other, exvector &v) const override
Contraction of an indexed metric tensor with something else.
Definition: tensor.cpp:444
This class holds one of GiNaC's predefined special tensors such as the delta and the metric tensors.
Definition: tensor.h:35
bool replace_contr_index(exvector::iterator self, exvector::iterator other) const
Replace dummy index in contracted-with object by the contracting object's second index (used internal...
Definition: tensor.cpp:388
This class holds an index with a variance (co- or contravariant).
Definition: idx.h:112
bool is_covariant() const
Check whether the index is covariant.
Definition: idx.h:135
size_t n
Definition: factor.cpp:1432
ex x
Definition: factor.cpp:1610
mvec m
Definition: factor.cpp:758
Interface to GiNaC's indices.
Interface to GiNaC's indexed expressions.
Definition of GiNaC's lst.
Interface to symbolic matrices.
Definition: add.cpp:38
const symmetry & antisymmetric4()
Definition: symmetry.cpp:386
bool is_zero(const ex &thisex)
Definition: ex.h:835
const ex _ex2
Definition: utils.cpp:389
ex spinor_metric(const ex &i1, const ex &i2)
Create a spinor metric tensor with specified indices.
Definition: tensor.cpp:608
ex metric_tensor(const ex &i1, const ex &i2)
Create a symmetric metric tensor with specified indices.
Definition: tensor.cpp:587
std::map< ex, ex, ex_is_less > exmap
Definition: basic.h:50
const symmetry & antisymmetric3()
Definition: symmetry.cpp:380
const ex _ex1
Definition: utils.cpp:385
const symmetry & antisymmetric2()
Definition: symmetry.cpp:374
const ex _ex3
Definition: utils.cpp:393
const symmetry & symmetric2()
Definition: symmetry.cpp:356
const ex _ex_1
Definition: utils.cpp:352
bool is_dummy_pair(const idx &i1, const idx &i2)
Check whether two indices form a dummy pair.
Definition: idx.cpp:502
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(add, expairseq, print_func< print_context >(&add::do_print). print_func< print_latex >(&add::do_print_latex). print_func< print_csrc >(&add::do_print_csrc). print_func< print_tree >(&add::do_print_tree). print_func< print_python_repr >(&add::do_print_python_repr)) add
Definition: add.cpp:40
const ex _ex_2
Definition: utils.cpp:348
const ex _ex4
Definition: utils.cpp:397
ex delta_tensor(const ex &i1, const ex &i2)
Create a delta tensor with specified indices.
Definition: tensor.cpp:577
ex lorentz_eps(const ex &i1, const ex &i2, const ex &i3, const ex &i4, bool pos_sig)
Create an epsilon tensor in a Minkowski space with four indices.
Definition: tensor.cpp:658
ex lorentz_g(const ex &i1, const ex &i2, bool pos_sig)
Create a Minkowski metric tensor with specified indices.
Definition: tensor.cpp:597
int permutation_sign(It first, It last)
Definition: utils.h:77
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT_T(lst, basic, print_func< print_context >(&lst::do_print). print_func< print_tree >(&lst::do_print_tree)) template<> bool lst GINAC_BIND_UNARCHIVER(lst)
Specialization of container::info() for lst.
Definition: lst.cpp:42
const ex _ex0
Definition: utils.cpp:369
std::vector< ex > exvector
Definition: basic.h:48
ex epsilon_tensor(const ex &i1, const ex &i2)
Create an epsilon tensor in a Euclidean space with two indices.
Definition: tensor.cpp:620
Makes the interface to the underlying bignum package available.
Interface to GiNaC's overloaded operators.
#define GINAC_IMPLEMENT_REGISTERED_CLASS(classname, supername)
Macro for inclusion in the implementation of each registered class.
Definition: registrar.h:180
Interface to relations between expressions.
Interface to GiNaC's symmetry definitions.
Interface to GiNaC's special tensors.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...
#define DEFAULT_PRINT_LATEX(classname, text, latex)
Definition: utils.h:622
#define DEFAULT_PRINT(classname, text)
Definition: utils.h:616
#define DEFAULT_CTOR(classname)
Definition: utils.h:606
#define DEFAULT_COMPARE(classname)
Definition: utils.h:609

This page is part of the GiNaC developer's reference. It was generated automatically by doxygen. For an introduction, see the tutorial.