GiNaC  1.8.3
idx.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 "idx.h"
24 #include "symbol.h"
25 #include "lst.h"
26 #include "relational.h"
27 #include "operators.h"
28 #include "archive.h"
29 #include "utils.h"
30 #include "hash_seed.h"
31 
32 #include <iostream>
33 #include <sstream>
34 #include <stdexcept>
35 
36 namespace GiNaC {
37 
40  print_func<print_latex>(&idx::do_print_latex).
41  print_func<print_csrc>(&idx::do_print_csrc).
42  print_func<print_tree>(&idx::do_print_tree))
43 
45  print_func<print_context>(&varidx::do_print).
46  print_func<print_latex>(&varidx::do_print_latex).
47  print_func<print_tree>(&varidx::do_print_tree))
48 
50  print_func<print_context>(&spinidx::do_print).
51  print_func<print_latex>(&spinidx::do_print_latex).
52  print_func<print_tree>(&spinidx::do_print_tree))
53 
55 // default constructor
57 
58 idx::idx() {}
59 
60 varidx::varidx() : covariant(false)
61 {
62 }
63 
64 spinidx::spinidx() : dotted(false)
65 {
66 }
67 
69 // other constructors
71 
72 idx::idx(const ex & v, const ex & d) : value(v), dim(d)
73 {
74  if (is_dim_numeric())
76  throw(std::invalid_argument("dimension of space must be a positive integer"));
77 }
78 
79 varidx::varidx(const ex & v, const ex & d, bool cov) : inherited(v, d), covariant(cov)
80 {
81 }
82 
83 spinidx::spinidx(const ex & v, const ex & d, bool cov, bool dot) : inherited(v, d, cov), dotted(dot)
84 {
85 }
86 
88 // archiving
90 
91 void idx::read_archive(const archive_node& n, lst& sym_lst)
92 {
93  inherited::read_archive(n, sym_lst);
94  n.find_ex("value", value, sym_lst);
95  n.find_ex("dim", dim, sym_lst);
96 }
98 
99 void varidx::read_archive(const archive_node& n, lst& sym_lst)
100 {
101  inherited::read_archive(n, sym_lst);
102  n.find_bool("covariant", covariant);
103 }
105 
106 void spinidx::read_archive(const archive_node& n, lst& sym_lst)
107 {
108  inherited::read_archive(n, sym_lst);
109  n.find_bool("dotted", dotted);
110 }
112 
114 {
115  inherited::archive(n);
116  n.add_ex("value", value);
117  n.add_ex("dim", dim);
118 }
119 
121 {
122  inherited::archive(n);
123  n.add_bool("covariant", covariant);
124 }
125 
127 {
128  inherited::archive(n);
129  n.add_bool("dotted", dotted);
130 }
131 
133 // functions overriding virtual functions from base classes
135 
136 void idx::print_index(const print_context & c, unsigned level) const
137 {
138  bool need_parens = !(is_exactly_a<numeric>(value) || is_a<symbol>(value));
139  if (need_parens)
140  c.s << "(";
141  value.print(c);
142  if (need_parens)
143  c.s << ")";
145  c.s << "[";
146  dim.print(c);
147  c.s << "]";
148  }
149 }
150 
151 void idx::do_print(const print_context & c, unsigned level) const
152 {
153  c.s << ".";
154  print_index(c, level);
155 }
156 
157 void idx::do_print_latex(const print_latex & c, unsigned level) const
158 {
159  c.s << "{";
160  print_index(c, level);
161  c.s << "}";
162 }
163 
164 void idx::do_print_csrc(const print_csrc & c, unsigned level) const
165 {
166  c.s << "[";
168  c.s << ex_to<numeric>(value).to_int();
169  else
170  value.print(c);
171  c.s << "]";
172 }
173 
174 void idx::do_print_tree(const print_tree & c, unsigned level) const
175 {
176  c.s << std::string(level, ' ') << class_name() << " @" << this
177  << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
178  << std::endl;
179  value.print(c, level + c.delta_indent);
180  dim.print(c, level + c.delta_indent);
181 }
182 
183 void varidx::do_print(const print_context & c, unsigned level) const
184 {
185  if (covariant)
186  c.s << ".";
187  else
188  c.s << "~";
189  print_index(c, level);
190 }
191 
192 void varidx::do_print_tree(const print_tree & c, unsigned level) const
193 {
194  c.s << std::string(level, ' ') << class_name() << " @" << this
195  << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
196  << (covariant ? ", covariant" : ", contravariant")
197  << std::endl;
198  value.print(c, level + c.delta_indent);
199  dim.print(c, level + c.delta_indent);
200 }
201 
202 void spinidx::do_print(const print_context & c, unsigned level) const
203 {
204  if (covariant)
205  c.s << ".";
206  else
207  c.s << "~";
208  if (dotted)
209  c.s << "*";
210  print_index(c, level);
211 }
212 
213 void spinidx::do_print_latex(const print_latex & c, unsigned level) const
214 {
215  if (dotted)
216  c.s << "\\dot{";
217  else
218  c.s << "{";
219  print_index(c, level);
220  c.s << "}";
221 }
222 
223 void spinidx::do_print_tree(const print_tree & c, unsigned level) const
224 {
225  c.s << std::string(level, ' ') << class_name() << " @" << this
226  << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec
227  << (covariant ? ", covariant" : ", contravariant")
228  << (dotted ? ", dotted" : ", undotted")
229  << std::endl;
230  value.print(c, level + c.delta_indent);
231  dim.print(c, level + c.delta_indent);
232 }
233 
234 bool idx::info(unsigned inf) const
235 {
236  switch(inf) {
237  case info_flags::idx:
239  return true;
240  }
241  return inherited::info(inf);
242 }
243 
244 size_t idx::nops() const
245 {
246  // don't count the dimension as that is not really a sub-expression
247  return 1;
248 }
249 
250 ex idx::op(size_t i) const
251 {
252  GINAC_ASSERT(i == 0);
253  return value;
254 }
255 
257 {
258  const ex &mapped_value = f(value);
259  if (are_ex_trivially_equal(value, mapped_value))
260  return *this;
261  else {
262  idx *copy = duplicate();
264  copy->value = mapped_value;
265  return *copy;
266  }
267 }
268 
271 int idx::compare_same_type(const basic & other) const
272 {
273  GINAC_ASSERT(is_a<idx>(other));
274  const idx &o = static_cast<const idx &>(other);
275 
276  int cmpval = value.compare(o.value);
277  if (cmpval)
278  return cmpval;
279  return dim.compare(o.dim);
280 }
281 
282 bool idx::match_same_type(const basic & other) const
283 {
284  GINAC_ASSERT(is_a<idx>(other));
285  const idx &o = static_cast<const idx &>(other);
286 
287  return dim.is_equal(o.dim);
288 }
289 
290 int varidx::compare_same_type(const basic & other) const
291 {
292  GINAC_ASSERT(is_a<varidx>(other));
293  const varidx &o = static_cast<const varidx &>(other);
294 
295  int cmpval = inherited::compare_same_type(other);
296  if (cmpval)
297  return cmpval;
298 
299  // Check variance last so dummy indices will end up next to each other
300  if (covariant != o.covariant)
301  return covariant ? -1 : 1;
302 
303  return 0;
304 }
305 
306 bool varidx::match_same_type(const basic & other) const
307 {
308  GINAC_ASSERT(is_a<varidx>(other));
309  const varidx &o = static_cast<const varidx &>(other);
310 
311  if (covariant != o.covariant)
312  return false;
313 
314  return inherited::match_same_type(other);
315 }
316 
317 int spinidx::compare_same_type(const basic & other) const
318 {
319  GINAC_ASSERT(is_a<spinidx>(other));
320  const spinidx &o = static_cast<const spinidx &>(other);
321 
322  // Check dottedness first so dummy indices will end up next to each other
323  if (dotted != o.dotted)
324  return dotted ? -1 : 1;
325 
326  int cmpval = inherited::compare_same_type(other);
327  if (cmpval)
328  return cmpval;
329 
330  return 0;
331 }
332 
333 bool spinidx::match_same_type(const basic & other) const
334 {
335  GINAC_ASSERT(is_a<spinidx>(other));
336  const spinidx &o = static_cast<const spinidx &>(other);
337 
338  if (dotted != o.dotted)
339  return false;
340  return inherited::match_same_type(other);
341 }
342 
343 unsigned idx::calchash() const
344 {
345  // NOTE: The code in simplify_indexed() assumes that canonically
346  // ordered sequences of indices have the two members of dummy index
347  // pairs lying next to each other. The hash values for indices must
348  // be devised accordingly. The easiest (only?) way to guarantee the
349  // desired ordering is to make indices with the same value have equal
350  // hash keys. That is, the hash values must not depend on the index
351  // dimensions or other attributes (variance etc.).
352  // The compare_same_type() methods will take care of the rest.
353  unsigned v = make_hash_seed(typeid(*this));
354  v = rotate_left(v);
355  v ^= value.gethash();
356 
357  // Store calculated hash value only if object is already evaluated
360  hashvalue = v;
361  }
362 
363  return v;
364 }
365 
368 ex idx::evalf() const
369 {
370  return *this;
371 }
372 
373 ex idx::subs(const exmap & m, unsigned options) const
374 {
375  // First look for index substitutions
376  auto it = m.find(*this);
377  if (it != m.end()) {
378 
379  // Substitution index->index
380  if (is_a<idx>(it->second) || (options & subs_options::really_subs_idx))
381  return it->second;
382 
383  // Otherwise substitute value
384  idx *i_copy = duplicate();
385  i_copy->value = it->second;
387  return *i_copy;
388  }
389 
390  // None, substitute objects in value (not in dimension)
391  const ex &subsed_value = value.subs(m, options);
392  if (are_ex_trivially_equal(value, subsed_value))
393  return *this;
394 
395  idx *i_copy = duplicate();
396  i_copy->value = subsed_value;
398  return *i_copy;
399 }
400 
404 ex idx::derivative(const symbol & s) const
405 {
406  return _ex0;
407 }
408 
410 // new virtual functions
412 
413 bool idx::is_dummy_pair_same_type(const basic & other) const
414 {
415  const idx &o = static_cast<const idx &>(other);
416 
417  // Only pure symbols form dummy pairs, "2n+1" doesn't
418  if (!is_a<symbol>(value))
419  return false;
420 
421  // Value must be equal, of course
422  if (!value.is_equal(o.value))
423  return false;
424 
425  // Dimensions need not be equal but must be comparable (so we can
426  // determine the minimum dimension of contractions)
427  if (dim.is_equal(o.dim))
428  return true;
429 
430  return is_exactly_a<numeric>(dim) || is_exactly_a<numeric>(o.dim);
431 }
432 
433 bool varidx::is_dummy_pair_same_type(const basic & other) const
434 {
435  const varidx &o = static_cast<const varidx &>(other);
436 
437  // Variance must be opposite
438  if (covariant == o.covariant)
439  return false;
440 
441  return inherited::is_dummy_pair_same_type(other);
442 }
443 
444 bool spinidx::is_dummy_pair_same_type(const basic & other) const
445 {
446  const spinidx &o = static_cast<const spinidx &>(other);
447 
448  // Dottedness must be the same
449  if (dotted != o.dotted)
450  return false;
451 
452  return inherited::is_dummy_pair_same_type(other);
453 }
454 
455 
457 // non-virtual functions
459 
460 ex idx::replace_dim(const ex & new_dim) const
461 {
462  idx *i_copy = duplicate();
463  i_copy->dim = new_dim;
465  return *i_copy;
466 }
467 
468 ex idx::minimal_dim(const idx & other) const
469 {
470  return GiNaC::minimal_dim(dim, other.dim);
471 }
472 
474 {
475  varidx *i_copy = duplicate();
476  i_copy->covariant = !i_copy->covariant;
478  return *i_copy;
479 }
480 
482 {
483  spinidx *i_copy = duplicate();
484  i_copy->dotted = !i_copy->dotted;
486  return *i_copy;
487 }
488 
490 {
491  spinidx *i_copy = duplicate();
492  i_copy->covariant = !i_copy->covariant;
493  i_copy->dotted = !i_copy->dotted;
495  return *i_copy;
496 }
497 
499 // global functions
501 
502 bool is_dummy_pair(const idx & i1, const idx & i2)
503 {
504  // The indices must be of exactly the same type
505  if (typeid(i1) != typeid(i2))
506  return false;
507 
508  // Same type, let the indices decide whether they are paired
509  return i1.is_dummy_pair_same_type(i2);
510 }
511 
512 bool is_dummy_pair(const ex & e1, const ex & e2)
513 {
514  // The expressions must be indices
515  if (!is_a<idx>(e1) || !is_a<idx>(e2))
516  return false;
517 
518  return is_dummy_pair(ex_to<idx>(e1), ex_to<idx>(e2));
519 }
520 
521 void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator itend, exvector & out_free, exvector & out_dummy)
522 {
523  out_free.clear();
524  out_dummy.clear();
525 
526  // No indices? Then do nothing
527  if (it == itend)
528  return;
529 
530  // Only one index? Then it is a free one if it's not numeric
531  if (itend - it == 1) {
532  if (ex_to<idx>(*it).is_symbolic())
533  out_free.push_back(*it);
534  return;
535  }
536 
537  // Sort index vector. This will cause dummy indices come to lie next
538  // to each other (because the sort order is defined to guarantee this).
539  exvector v(it, itend);
540  shaker_sort(v.begin(), v.end(), ex_is_less(), ex_swap());
541 
542  // Find dummy pairs and free indices
543  it = v.begin(); itend = v.end();
544  auto last = it++;
545  while (it != itend) {
546  if (is_dummy_pair(*it, *last)) {
547  out_dummy.push_back(*last);
548  it++;
549  if (it == itend)
550  return;
551  } else {
552  if (!it->is_equal(*last) && ex_to<idx>(*last).is_symbolic())
553  out_free.push_back(*last);
554  }
555  last = it++;
556  }
557  if (ex_to<idx>(*last).is_symbolic())
558  out_free.push_back(*last);
559 }
560 
561 ex minimal_dim(const ex & dim1, const ex & dim2)
562 {
563  if (dim1.is_equal(dim2) || dim1 < dim2 || (is_exactly_a<numeric>(dim1) && !is_a<numeric>(dim2)))
564  return dim1;
565  else if (dim1 > dim2 || (!is_a<numeric>(dim1) && is_exactly_a<numeric>(dim2)))
566  return dim2;
567  else {
568  std::ostringstream s;
569  s << "minimal_dim(): index dimensions " << dim1 << " and " << dim2 << " cannot be ordered";
570  throw (std::runtime_error(s.str()));
571  }
572 }
573 
574 } // 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
unsigned hashvalue
hash value
Definition: basic.h:303
unsigned flags
of type status_flags
Definition: basic.h:302
const basic & setflag(unsigned f) const
Set some status_flags.
Definition: basic.h:288
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition: basic.cpp:719
const basic & clearflag(unsigned f) const
Clear some status_flags.
Definition: basic.h:291
virtual basic * duplicate() const
Create a clone of this object on the heap.
Definition: basic.h:131
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
unsigned gethash() const
Definition: ex.h:233
bool is_equal(const ex &other) const
Definition: ex.h:345
ex subs(const exmap &m, unsigned options=0) const
Definition: ex.h:826
bool info(unsigned inf) const
Definition: ex.h:132
int compare(const ex &other) const
Definition: ex.h:322
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
Definition: ex.cpp:56
This class holds one index of an indexed object.
Definition: idx.h:36
ex map(map_function &f) const override
Construct new expression by applying the specified function to all sub-expressions (one level only,...
Definition: idx.cpp:256
void print_index(const print_context &c, unsigned level) const
Definition: idx.cpp:136
ex derivative(const symbol &s) const override
Implementation of ex::diff() for an index always returns 0.
Definition: idx.cpp:404
ex dim
Dimension of space (can be symbolic or numeric)
Definition: idx.h:105
idx(const ex &v, const ex &dim)
Construct index with given value and dimension.
Definition: idx.cpp:72
void do_print_csrc(const print_csrc &c, unsigned level) const
Definition: idx.cpp:164
bool is_dim_numeric() const
Check whether the dimension is numeric.
Definition: idx.h:84
unsigned calchash() const override
Compute the hash value of an object and if it makes sense to store it in the objects status_flags,...
Definition: idx.cpp:343
ex subs(const exmap &m, unsigned options=0) const override
Substitute a set of objects by arbitrary expressions.
Definition: idx.cpp:373
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 op(size_t i) const override
Return operand/member at position i.
Definition: idx.cpp:250
ex value
Expression that constitutes the index (numeric or symbolic name)
Definition: idx.h:104
bool match_same_type(const basic &other) const override
Returns true if the attributes of two objects are similar enough for a match.
Definition: idx.cpp:282
virtual bool is_dummy_pair_same_type(const basic &other) const
Check whether the index forms a dummy index pair with another index of the same type.
Definition: idx.cpp:413
bool info(unsigned inf) const override
Information about the object.
Definition: idx.cpp:234
void do_print_latex(const print_latex &c, unsigned level) const
Definition: idx.cpp:157
size_t nops() const override
Number of operands/members.
Definition: idx.cpp:244
void do_print_tree(const print_tree &c, unsigned level) const
Definition: idx.cpp:174
void read_archive(const archive_node &n, lst &syms) override
Load (deserialize) the object from an archive node.
Definition: idx.cpp:91
ex minimal_dim(const idx &other) const
Return the minimum of the dimensions of this and another index.
Definition: idx.cpp:468
void do_print(const print_context &c, unsigned level) const
Definition: idx.cpp:151
void archive(archive_node &n) const override
Save (serialize) the object into archive node.
Definition: idx.cpp:113
ex evalf() const override
By default, basic::evalf would evaluate the index value but we don't want a.1 to become a.
Definition: idx.cpp:368
Base class for print_contexts.
Definition: print.h:103
Base context for C source output.
Definition: print.h:158
Context for latex-parsable output.
Definition: print.h:123
@ print_index_dimensions
print the dimensions of indices
Definition: print.h:57
Context for tree-like output for debugging.
Definition: print.h:147
This class holds a spinor index that can be dotted or undotted and that also has a variance.
Definition: idx.h:162
void read_archive(const archive_node &n, lst &syms) override
Load (deserialize) the object from an archive node.
Definition: idx.cpp:106
void do_print_latex(const print_latex &c, unsigned level) const
Definition: idx.cpp:213
void do_print(const print_context &c, unsigned level) const
Definition: idx.cpp:202
void archive(archive_node &n) const override
Save (serialize) the object into archive node.
Definition: idx.cpp:126
spinidx(const ex &v, const ex &dim=2, bool covariant=false, bool dotted=false)
Construct index with given value, dimension, variance and dot.
Definition: idx.cpp:64
bool match_same_type(const basic &other) const override
Returns true if the attributes of two objects are similar enough for a match.
Definition: idx.cpp:333
ex toggle_dot() const
Make a new index with the same value and variance but the opposite dottedness.
Definition: idx.cpp:481
bool is_dummy_pair_same_type(const basic &other) const override
Check whether the index forms a dummy index pair with another index of the same type.
Definition: idx.cpp:444
void do_print_tree(const print_tree &c, unsigned level) const
Definition: idx.cpp:223
bool dotted
Definition: idx.h:209
ex toggle_variance_dot() const
Make a new index with the same value but opposite variance and dottedness.
Definition: idx.cpp:489
@ evaluated
.eval() has already done its job
Definition: flags.h:203
@ hash_calculated
.calchash() has already done its job
Definition: flags.h:205
Basic CAS symbol.
Definition: symbol.h:39
This class holds an index with a variance (co- or contravariant).
Definition: idx.h:113
void read_archive(const archive_node &n, lst &syms) override
Load (deserialize) the object from an archive node.
Definition: idx.cpp:99
bool is_dummy_pair_same_type(const basic &other) const override
Check whether the index forms a dummy index pair with another index of the same type.
Definition: idx.cpp:433
varidx(const ex &v, const ex &dim, bool covariant=false)
Construct index with given value, dimension and variance.
Definition: idx.cpp:60
void do_print(const print_context &c, unsigned level) const
Definition: idx.cpp:183
void archive(archive_node &n) const override
Save (serialize) the object into archive node.
Definition: idx.cpp:120
bool match_same_type(const basic &other) const override
Returns true if the attributes of two objects are similar enough for a match.
Definition: idx.cpp:306
bool covariant
x.mu, default is contravariant: x~mu
Definition: idx.h:151
void do_print_tree(const print_tree &c, unsigned level) const
Definition: idx.cpp:192
ex toggle_variance() const
Make a new index with the same value but the opposite variance.
Definition: idx.cpp:473
static const bool value
Definition: factor.cpp:231
unsigned options
Definition: factor.cpp:2480
size_t n
Definition: factor.cpp:1463
size_t c
Definition: factor.cpp:770
mvec m
Definition: factor.cpp:771
size_t last
Definition: factor.cpp:1465
Type-specific hash seed.
Interface to GiNaC's indices.
Definition of GiNaC's lst.
Definition: add.cpp:38
ex minimal_dim(const ex &dim1, const ex &dim2)
Return the minimum of two index dimensions.
Definition: idx.cpp:561
std::map< ex, ex, ex_is_less > exmap
Definition: basic.h:50
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
Definition: ex.h:684
bool is_dummy_pair(const idx &i1, const idx &i2)
Check whether two indices form a dummy pair.
Definition: idx.cpp:502
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition: idx.cpp:45
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
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
static unsigned make_hash_seed(const std::type_info &tinfo)
We need a hash function which gives different values for objects of different types.
Definition: hash_seed.h:36
unsigned rotate_left(unsigned n)
Rotate bits of unsigned value by one bit to the left.
Definition: utils.h:48
void shaker_sort(It first, It last, Cmp comp, Swap swapit)
Definition: utils.h:193
const ex _ex0
Definition: utils.cpp:369
void find_free_and_dummy(exvector::const_iterator it, exvector::const_iterator itend, exvector &out_free, exvector &out_dummy)
Given a vector of indices, split them into two vectors, one containing the free indices,...
Definition: idx.cpp:521
std::vector< ex > exvector
Definition: basic.h:46
Interface to GiNaC's overloaded operators.
Interface to relations between expressions.
Function object for map().
Definition: basic.h:85
Interface to GiNaC's symbolic objects.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...

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