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