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