GiNaC 1.8.7
basic.cpp
Go to the documentation of this file.
1
4
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.
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
97{ }
98
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
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{
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
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
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) {
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); }
438} map_evalm;
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); }
452} map_eval_integ;
453
456{
457 if (nops() == 0)
458 return *this;
459 else
460 return map(map_eval_integ);
461}
462
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();
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
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
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
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
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{
754}
755
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
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{
890}
891
895{
896 if (get_refcount() > 1)
897 throw(std::runtime_error("cannot modify multiply referenced object"));
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
void add_string(const std::string &name, const std::string &value)
Add property of type "string" to node.
Definition archive.cpp:405
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
Definition basic.h:105
virtual return_type_t return_type_tinfo() const
Definition basic.cpp:756
virtual size_t nops() const
Number of operands/members.
Definition basic.cpp:229
unsigned gethash() const
Definition basic.h:272
virtual ex eval_integ() const
Evaluate integrals, if result is known.
Definition basic.cpp:455
const basic & clearflag(unsigned f) const
Clear some status_flags.
Definition basic.h:291
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:744
virtual bool match(const ex &pattern, exmap &repls) const
Check whether the expression matches a given pattern.
Definition basic.cpp:519
virtual void dbgprinttree() const
Little wrapper around printtree to be called within a debugger.
Definition basic.cpp:208
void print_dispatch(const print_context &c, unsigned level) const
Like print(), but dispatch to the specified class.
Definition basic.h:242
virtual ex imag_part() const
Definition basic.cpp:681
virtual void archive(archive_node &n) const
Save (serialize) the object into archive node.
Definition basic.cpp:100
virtual ex eval() const
Perform automatic non-interruptive term rewriting rules.
Definition basic.cpp:413
const basic & setflag(unsigned f) const
Set some status_flags.
Definition basic.h:288
virtual bool info(unsigned inf) const
Information about the object.
Definition basic.cpp:222
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:510
ex diff(const symbol &s, unsigned nth=1) const
Default interface of nth derivative ex::diff(s, n).
Definition basic.cpp:646
virtual ex scalar_mul_indexed(const ex &self, const numeric &other) const
Multiply an indexed expression with a scalar.
Definition basic.cpp:493
unsigned hashvalue
hash value
Definition basic.h:303
void ensure_if_modifiable() const
Ensure the object may be modified without hurting others, throws if this is not the case.
Definition basic.cpp:894
virtual bool is_equal_same_type(const basic &other) const
Returns true if two objects of same type are equal.
Definition basic.cpp:729
virtual bool has(const ex &other, unsigned options=0) const
Test for occurrence of a pattern.
Definition basic.cpp:280
virtual ex evalm() const
Evaluate sums, products and integer powers of matrices.
Definition basic.cpp:441
friend class ex
Definition basic.h:108
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:465
virtual int degree(const ex &s) const
Return degree of highest power in object s.
Definition basic.cpp:325
virtual ex conjugate() const
Definition basic.cpp:671
virtual unsigned precedence() const
Return relative operator precedence (for parenthezing output).
Definition basic.cpp:214
virtual ex op(size_t i) const
Return operand/member at position i.
Definition basic.cpp:238
unsigned flags
of type status_flags
Definition basic.h:302
virtual ex add_indexed(const ex &self, const ex &other) const
Add two indexed expressions.
Definition basic.cpp:481
const basic & operator=(const basic &other)
basic assignment operator: the other object might be of a derived class.
Definition basic.cpp:64
virtual void print(const print_context &c, unsigned level=0) const
Output to stream.
Definition basic.cpp:116
void do_print(const print_context &c, unsigned level) const
Default output to stream.
Definition basic.cpp:169
virtual void read_archive(const archive_node &n, lst &syms)
Load (deserialize) the object from an archive node.
Definition basic.cpp:96
ex subs_one_level(const exmap &m, unsigned options) const
Helper function for subs().
Definition basic.cpp:585
const basic & hold() const
Stop further evaluation.
Definition basic.cpp:887
bool is_equal(const basic &other) const
Test for syntactic equality.
Definition basic.cpp:863
virtual ex collect(const ex &s, bool distributed=false) const
Sort expanded expression in terms of powers of some object(s).
Definition basic.cpp:348
virtual ex subs(const exmap &m, unsigned options=0) const
Substitute a set of objects by arbitrary expressions.
Definition basic.cpp:607
virtual ex real_part() const
Definition basic.cpp:676
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
Definition basic.cpp:719
virtual ex & let_op(size_t i)
Return modifiable operand/member at position i.
Definition basic.cpp:244
virtual basic * duplicate() const
Create a clone of this object on the heap.
Definition basic.h:131
virtual void dbgprint() const
Little wrapper around print to be called within a debugger.
Definition basic.cpp:199
void do_print_tree(const print_tree &c, unsigned level) const
Tree output to stream.
Definition basic.cpp:175
virtual ex coeff(const ex &s, int n=1) const
Return coefficient of degree n in object s.
Definition basic.cpp:337
virtual unsigned return_type() const
Definition basic.cpp:751
virtual ex eval_ncmul(const exvector &v) const
Definition basic.cpp:686
void do_print_python_repr(const print_python_repr &c, unsigned level) const
Python parsable output to stream.
Definition basic.cpp:187
virtual ex derivative(const symbol &s) const
Default implementation of ex::diff().
Definition basic.cpp:704
virtual int ldegree(const ex &s) const
Return degree of lowest power in object s.
Definition basic.cpp:331
virtual ex expand(unsigned options=0) const
Expand expression, i.e.
Definition basic.cpp:796
int compare(const basic &other) const
Compare objects syntactically to establish canonical ordering.
Definition basic.cpp:816
virtual ex evalf() const
Evaluate object numerically.
Definition basic.cpp:425
virtual ex operator[](const ex &index) const
Definition basic.cpp:250
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:770
virtual exvector get_free_indices() const
Return a vector containing the free indices of an expression.
Definition basic.cpp:666
virtual bool is_polynomial(const ex &var) const
Check whether this is a polynomial in the given variables.
Definition basic.cpp:319
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:294
class_info * get_parent() const
Get pointer to class_info of parent class (or nullptr).
Definition class_info.h:50
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:88
ex expand(unsigned options=0) const
Expand an expression.
Definition ex.cpp:75
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:82
This class holds a two-component object, a basis and and exponent representing exponentiation.
Definition power.h:39
unsigned get_id() const
Definition print.h:42
Base class for print_contexts.
Definition print.h:103
std::ostream & s
stream to output to
Definition print.h:109
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
const unsigned delta_indent
size of indentation step
Definition print.h:153
void set_refcount(unsigned int r) noexcept
Definition ptr.h:42
unsigned int get_refcount() const noexcept
Definition ptr.h:41
Flags to store information about the state of an object.
Definition flags.h:199
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
Definition flags.h:204
@ evaluated
.eval() has already done its job
Definition flags.h:203
@ hash_calculated
.calchash() has already done its job
Definition flags.h:205
@ no_pattern
disable pattern matching
Definition flags.h:51
Basic CAS symbol.
Definition symbol.h:39
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:38
ex hold_ncmul(const exvector &v)
Definition ncmul.cpp:614
const numeric pow(const numeric &x, const numeric &y)
Definition numeric.h:251
container< std::list > lst
Definition lst.h:32
std::map< ex, ex, ex_is_less > exmap
Definition basic.h:50
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
B & dynallocate(Args &&... args)
Constructs a new (class basic or derived) B object on the heap.
Definition basic.h:334
class_info< registered_class_options > registered_class_info
Definition registrar.h:126
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 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:243
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
Definition idx.cpp:45
bool is_a(const basic &obj)
Check if obj is a T, including base classes.
Definition basic.h:313
class_info< print_context_options > print_context_class_info
Definition print.h:50
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
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 is_exactly_a(const basic &obj)
Check if obj is a T, not including base classes.
Definition basic.h:320
const ex _ex0
Definition utils.cpp:369
std::vector< ex > exvector
Definition basic.h:48
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:185
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.