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

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