GiNaC 1.8.10
basic.cpp
Go to the documentation of this file.
1
4
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.
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
96{ }
97
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
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{
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
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
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) {
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
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
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
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
455{
456 if (nops() == 0)
457 return *this;
458 else
459 return map(map_eval_integ);
460}
461
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();
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
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
666{
667 return exvector(); // return an empty exvector
668}
669
671{
672 return *this;
673}
674
676{
677 return real_part_function(*this).hold();
678}
679
681{
682 return imag_part_function(*this).hold();
683}
684
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
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{
753}
754
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
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{
889}
890
894{
895 if (get_refcount() > 1)
896 throw(std::runtime_error("cannot modify multiply referenced object"));
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
void add_string(const std::string &name, const std::string &value)
Add property of type "string" to node.
Definition archive.cpp:403
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition basic.h:104
virtual return_type_t return_type_tinfo() const
Definition basic.cpp:755
virtual size_t nops() const
Number of operands/members.
Definition basic.cpp:228
unsigned gethash() const
Definition basic.h:271
virtual ex eval_integ() const
Evaluate integrals, if result is known.
Definition basic.cpp:454
const basic & clearflag(unsigned f) const
Clear some status_flags.
Definition basic.h:290
virtual bool match_same_type(const basic &other) const
Returns true if the attributes of two objects are similar enough for a match.
Definition basic.cpp:743
virtual bool match(const ex &pattern, exmap &repls) const
Check whether the expression matches a given pattern.
Definition basic.cpp:518
virtual void dbgprinttree() const
Little wrapper around printtree to be called within a debugger.
Definition basic.cpp:207
void print_dispatch(const print_context &c, unsigned level) const
Like print(), but dispatch to the specified class.
Definition basic.h:241
virtual ex imag_part() const
Definition basic.cpp:680
virtual void archive(archive_node &n) const
Save (serialize) the object into archive node.
Definition basic.cpp:99
virtual ex eval() const
Perform automatic non-interruptive term rewriting rules.
Definition basic.cpp:412
const basic & setflag(unsigned f) const
Set some status_flags.
Definition basic.h:287
virtual bool info(unsigned inf) const
Information about the object.
Definition basic.cpp:221
virtual bool contract_with(exvector::iterator self, exvector::iterator other, exvector &v) const
Try to contract two indexed expressions that appear in the same product.
Definition basic.cpp:509
ex diff(const symbol &s, unsigned nth=1) const
Default interface of nth derivative ex::diff(s, n).
Definition basic.cpp:645
virtual ex scalar_mul_indexed(const ex &self, const numeric &other) const
Multiply an indexed expression with a scalar.
Definition basic.cpp:492
unsigned hashvalue
hash value
Definition basic.h:302
void ensure_if_modifiable() const
Ensure the object may be modified without hurting others, throws if this is not the case.
Definition basic.cpp:893
virtual bool is_equal_same_type(const basic &other) const
Returns true if two objects of same type are equal.
Definition basic.cpp:728
virtual bool has(const ex &other, unsigned options=0) const
Test for occurrence of a pattern.
Definition basic.cpp:279
virtual ex evalm() const
Evaluate sums, products and integer powers of matrices.
Definition basic.cpp:440
friend class ex
Definition basic.h:107
virtual ex eval_indexed(const basic &i) const
Perform automatic symbolic evaluations on indexed expression that contains this object as the base ex...
Definition basic.cpp:464
virtual int degree(const ex &s) const
Return degree of highest power in object s.
Definition basic.cpp:324
virtual ex conjugate() const
Definition basic.cpp:670
virtual unsigned precedence() const
Return relative operator precedence (for parenthezing output).
Definition basic.cpp:213
virtual ex op(size_t i) const
Return operand/member at position i.
Definition basic.cpp:237
unsigned flags
of type status_flags
Definition basic.h:301
virtual ex add_indexed(const ex &self, const ex &other) const
Add two indexed expressions.
Definition basic.cpp:480
const basic & operator=(const basic &other)
basic assignment operator: the other object might be of a derived class.
Definition basic.cpp:63
virtual void print(const print_context &c, unsigned level=0) const
Output to stream.
Definition basic.cpp:115
void do_print(const print_context &c, unsigned level) const
Default output to stream.
Definition basic.cpp:168
virtual void read_archive(const archive_node &n, lst &syms)
Load (deserialize) the object from an archive node.
Definition basic.cpp:95
ex subs_one_level(const exmap &m, unsigned options) const
Helper function for subs().
Definition basic.cpp:584
const basic & hold() const
Stop further evaluation.
Definition basic.cpp:886
bool is_equal(const basic &other) const
Test for syntactic equality.
Definition basic.cpp:862
virtual ex collect(const ex &s, bool distributed=false) const
Sort expanded expression in terms of powers of some object(s).
Definition basic.cpp:347
virtual ex subs(const exmap &m, unsigned options=0) const
Substitute a set of objects by arbitrary expressions.
Definition basic.cpp:606
virtual ex real_part() const
Definition basic.cpp:675
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition basic.cpp:718
virtual ex & let_op(size_t i)
Return modifiable operand/member at position i.
Definition basic.cpp:243
virtual basic * duplicate() const
Create a clone of this object on the heap.
Definition basic.h:130
virtual void dbgprint() const
Little wrapper around print to be called within a debugger.
Definition basic.cpp:198
void do_print_tree(const print_tree &c, unsigned level) const
Tree output to stream.
Definition basic.cpp:174
virtual ex coeff(const ex &s, int n=1) const
Return coefficient of degree n in object s.
Definition basic.cpp:336
virtual unsigned return_type() const
Definition basic.cpp:750
virtual ex eval_ncmul(const exvector &v) const
Definition basic.cpp:685
void do_print_python_repr(const print_python_repr &c, unsigned level) const
Python parsable output to stream.
Definition basic.cpp:186
virtual ex derivative(const symbol &s) const
Default implementation of ex::diff().
Definition basic.cpp:703
virtual int ldegree(const ex &s) const
Return degree of lowest power in object s.
Definition basic.cpp:330
virtual ex expand(unsigned options=0) const
Expand expression, i.e.
Definition basic.cpp:795
int compare(const basic &other) const
Compare objects syntactically to establish canonical ordering.
Definition basic.cpp:815
virtual ex evalf() const
Evaluate object numerically.
Definition basic.cpp:424
virtual ex operator[](const ex &index) const
Definition basic.cpp:249
virtual unsigned calchash() const
Compute the hash value of an object and if it makes sense to store it in the objects status_flags,...
Definition basic.cpp:769
virtual exvector get_free_indices() const
Return a vector containing the free indices of an expression.
Definition basic.cpp:665
virtual bool is_polynomial(const ex &var) const
Check whether this is a polynomial in the given variables.
Definition basic.cpp:318
virtual ex map(map_function &f) const
Construct new expression by applying the specified function to all sub-expressions (one level only,...
Definition basic.cpp:293
class_info * get_parent() const
Get pointer to class_info of parent class (or nullptr).
Definition class_info.h:49
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:72
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
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
ex collect(const ex &s, bool distributed=false) const
Definition ex.h:181
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
unsigned get_id() const
Definition print.h:40
Base class for print_contexts.
Definition print.h:101
std::ostream & s
stream to output to
Definition print.h:107
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
const unsigned delta_indent
size of indentation step
Definition print.h:151
void set_refcount(unsigned int r) noexcept
Definition ptr.h:41
unsigned int get_refcount() const noexcept
Definition ptr.h:40
Flags to store information about the state of an object.
Definition flags.h:198
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
Definition flags.h:203
@ evaluated
.eval() has already done its job
Definition flags.h:202
@ hash_calculated
.calchash() has already done its job
Definition flags.h:204
@ no_pattern
disable pattern matching
Definition flags.h:50
Basic CAS symbol.
Definition symbol.h:38
Interface to GiNaC's light-weight expression handles.
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
container< std::list > lst
Definition lst.h:31
std::map< ex, ex, ex_is_less > exmap
Definition basic.h:49
B & dynallocate(Args &&... args)
Constructs a new (class basic or derived) B object on the heap.
Definition basic.h:333
class_info< registered_class_options > registered_class_info
Definition registrar.h:124
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
attribute_pure const T & ex_to(const ex &e)
Return a reference to the basic-derived class T object embedded in an expression.
Definition ex.h:977
ex diff(const ex &thisex, const symbol &s, unsigned nth=1)
Definition ex.h:793
registered_class_info structure< T, CP >::reg_info
Definition structure.h:242
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition idx.cpp:43
bool is_a(const basic &obj)
Check if obj is a T, including base classes.
Definition basic.h:312
class_info< print_context_options > print_context_class_info
Definition print.h:48
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
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 is_exactly_a(const basic &obj)
Check if obj is a T, not including base classes.
Definition basic.h:319
const ex _ex0
Definition utils.cpp:368
std::vector< ex > exvector
Definition basic.h:47
GiNaC::eval_integ_map_function map_eval_integ
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.