GiNaC  1.8.3
tensor.cpp
Go to the documentation of this file.
1 
5 /*
6  * GiNaC Copyright (C) 1999-2022 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 
39 namespace 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 
67 tensor::tensor()
68 {
70 }
71 
72 DEFAULT_CTOR(tensdelta)
73 DEFAULT_CTOR(tensmetric)
74 
75 minkmetric::minkmetric() : pos_sig(false)
76 {
77 }
78 
79 spinmetric::spinmetric()
80 {
81 }
82 
83 minkmetric::minkmetric(bool ps) : pos_sig(ps)
84 {
85 }
86 
87 tensepsilon::tensepsilon() : minkowski(false), pos_sig(false)
88 {
89 }
90 
91 tensepsilon::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 
140 bool tensdelta::info(unsigned inf) const
141 {
142  if(inf == info_flags::real)
143  return true;
144 
145  return false;
146 }
147 
148 bool tensmetric::info(unsigned inf) const
149 {
150  if(inf == info_flags::real)
151  return true;
152 
153  return false;
154 }
155 
156 int 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 
167 bool minkmetric::info(unsigned inf) const
168 {
169  if(inf == info_flags::real)
170  return true;
171 
172  return false;
173 }
174 
175 int 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 
188 bool tensepsilon::info(unsigned inf) const
189 {
190  if(inf == info_flags::real)
191  return true;
192 
193  return false;
194 }
195 
196 bool spinmetric::info(unsigned inf) const
197 {
198  if(inf == info_flags::real)
199  return true;
200 
201  return false;
202 }
203 
204 DEFAULT_PRINT_LATEX(tensdelta, "delta", "\\delta")
206 DEFAULT_PRINT_LATEX(minkmetric, "eta", "\\eta")
207 DEFAULT_PRINT_LATEX(spinmetric, "eps", "\\varepsilon")
208 DEFAULT_PRINT_LATEX(tensepsilon, "eps", "\\varepsilon")
209 
211 ex 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);
227  return i.subs(m, subs_options::no_pattern);
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);
271  return i.subs(m, subs_options::no_pattern);
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 
388 bool 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 
395 again:
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 
431 bool 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 
444 bool 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 
462 bool 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 
512 again:
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 
542 bool 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 
577 ex 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 
587 ex 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 
597 ex 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 
608 ex 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 
620 ex 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 
639 ex 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 
658 ex 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:826
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:81
bool is_symbolic() const
Check whether the index is symbolic.
Definition: idx.h:78
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:72
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:162
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:113
bool is_covariant() const
Check whether the index is covariant.
Definition: idx.h:137
ex x
Definition: factor.cpp:1641
size_t n
Definition: factor.cpp:1463
mvec m
Definition: factor.cpp:771
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:820
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
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 _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
const ex _ex0
Definition: utils.cpp:369
std::vector< ex > exvector
Definition: basic.h:46
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.