GiNaC 1.8.5
basic.cpp
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2023 Johannes Gutenberg University Mainz, Germany
7 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 */
22
23#include "basic.h"
24#include "ex.h"
25#include "numeric.h"
26#include "power.h"
27#include "add.h"
28#include "symbol.h"
29#include "lst.h"
30#include "ncmul.h"
31#include "relational.h"
32#include "operators.h"
33#include "wildcard.h"
34#include "archive.h"
35#include "utils.h"
36#include "hash_seed.h"
37#include "inifcns.h"
38
39#include <iostream>
40#include <stdexcept>
41#include <typeinfo>
42
43namespace GiNaC {
44
47 print_func<print_tree>(&basic::do_print_tree).
48 print_func<print_python_repr>(&basic::do_print_python_repr))
49
50
51// default constructor, destructor, copy constructor and assignment operator
53
54// public
55
56
59basic::basic(const basic & other) : flags(other.flags & ~status_flags::dynallocated), hashvalue(other.hashvalue)
60{
61}
62
64const basic & basic::operator=(const basic & other)
65{
66 unsigned fl = other.flags & ~status_flags::dynallocated;
67 if (typeid(*this) != typeid(other)) {
68 // The other object is of a derived class, so clear the flags as they
69 // might no longer apply (especially hash_calculated). Oh, and don't
70 // copy the tinfo_key: it is already set correctly for this object.
71 fl &= ~(status_flags::evaluated | status_flags::expanded | status_flags::hash_calculated);
72 } else {
73 // The objects are of the exact same class, so copy the hash value.
74 hashvalue = other.hashvalue;
75 }
76 flags = fl;
77 set_refcount(0);
78 return *this;
79}
80
81// protected
82
83// none (all inlined)
84
86// other constructors
88
89// none (all inlined)
90
92// archiving
94
96void basic::read_archive(const archive_node& n, lst& syms)
97{ }
98
100void basic::archive(archive_node &n) const
101{
102 n.add_string("class", class_name());
103}
104
106// new virtual functions which can be overridden by derived classes
108
109// public
110
116void basic::print(const print_context & c, unsigned level) const
117{
118 print_dispatch(get_class_info(), c, level);
119}
120
126void basic::print_dispatch(const registered_class_info & ri, const print_context & c, unsigned level) const
127{
128 // Double dispatch on object type and print_context type
129 const registered_class_info * reg_info = &ri;
130 const print_context_class_info * pc_info = &c.get_class_info();
131
132next_class:
133 const std::vector<print_functor> & pdt = reg_info->options.get_print_dispatch_table();
134
135next_context:
136 unsigned id = pc_info->options.get_id();
137 if (id >= pdt.size() || !(pdt[id].is_valid())) {
138
139 // Method not found, try parent print_context class
140 const print_context_class_info * parent_pc_info = pc_info->get_parent();
141 if (parent_pc_info) {
142 pc_info = parent_pc_info;
143 goto next_context;
144 }
145
146 // Method still not found, try parent class
147 const registered_class_info * parent_reg_info = reg_info->get_parent();
148 if (parent_reg_info) {
149 reg_info = parent_reg_info;
150 pc_info = &c.get_class_info();
151 goto next_class;
152 }
153
154 // Method still not found. This shouldn't happen because basic (the
155 // base class of the algebraic hierarchy) registers a method for
156 // print_context (the base class of the print context hierarchy),
157 // so if we end up here, there's something wrong with the class
158 // registry.
159 throw (std::runtime_error(std::string("basic::print(): method for ") + class_name() + "/" + c.class_name() + " not found"));
160
161 } else {
162
163 // Call method
164 pdt[id](*this, c, level);
165 }
166}
167
169void basic::do_print(const print_context & c, unsigned level) const
170{
171 c.s << "[" << class_name() << " object]";
172}
173
175void basic::do_print_tree(const print_tree & c, unsigned level) const
176{
177 c.s << std::string(level, ' ') << class_name() << " @" << this
178 << std::hex << ", hash=0x" << hashvalue << ", flags=0x" << flags << std::dec;
179 if (nops())
180 c.s << ", nops=" << nops();
181 c.s << std::endl;
182 for (size_t i=0; i<nops(); ++i)
183 op(i).print(c, level + c.delta_indent);
184}
185
187void basic::do_print_python_repr(const print_python_repr & c, unsigned level) const
188{
189 c.s << class_name() << "()";
190}
191
199void basic::dbgprint() const
200{
201 this->print(print_dflt(std::cerr));
202 std::cerr << std::endl;
203}
204
208void basic::dbgprinttree() const
209{
210 this->print(print_tree(std::cerr));
211}
212
214unsigned basic::precedence() const
215{
216 return 70;
217}
218
222bool basic::info(unsigned inf) const
223{
224 // all possible properties are false for basic objects
225 return false;
226}
227
229size_t basic::nops() const
230{
231 // iterating from 0 to nops() on atomic objects should be an empty loop,
232 // and accessing their elements is a range error. Container objects should
233 // override this.
234 return 0;
235}
236
238ex basic::op(size_t i) const
239{
240 throw(std::range_error(std::string("basic::op(): ") + class_name() + std::string(" has no operands")));
241}
242
244ex & basic::let_op(size_t i)
245{
246 ensure_if_modifiable();
247 throw(std::range_error(std::string("basic::let_op(): ") + class_name() + std::string(" has no operands")));
248}
249
250ex basic::operator[](const ex & index) const
251{
252 if (is_exactly_a<numeric>(index))
253 return op(static_cast<size_t>(ex_to<numeric>(index).to_int()));
254
255 throw(std::invalid_argument(std::string("non-numeric indices not supported by ") + class_name()));
256}
257
258ex basic::operator[](size_t i) const
259{
260 return op(i);
261}
262
263ex & basic::operator[](const ex & index)
264{
265 if (is_exactly_a<numeric>(index))
266 return let_op(ex_to<numeric>(index).to_int());
267
268 throw(std::invalid_argument(std::string("non-numeric indices not supported by ") + class_name()));
269}
270
271ex & basic::operator[](size_t i)
272{
273 return let_op(i);
274}
275
280bool basic::has(const ex & pattern, unsigned options) const
281{
282 exmap repl_lst;
283 if (match(pattern, repl_lst))
284 return true;
285 for (size_t i=0; i<nops(); i++)
286 if (op(i).has(pattern, options))
287 return true;
288
289 return false;
290}
291
294ex basic::map(map_function & f) const
295{
296 size_t num = nops();
297 if (num == 0)
298 return *this;
299
300 basic *copy = nullptr;
301 for (size_t i=0; i<num; i++) {
302 const ex & o = op(i);
303 const ex & n = f(o);
304 if (!are_ex_trivially_equal(o, n)) {
305 if (copy == nullptr)
306 copy = duplicate();
307 copy->let_op(i) = n;
308 }
309 }
310
311 if (copy) {
312 copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
313 return *copy;
314 } else
315 return *this;
316}
317
319bool basic::is_polynomial(const ex & var) const
320{
321 return !has(var) || is_equal(ex_to<basic>(var));
322}
323
325int basic::degree(const ex & s) const
326{
327 return is_equal(ex_to<basic>(s)) ? 1 : 0;
328}
329
331int basic::ldegree(const ex & s) const
332{
333 return is_equal(ex_to<basic>(s)) ? 1 : 0;
334}
335
337ex basic::coeff(const ex & s, int n) const
338{
339 if (is_equal(ex_to<basic>(s)))
340 return n==1 ? _ex1 : _ex0;
341 else
342 return n==0 ? *this : _ex0;
343}
344
348ex basic::collect(const ex & s, bool distributed) const
349{
350 ex x;
351 if (is_a<lst>(s)) {
352
353 // List of objects specified
354 if (s.nops() == 0)
355 return *this;
356 if (s.nops() == 1)
357 return collect(s.op(0));
358
359 else if (distributed) {
360
361 x = this->expand();
362 if (! is_a<add>(x))
363 return x;
364 const lst& l(ex_to<lst>(s));
365
366 exmap cmap;
367 cmap[_ex1] = _ex0;
368 for (const auto & xi : x) {
369 ex key = _ex1;
370 ex pre_coeff = xi;
371 for (auto & li : l) {
372 int cexp = pre_coeff.degree(li);
373 pre_coeff = pre_coeff.coeff(li, cexp);
374 key *= pow(li, cexp);
375 }
376 auto ci = cmap.find(key);
377 if (ci != cmap.end())
378 ci->second += pre_coeff;
379 else
380 cmap.insert(exmap::value_type(key, pre_coeff));
381 }
382
383 exvector resv;
384 for (auto & mi : cmap)
385 resv.push_back((mi.first)*(mi.second));
386 return dynallocate<add>(resv);
387
388 } else {
389
390 // Recursive form
391 x = *this;
392 size_t n = s.nops() - 1;
393 while (true) {
394 x = x.collect(s[n]);
395 if (n == 0)
396 break;
397 n--;
398 }
399 }
400
401 } else {
402
403 // Only one object specified
404 for (int n=this->ldegree(s); n<=this->degree(s); ++n)
405 x += this->coeff(s,n)*power(s,n);
406 }
407
408 // correct for lost fractional arguments and return
409 return x + (*this - x).expand();
410}
411
414{
415 // There is nothing to do for basic objects:
416 return hold();
417}
418
421 ex operator()(const ex & e) override { return evalf(e); }
422};
423
426{
427 if (nops() == 0)
428 return *this;
429 else {
430 evalf_map_function map_evalf;
431 return map(map_evalf);
432 }
433}
434
437 ex operator()(const ex & e) override { return evalm(e); }
439
442{
443 if (nops() == 0)
444 return *this;
445 else
446 return map(map_evalm);
447}
448
451 ex operator()(const ex & e) override { return eval_integ(e); }
453
456{
457 if (nops() == 0)
458 return *this;
459 else
460 return map(map_eval_integ);
461}
462
465ex basic::eval_indexed(const basic & i) const
466 // this function can't take a "const ex & i" because that would result
467 // in an infinite eval() loop
468{
469 // There is nothing to do for basic objects
470 return i.hold();
471}
472
481ex basic::add_indexed(const ex & self, const ex & other) const
482{
483 return self + other;
484}
485
493ex basic::scalar_mul_indexed(const ex & self, const numeric & other) const
494{
495 return self * other;
496}
497
510bool basic::contract_with(exvector::iterator self, exvector::iterator other, exvector & v) const
511{
512 // Do nothing
513 return false;
514}
515
519bool basic::match(const ex & pattern, exmap& repl_lst) const
520{
521/*
522 Sweet sweet shapes, sweet sweet shapes,
523 That's the key thing, right right.
524 Feed feed face, feed feed shapes,
525 But who is the king tonight?
526 Who is the king tonight?
527 Pattern is the thing, the key thing-a-ling,
528 But who is the king of Pattern?
529 But who is the king, the king thing-a-ling,
530 Who is the king of Pattern?
531 Bog is the king, the king thing-a-ling,
532 Bog is the king of Pattern.
533 Ba bu-bu-bu-bu bu-bu-bu-bu-bu-bu bu-bu
534 Bog is the king of Pattern.
535*/
536
537 if (is_exactly_a<wildcard>(pattern)) {
538
539 // Wildcard matches anything, but check whether we already have found
540 // a match for that wildcard first (if so, the earlier match must be
541 // the same expression)
542 for (auto & it : repl_lst) {
543 if (it.first.is_equal(pattern))
544 return is_equal(ex_to<basic>(it.second));
545 }
546 repl_lst[pattern] = *this;
547 return true;
548
549 } else {
550
551 // Expression must be of the same type as the pattern
552 if (typeid(*this) != typeid(ex_to<basic>(pattern)))
553 return false;
554
555 // Number of subexpressions must match
556 if (nops() != pattern.nops())
557 return false;
558
559 // No subexpressions? Then just compare the objects (there can't be
560 // wildcards in the pattern)
561 if (nops() == 0)
562 return is_equal_same_type(ex_to<basic>(pattern));
563
564 // Check whether attributes that are not subexpressions match
565 if (!match_same_type(ex_to<basic>(pattern)))
566 return false;
567
568 // Even if the expression does not match the pattern, some of
569 // its subexpressions could match it. For example, x^5*y^(-1)
570 // does not match the pattern $0^5, but its subexpression x^5
571 // does. So, save repl_lst in order to not add bogus entries.
572 exmap tmp_repl = repl_lst;
573 // Otherwise the subexpressions must match one-to-one
574 for (size_t i=0; i<nops(); i++)
575 if (!op(i).match(pattern.op(i), tmp_repl))
576 return false;
577
578 // Looks similar enough, match found
579 repl_lst = tmp_repl;
580 return true;
581 }
582}
583
585ex basic::subs_one_level(const exmap & m, unsigned options) const
586{
587 if (options & subs_options::no_pattern) {
588 ex thisex = *this; // NB: *this may be deleted here.
589 auto it = m.find(thisex);
590 if (it != m.end())
591 return it->second;
592 return thisex;
593 } else {
594 for (auto & it : m) {
595 exmap repl_lst;
596 if (match(ex_to<basic>(it.first), repl_lst))
597 return it.second.subs(repl_lst, options | subs_options::no_pattern);
598 // avoid infinite recursion when re-substituting the wildcards
599 }
600 }
601
602 return *this;
603}
604
607ex basic::subs(const exmap & m, unsigned options) const
608{
609 size_t num = nops();
610 if (num) {
611
612 // Substitute in subexpressions
613 for (size_t i=0; i<num; i++) {
614 const ex & orig_op = op(i);
615 const ex & subsed_op = orig_op.subs(m, options);
616 if (!are_ex_trivially_equal(orig_op, subsed_op)) {
617
618 // Something changed, clone the object
619 basic *copy = duplicate();
620 copy->clearflag(status_flags::hash_calculated | status_flags::expanded);
621
622 // Substitute the changed operand
623 copy->let_op(i++) = subsed_op;
624
625 // Substitute the other operands
626 for (; i<num; i++)
627 copy->let_op(i) = op(i).subs(m, options);
628
629 // Perform substitutions on the new object as a whole
630 return copy->subs_one_level(m, options);
631 }
632 }
633 }
634
635 // Nothing changed or no subexpressions
636 return subs_one_level(m, options);
637}
638
646ex basic::diff(const symbol & s, unsigned nth) const
647{
648 // trivial: zeroth derivative
649 if (nth==0)
650 return ex(*this);
651
652 // evaluate unevaluated *this before differentiating
653 if (!(flags & status_flags::evaluated))
654 return ex(*this).diff(s, nth);
655
656 ex ndiff = this->derivative(s);
657 while (!ndiff.is_zero() && // stop differentiating zeros
658 nth>1) {
659 ndiff = ndiff.diff(s);
660 --nth;
661 }
662 return ndiff;
663}
664
666exvector basic::get_free_indices() const
667{
668 return exvector(); // return an empty exvector
669}
670
672{
673 return *this;
674}
675
677{
678 return real_part_function(*this).hold();
679}
680
682{
683 return imag_part_function(*this).hold();
684}
685
686ex basic::eval_ncmul(const exvector & v) const
687{
688 return hold_ncmul(v);
689}
690
691// protected
692
695 const symbol &s;
696 derivative_map_function(const symbol &sym) : s(sym) {}
697 ex operator()(const ex & e) override { return diff(e, s); }
698};
699
704ex basic::derivative(const symbol & s) const
705{
706 if (nops() == 0)
707 return _ex0;
708 else {
709 derivative_map_function map_derivative(s);
710 return map(map_derivative);
711 }
712}
713
719int basic::compare_same_type(const basic & other) const
720{
721 return compare_pointers(this, &other);
722}
723
729bool basic::is_equal_same_type(const basic & other) const
730{
731 return compare_same_type(other)==0;
732}
733
744bool basic::match_same_type(const basic & other) const
745{
746 // The default is to only consider subexpressions, but not any other
747 // attributes
748 return true;
749}
750
751unsigned basic::return_type() const
752{
753 return return_types::commutative;
754}
755
756return_type_t basic::return_type_tinfo() const
757{
758 return_type_t rt;
759 rt.tinfo = &typeid(*this);
760 rt.rl = 0;
761 return rt;
762}
763
770unsigned basic::calchash() const
771{
772 unsigned v = make_hash_seed(typeid(*this));
773 for (size_t i=0; i<nops(); i++) {
774 v = rotate_left(v);
775 v ^= this->op(i).gethash();
776 }
777
778 // store calculated hash value only if object is already evaluated
779 if (flags & status_flags::evaluated) {
780 setflag(status_flags::hash_calculated);
781 hashvalue = v;
782 }
783
784 return v;
785}
786
789 unsigned options;
790 expand_map_function(unsigned o) : options(o) {}
791 ex operator()(const ex & e) override { return e.expand(options); }
792};
793
796ex basic::expand(unsigned options) const
797{
798 if (nops() == 0)
799 return (options == 0) ? setflag(status_flags::expanded) : *this;
800 else {
801 expand_map_function map_expand(options);
802 return ex_to<basic>(map(map_expand)).setflag(options == 0 ? status_flags::expanded : 0);
803 }
804}
805
806
808// non-virtual functions in this class
810
811// public
812
816int basic::compare(const basic & other) const
817{
818#ifdef GINAC_COMPARE_STATISTICS
819 compare_statistics.total_basic_compares++;
820#endif
821 const unsigned hash_this = gethash();
822 const unsigned hash_other = other.gethash();
823 if (hash_this<hash_other) return -1;
824 if (hash_this>hash_other) return 1;
825#ifdef GINAC_COMPARE_STATISTICS
826 compare_statistics.compare_same_hashvalue++;
827#endif
828
829 const std::type_info& typeid_this = typeid(*this);
830 const std::type_info& typeid_other = typeid(other);
831 if (typeid_this == typeid_other) {
832// int cmpval = compare_same_type(other);
833// if (cmpval!=0) {
834// std::cout << "hash collision, same type: "
835// << *this << " and " << other << std::endl;
836// this->print(print_tree(std::cout));
837// std::cout << " and ";
838// other.print(print_tree(std::cout));
839// std::cout << std::endl;
840// }
841// return cmpval;
842#ifdef GINAC_COMPARE_STATISTICS
843 compare_statistics.compare_same_type++;
844#endif
845 return compare_same_type(other);
846 } else {
847// std::cout << "hash collision, different types: "
848// << *this << " and " << other << std::endl;
849// this->print(print_tree(std::cout));
850// std::cout << " and ";
851// other.print(print_tree(std::cout));
852// std::cout << std::endl;
853 return (typeid_this.before(typeid_other) ? -1 : 1);
854 }
855}
856
863bool basic::is_equal(const basic & other) const
864{
865#ifdef GINAC_COMPARE_STATISTICS
866 compare_statistics.total_basic_is_equals++;
867#endif
868 if (this->gethash()!=other.gethash())
869 return false;
870#ifdef GINAC_COMPARE_STATISTICS
871 compare_statistics.is_equal_same_hashvalue++;
872#endif
873 if (typeid(*this) != typeid(other))
874 return false;
875
876#ifdef GINAC_COMPARE_STATISTICS
877 compare_statistics.is_equal_same_type++;
878#endif
879 return is_equal_same_type(other);
880}
881
882// protected
883
887const basic & basic::hold() const
888{
889 return setflag(status_flags::evaluated);
890}
891
894void basic::ensure_if_modifiable() const
895{
896 if (get_refcount() > 1)
897 throw(std::runtime_error("cannot modify multiply referenced object"));
898 clearflag(status_flags::hash_calculated | status_flags::evaluated);
899}
900
902// global variables
904
905#ifdef GINAC_COMPARE_STATISTICS
906compare_statistics_t::~compare_statistics_t()
907{
908 std::clog << "ex::compare() called " << total_compares << " times" << std::endl;
909 std::clog << "nontrivial compares: " << nontrivial_compares << " times" << std::endl;
910 std::clog << "basic::compare() called " << total_basic_compares << " times" << std::endl;
911 std::clog << "same hashvalue in compare(): " << compare_same_hashvalue << " times" << std::endl;
912 std::clog << "compare_same_type() called " << compare_same_type << " times" << std::endl;
913 std::clog << std::endl;
914 std::clog << "ex::is_equal() called " << total_is_equals << " times" << std::endl;
915 std::clog << "nontrivial is_equals: " << nontrivial_is_equals << " times" << std::endl;
916 std::clog << "basic::is_equal() called " << total_basic_is_equals << " times" << std::endl;
917 std::clog << "same hashvalue in is_equal(): " << is_equal_same_hashvalue << " times" << std::endl;
918 std::clog << "is_equal_same_type() called " << is_equal_same_type << " times" << std::endl;
919 std::clog << std::endl;
920 std::clog << "basic::gethash() called " << total_gethash << " times" << std::endl;
921 std::clog << "used cached hashvalue " << gethash_cached << " times" << std::endl;
922}
923
924compare_statistics_t compare_statistics;
925#endif
926
927} // namespace GiNaC
Interface to GiNaC's sums of expressions.
Archiving of GiNaC expressions.
Interface to GiNaC's ABC.
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 gethash() const
Definition: basic.h:272
const basic & clearflag(unsigned f) const
Clear some status_flags.
Definition: basic.h:291
unsigned hashvalue
hash value
Definition: basic.h:303
unsigned flags
of type status_flags
Definition: basic.h:302
void do_print(const print_context &c, unsigned level) const
Default output to stream.
Definition: basic.cpp:169
ex subs_one_level(const exmap &m, unsigned options) const
Helper function for subs().
Definition: basic.cpp:585
virtual ex & let_op(size_t i)
Return modifiable operand/member at position i.
Definition: basic.cpp:244
void do_print_tree(const print_tree &c, unsigned level) const
Tree output to stream.
Definition: basic.cpp:175
void do_print_python_repr(const print_python_repr &c, unsigned level) const
Python parsable output to stream.
Definition: basic.cpp:187
class_info * get_parent() const
Get pointer to class_info of parent class (or nullptr).
Definition: class_info.h:50
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 match(const ex &pattern) const
Check whether expression matches a specified pattern.
Definition: ex.cpp:95
unsigned gethash() const
Definition: ex.h:233
ex diff(const symbol &s, unsigned nth=1) const
Compute partial derivative of an expression.
Definition: ex.cpp:86
ex expand(unsigned options=0) const
Definition: ex.cpp:73
int degree(const ex &s) const
Definition: ex.h:173
bool has(const ex &pattern, unsigned options=0) const
Definition: ex.h:151
size_t nops() const
Definition: ex.h:135
ex subs(const exmap &m, unsigned options=0) const
Definition: ex.h:841
bool is_zero() const
Definition: ex.h:213
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
Definition: ex.cpp:56
ex op(size_t i) const
Definition: ex.h:136
ex coeff(const ex &s, int n=1) const
Definition: ex.h:175
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Definition: numeric.h:82
This class holds a two-component object, a basis and and exponent representing exponentiation.
Definition: power.h:39
Base class for print_contexts.
Definition: print.h:103
Context for default (ginsh-parsable) output.
Definition: print.h:115
Context for python-parsable output.
Definition: print.h:139
Context for tree-like output for debugging.
Definition: print.h:147
Flags to store information about the state of an object.
Definition: flags.h:199
Basic CAS symbol.
Definition: symbol.h:39
Interface to GiNaC's light-weight expression handles.
unsigned options
Definition: factor.cpp:2475
size_t n
Definition: factor.cpp:1432
size_t c
Definition: factor.cpp:757
ex x
Definition: factor.cpp:1610
exset syms
Definition: factor.cpp:2429
mvec m
Definition: factor.cpp:758
Type-specific hash seed.
Interface to GiNaC's initially known functions.
Definition of GiNaC's lst.
Definition: add.cpp:38
ex hold_ncmul(const exvector &v)
Definition: ncmul.cpp:614
ex real_part(const ex &thisex)
Definition: ex.h:736
const numeric pow(const numeric &x, const numeric &y)
Definition: numeric.h:251
bool is_polynomial(const ex &thisex, const ex &vars)
Definition: ex.h:748
std::map< ex, ex, ex_is_less > exmap
Definition: basic.h:50
const ex _ex1
Definition: utils.cpp:385
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:699
int compare_pointers(const T *a, const T *b)
Compare two pointers (just to establish some sort of canonical order).
Definition: utils.h:56
ex conjugate(const ex &thisex)
Definition: ex.h:733
ex diff(const ex &thisex, const symbol &s, unsigned nth=1)
Definition: ex.h:793
ex subs(const ex &thisex, const exmap &m, unsigned options=0)
Definition: ex.h:846
ex eval(const ex &thisex)
Definition: ex.h:781
int degree(const ex &thisex, const ex &s)
Definition: ex.h:751
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition: idx.cpp:45
bool match(const ex &thisex, const ex &pattern, exmap &repl_lst)
Definition: ex.h:799
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
int ldegree(const ex &thisex, const ex &s)
Definition: ex.h:754
ex evalf(const ex &thisex)
Definition: ex.h:784
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
GiNaC::evalm_map_function map_evalm
ex op(const ex &thisex, size_t i)
Definition: ex.h:826
ex coeff(const ex &thisex, const ex &s, int n=1)
Definition: ex.h:757
ex collect(const ex &thisex, const ex &s, bool distributed=false)
Definition: ex.h:778
int to_int(const numeric &x)
Definition: numeric.h:302
ex eval_integ(const ex &thisex)
Definition: ex.h:790
ex evalm(const ex &thisex)
Definition: ex.h:787
bool has(const ex &thisex, const ex &pattern, unsigned options=0)
Definition: ex.h:742
const ex _ex0
Definition: utils.cpp:369
std::vector< ex > exvector
Definition: basic.h:48
size_t nops(const ex &thisex)
Definition: ex.h:727
ex imag_part(const ex &thisex)
Definition: ex.h:739
GiNaC::eval_integ_map_function map_eval_integ
ex expand(const ex &thisex, unsigned options=0)
Definition: ex.h:730
Interface to GiNaC's non-commutative products of expressions.
Makes the interface to the underlying bignum package available.
Interface to GiNaC's overloaded operators.
Interface to GiNaC's symbolic exponentiation (basis^exponent).
Interface to relations between expressions.
Function object to be applied by basic::derivative().
Definition: basic.cpp:694
derivative_map_function(const symbol &sym)
Definition: basic.cpp:696
ex operator()(const ex &e) override
Definition: basic.cpp:697
Function object to be applied by basic::eval_integ().
Definition: basic.cpp:450
ex operator()(const ex &e) override
Definition: basic.cpp:451
Function object to be applied by basic::evalf().
Definition: basic.cpp:420
ex operator()(const ex &e) override
Definition: basic.cpp:421
Function object to be applied by basic::evalm().
Definition: basic.cpp:436
ex operator()(const ex &e) override
Definition: basic.cpp:437
Function object to be applied by basic::expand().
Definition: basic.cpp:788
expand_map_function(unsigned o)
Definition: basic.cpp:790
ex operator()(const ex &e) override
Definition: basic.cpp:791
Function object for map().
Definition: basic.h:85
To distinguish between different kinds of non-commutative objects.
Definition: registrar.h:44
std::type_info const * tinfo
to distinguish between non-commutative objects of different type.
Definition: registrar.h:46
unsigned rl
to distinguish between non-commutative objects of the same type.
Definition: registrar.h:49
Interface to GiNaC's symbolic objects.
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...
Interface to GiNaC's wildcard objects.

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