GiNaC 1.8.8
ex.h
Go to the documentation of this file.
1
5/*
6 * GiNaC Copyright (C) 1999-2025 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#ifndef GINAC_EX_H
24#define GINAC_EX_H
25
26#include "basic.h"
27#include "ptr.h"
28#include "compiler.h"
29
30#include <functional>
31#include <iosfwd>
32#include <iterator>
33#include <memory>
34#include <stack>
35
36namespace GiNaC {
37#ifdef _MSC_VER
38 // MSVC produces a different symbol for _ex0 when it is declared inside
39 // ex::is_zero() than when it is declared at top level as follows
40 extern const ex _ex0;
41#endif
42
52 static void init_unarchivers();
53public:
56private:
57 static int count;
58};
61
62class scalar_products;
63class const_iterator;
66
67
73class ex {
74 friend class archive_node;
75 friend inline bool are_ex_trivially_equal(const ex &, const ex &);
76 template<class T> friend inline const T &ex_to(const ex &);
77 template<class T> friend inline bool is_a(const ex &);
78 template<class T> friend inline bool is_exactly_a(const ex &);
79
80 // default constructor, copy constructor and assignment operator
81public:
82 ex() noexcept;
83
84 // other constructors
85public:
86 ex(const basic & other);
87 ex(int i);
88 ex(unsigned int i);
89 ex(long i);
90 ex(unsigned long i);
91 ex(long long i);
92 ex(unsigned long long i);
93 ex(double const d);
94
99 ex(const std::string &s, const ex &l);
100
101public:
102 // non-virtual functions in this class
103public:
105 void swap(ex & other) noexcept
106 {
108 GINAC_ASSERT(other.bp->flags & status_flags::dynallocated);
109 bp.swap(other.bp);
110 }
111
112 // iterators
113 const_iterator begin() const noexcept;
114 const_iterator end() const noexcept;
116 const_preorder_iterator preorder_end() const noexcept;
119
120 // evaluation
121 ex eval() const { return bp->eval(); }
122 ex evalf() const { return bp->evalf(); }
123 ex evalm() const { return bp->evalm(); }
124 ex eval_ncmul(const exvector & v) const { return bp->eval_ncmul(v); }
125 ex eval_integ() const { return bp->eval_integ(); }
126
127 // printing
128 void print(const print_context & c, unsigned level = 0) const;
129 void dbgprint() const;
130 void dbgprinttree() const;
131
132 // info
133 bool info(unsigned inf) const { return bp->info(inf); }
134
135 // operand access
136 size_t nops() const { return bp->nops(); }
137 ex op(size_t i) const { return bp->op(i); }
138 ex operator[](const ex & index) const { return (const_cast<const basic&>(*bp))[index]; }
139 ex operator[](size_t i) const { return (const_cast<const basic&>(*bp))[i]; }
140 ex & let_op(size_t i);
141 ex & operator[](const ex & index);
142 ex & operator[](size_t i);
143 ex lhs() const;
144 ex rhs() const;
145
146 // function for complex expressions
147 ex conjugate() const { return bp->conjugate(); }
148 ex real_part() const { return bp->real_part(); }
149 ex imag_part() const { return bp->imag_part(); }
150
151 // pattern matching
152 bool has(const ex & pattern, unsigned options = 0) const { return bp->has(pattern, options); }
153 bool find(const ex & pattern, exset& found) const;
154 bool match(const ex & pattern) const;
155 bool match(const ex & pattern, exmap & repls) const { return bp->match(pattern, repls); }
156
157 // substitutions
158 ex subs(const exmap & m, unsigned options = 0) const;
159 ex subs(const lst & ls, const lst & lr, unsigned options = 0) const;
160 ex subs(const ex & e, unsigned options = 0) const;
161
162 // function mapping
163 ex map(map_function & f) const { return bp->map(f); }
164 ex map(ex (*f)(const ex & e)) const;
165
166 // visitors and tree traversal
167 void accept(visitor & v) const { bp->accept(v); }
168 void traverse_preorder(visitor & v) const;
169 void traverse_postorder(visitor & v) const;
170 void traverse(visitor & v) const { traverse_preorder(v); }
171
172 // degree/coeff
173 bool is_polynomial(const ex & vars) const;
174 int degree(const ex & s) const { return bp->degree(s); }
175 int ldegree(const ex & s) const { return bp->ldegree(s); }
176 ex coeff(const ex & s, int n = 1) const { return bp->coeff(s, n); }
177 ex lcoeff(const ex & s) const { return coeff(s, degree(s)); }
178 ex tcoeff(const ex & s) const { return coeff(s, ldegree(s)); }
179
180 // expand/collect
181 ex expand(unsigned options=0) const;
182 ex collect(const ex & s, bool distributed = false) const { return bp->collect(s, distributed); }
183
184 // differentiation and series expansion
185 ex diff(const symbol & s, unsigned nth = 1) const;
186 ex series(const ex & r, int order, unsigned options = 0) const;
187
188 // rational functions
189 ex normal() const;
190 ex to_rational(exmap & repl) const;
191 ex to_polynomial(exmap & repl) const;
192 ex numer() const;
193 ex denom() const;
194 ex numer_denom() const;
195
196 // polynomial algorithms
197 ex unit(const ex &x) const;
198 ex content(const ex &x) const;
199 numeric integer_content() const;
200 ex primpart(const ex &x) const;
201 ex primpart(const ex &x, const ex &cont) const;
202 void unitcontprim(const ex &x, ex &u, ex &c, ex &p) const;
203 ex smod(const numeric &xi) const { return bp->smod(xi); }
204 numeric max_coefficient() const;
205
206 // indexed objects
207 exvector get_free_indices() const { return bp->get_free_indices(); }
208 ex simplify_indexed(unsigned options = 0) const;
209 ex simplify_indexed(const scalar_products & sp, unsigned options = 0) const;
210
211 // comparison
212 int compare(const ex & other) const;
213 bool is_equal(const ex & other) const;
214 bool is_zero() const {
215#ifndef _MSC_VER
216 extern const ex _ex0;
217#endif
218 return is_equal(_ex0);
219 }
220 bool is_zero_matrix() const;
221
222 // symmetry
223 ex symmetrize() const;
224 ex symmetrize(const lst & l) const;
225 ex antisymmetrize() const;
226 ex antisymmetrize(const lst & l) const;
227 ex symmetrize_cyclic() const;
228 ex symmetrize_cyclic(const lst & l) const;
229
230 // noncommutativity
231 unsigned return_type() const { return bp->return_type(); }
232 return_type_t return_type_tinfo() const { return bp->return_type_tinfo(); }
233
234 unsigned gethash() const { return bp->gethash(); }
235
236private:
237 static ptr<basic> construct_from_basic(const basic & other);
238 static basic & construct_from_int(int i);
239 static basic & construct_from_uint(unsigned int i);
240 static basic & construct_from_long(long i);
241 static basic & construct_from_ulong(unsigned long i);
242 static basic & construct_from_longlong(long long i);
243 static basic & construct_from_ulonglong(unsigned long long i);
244 static basic & construct_from_double(double d);
245 static ptr<basic> construct_from_string_and_lst(const std::string &s, const ex &l);
246 void makewriteable();
247 void share(const ex & other) const;
248
249// member variables
250
251private:
252 mutable ptr<basic> bp;
253};
254
255
256// performance-critical inlined method implementations
257
258// This needs to be a basic* because we don't know that numeric is derived
259// from basic and we need a basic& for the ex default constructor
260extern const basic *_num0_bp;
261
262inline
263ex::ex() noexcept : bp(*const_cast<basic *>(_num0_bp))
264{
266}
267
268inline
269ex::ex(const basic & other) : bp(construct_from_basic(other))
270{
272}
273
274inline
275ex::ex(int i) : bp(construct_from_int(i))
276{
278}
279
280inline
281ex::ex(unsigned int i) : bp(construct_from_uint(i))
282{
284}
285
286inline
287ex::ex(long i) : bp(construct_from_long(i))
288{
290}
291
292inline
293ex::ex(unsigned long i) : bp(construct_from_ulong(i))
294{
296}
297
298inline
299ex::ex(long long i) : bp(construct_from_longlong(i))
300{
302}
303
304inline
305ex::ex(unsigned long long i) : bp(construct_from_ulonglong(i))
306{
308}
309
310inline
311ex::ex(double const d) : bp(construct_from_double(d))
312{
314}
315
316inline
317ex::ex(const std::string &s, const ex &l) : bp(construct_from_string_and_lst(s, l))
318{
320}
321
322inline
323int ex::compare(const ex & other) const
324{
325#ifdef GINAC_COMPARE_STATISTICS
326 compare_statistics.total_compares++;
327#endif
328 if (bp == other.bp) // trivial case: both expressions point to same basic
329 return 0;
330#ifdef GINAC_COMPARE_STATISTICS
331 compare_statistics.nontrivial_compares++;
332#endif
333 const int cmpval = bp->compare(*other.bp);
334#if 1
335 if (cmpval == 0) {
336 // Expressions point to different, but equal, trees: conserve
337 // memory and make subsequent compare() operations faster by
338 // making both expressions point to the same tree.
339 share(other);
340 }
341#endif
342 return cmpval;
343}
344
345inline
346bool ex::is_equal(const ex & other) const
347{
348#ifdef GINAC_COMPARE_STATISTICS
349 compare_statistics.total_is_equals++;
350#endif
351 if (bp == other.bp) // trivial case: both expressions point to same basic
352 return true;
353#ifdef GINAC_COMPARE_STATISTICS
354 compare_statistics.nontrivial_is_equals++;
355#endif
356 const bool equal = bp->is_equal(*other.bp);
357#if 0
358 if (equal) {
359 // Expressions point to different, but equal, trees: conserve
360 // memory and make subsequent compare() operations faster by
361 // making both expressions point to the same tree.
362 share(other);
363 }
364#endif
365 return equal;
366}
367
368
369// Iterators
370
372 friend class ex;
375public:
376 using iterator_category = std::random_access_iterator_tag;
377 using value_type = ex;
378 using difference_type = ptrdiff_t;
379 using pointer = const ex *;
380 using reference = const ex &;
381
382 const_iterator() noexcept {}
383
384private:
385 const_iterator(const ex &e_, size_t i_) noexcept : e(e_), i(i_) {}
386
387public:
388 // This should return an ex&, but that would be a reference to a
389 // temporary value
390 ex operator*() const
391 {
392 return e.op(i);
393 }
394
395 // This should return an ex*, but that would be a pointer to a
396 // temporary value
397 std::unique_ptr<ex> operator->() const
398 {
399 return std::unique_ptr<ex>(new ex(operator*()));
400 }
401
403 {
404 return e.op(i + n);
405 }
406
408 {
409 ++i;
410 return *this;
411 }
412
414 {
415 const_iterator tmp = *this;
416 ++i;
417 return tmp;
418 }
419
421 {
422 i += n;
423 return *this;
424 }
425
427 {
428 return const_iterator(e, i + n);
429 }
430
431 inline friend const_iterator operator+(difference_type n, const const_iterator &it) noexcept
432 {
433 return const_iterator(it.e, it.i + n);
434 }
435
437 {
438 --i;
439 return *this;
440 }
441
443 {
444 const_iterator tmp = *this;
445 --i;
446 return tmp;
447 }
448
450 {
451 i -= n;
452 return *this;
453 }
454
456 {
457 return const_iterator(e, i - n);
458 }
459
460 inline friend difference_type operator-(const const_iterator &lhs, const const_iterator &rhs) noexcept
461 {
462 return lhs.i - rhs.i;
463 }
464
465 bool operator==(const const_iterator &other) const noexcept
466 {
467 return are_ex_trivially_equal(e, other.e) && i == other.i;
468 }
469
470 bool operator!=(const const_iterator &other) const noexcept
471 {
472 return !(*this == other);
473 }
474
475 bool operator<(const const_iterator &other) const noexcept
476 {
477 return i < other.i;
478 }
479
480 bool operator>(const const_iterator &other) const noexcept
481 {
482 return other < *this;
483 }
484
485 bool operator<=(const const_iterator &other) const noexcept
486 {
487 return !(other < *this);
488 }
489
490 bool operator>=(const const_iterator &other) const noexcept
491 {
492 return !(*this < other);
493 }
494
495protected:
496 ex e; // this used to be a "const basic *", but in view of object fusion that wouldn't be safe
497 size_t i;
498};
499
500namespace internal {
501
502struct _iter_rep {
503 _iter_rep(const ex &e_, size_t i_, size_t i_end_) : e(e_), i(i_), i_end(i_end_) {}
504
505 bool operator==(const _iter_rep &other) const noexcept
506 {
507 return are_ex_trivially_equal(e, other.e) && i == other.i;
508 }
509
510 bool operator!=(const _iter_rep &other) const noexcept
511 {
512 return !(*this == other);
513 }
514
516 size_t i;
517 size_t i_end;
518};
519
520} // namespace internal
521
523public:
524 using iterator_category = std::forward_iterator_tag;
525 using value_type = ex;
526 using difference_type = ptrdiff_t;
527 using pointer = const ex *;
528 using reference = const ex &;
530
531 const_preorder_iterator(const ex &e, size_t n)
532 {
533 s.push(internal::_iter_rep(e, 0, n));
534 }
535
536public:
538 {
539 return s.top().e;
540 }
541
543 {
544 return &(s.top().e);
545 }
546
548 {
549 increment();
550 return *this;
551 }
552
554 {
555 const_preorder_iterator tmp = *this;
556 increment();
557 return tmp;
558 }
559
560 bool operator==(const const_preorder_iterator &other) const noexcept
561 {
562 return s == other.s;
563 }
564
565 bool operator!=(const const_preorder_iterator &other) const noexcept
566 {
567 return !(*this == other);
568 }
569
570private:
571 std::stack<internal::_iter_rep, std::vector<internal::_iter_rep>> s;
572
574 {
575 while (!s.empty() && s.top().i == s.top().i_end) {
576 s.pop();
577 if (s.empty())
578 return;
579 ++s.top().i;
580 }
581
582 internal::_iter_rep & current = s.top();
583
584 if (current.i != current.i_end) {
585 const ex & child = current.e.op(current.i);
586 s.push(internal::_iter_rep(child, 0, child.nops()));
587 }
588 }
589};
590
592public:
593 using iterator_category = std::forward_iterator_tag;
594 using value_type = ex;
595 using difference_type = ptrdiff_t;
596 using pointer = const ex *;
597 using reference = const ex &;
599
600 const_postorder_iterator(const ex &e, size_t n)
601 {
602 s.push(internal::_iter_rep(e, 0, n));
603 descend();
604 }
605
606public:
608 {
609 return s.top().e;
610 }
611
613 {
614 return &(s.top().e);
615 }
616
618 {
619 increment();
620 return *this;
621 }
622
624 {
625 const_postorder_iterator tmp = *this;
626 increment();
627 return tmp;
628 }
629
630 bool operator==(const const_postorder_iterator &other) const noexcept
631 {
632 return s == other.s;
633 }
634
635 bool operator!=(const const_postorder_iterator &other) const noexcept
636 {
637 return !(*this == other);
638 }
639
640private:
641 std::stack<internal::_iter_rep, std::vector<internal::_iter_rep>> s;
642
643 void descend()
644 {
645 while (s.top().i != s.top().i_end) {
646 internal::_iter_rep & current = s.top();
647 const ex & child = current.e.op(current.i);
648 s.push(internal::_iter_rep(child, 0, child.nops()));
649 }
650 }
651
653 {
654 if (s.top().i == s.top().i_end)
655 s.pop();
656 if (!s.empty()) {
657 ++s.top().i;
658 descend();
659 }
660 }
661};
662
663inline const_iterator ex::begin() const noexcept
664{
665 return const_iterator(*this, 0);
666}
667
668inline const_iterator ex::end() const noexcept
669{
670 return const_iterator(*this, nops());
671}
672
674{
675 return const_preorder_iterator(*this, nops());
676}
677
679{
681}
682
684{
685 return const_postorder_iterator(*this, nops());
686}
687
689{
691}
692
693
694// utility functions
695
700inline bool are_ex_trivially_equal(const ex &e1, const ex &e2)
701{
702 return e1.bp == e2.bp;
703}
704
705/* Function objects for STL sort() etc. */
707 bool operator() (const ex &lh, const ex &rh) const { return lh.compare(rh) < 0; }
708};
709
711 bool operator() (const ex &lh, const ex &rh) const { return lh.is_equal(rh); }
712};
713
715 bool operator() (const ex &lh, const ex &rh) const { return lh.op(0).is_equal(rh.op(0)); }
716};
717
718struct ex_swap {
719 void operator() (ex &lh, ex &rh) const { lh.swap(rh); }
720};
721
722// Make it possible to print exvectors and exmaps
723std::ostream & operator<<(std::ostream & os, const exvector & e);
724std::ostream & operator<<(std::ostream & os, const exset & e);
725std::ostream & operator<<(std::ostream & os, const exmap & e);
726
727// wrapper functions around member functions
728inline size_t nops(const ex & thisex)
729{ return thisex.nops(); }
730
731inline ex expand(const ex & thisex, unsigned options = 0)
732{ return thisex.expand(options); }
733
734inline ex conjugate(const ex & thisex)
735{ return thisex.conjugate(); }
736
737inline ex real_part(const ex & thisex)
738{ return thisex.real_part(); }
739
740inline ex imag_part(const ex & thisex)
741{ return thisex.imag_part(); }
742
743inline bool has(const ex & thisex, const ex & pattern, unsigned options = 0)
744{ return thisex.has(pattern, options); }
745
746inline bool find(const ex & thisex, const ex & pattern, exset& found)
747{ return thisex.find(pattern, found); }
748
749inline bool is_polynomial(const ex & thisex, const ex & vars)
750{ return thisex.is_polynomial(vars); }
751
752inline int degree(const ex & thisex, const ex & s)
753{ return thisex.degree(s); }
754
755inline int ldegree(const ex & thisex, const ex & s)
756{ return thisex.ldegree(s); }
757
758inline ex coeff(const ex & thisex, const ex & s, int n=1)
759{ return thisex.coeff(s, n); }
760
761inline ex numer(const ex & thisex)
762{ return thisex.numer(); }
763
764inline ex denom(const ex & thisex)
765{ return thisex.denom(); }
766
767inline ex numer_denom(const ex & thisex)
768{ return thisex.numer_denom(); }
769
770inline ex normal(const ex & thisex)
771{ return thisex.normal(); }
772
773inline ex to_rational(const ex & thisex, exmap & repl)
774{ return thisex.to_rational(repl); }
775
776inline ex to_polynomial(const ex & thisex, exmap & repl)
777{ return thisex.to_polynomial(repl); }
778
779inline ex collect(const ex & thisex, const ex & s, bool distributed = false)
780{ return thisex.collect(s, distributed); }
781
782inline ex eval(const ex & thisex)
783{ return thisex.eval(); }
784
785inline ex evalf(const ex & thisex)
786{ return thisex.evalf(); }
787
788inline ex evalm(const ex & thisex)
789{ return thisex.evalm(); }
790
791inline ex eval_integ(const ex & thisex)
792{ return thisex.eval_integ(); }
793
794inline ex diff(const ex & thisex, const symbol & s, unsigned nth = 1)
795{ return thisex.diff(s, nth); }
796
797inline ex series(const ex & thisex, const ex & r, int order, unsigned options = 0)
798{ return thisex.series(r, order, options); }
799
800inline bool match(const ex & thisex, const ex & pattern, exmap& repl_lst)
801{ return thisex.match(pattern, repl_lst); }
802
803inline ex simplify_indexed(const ex & thisex, unsigned options = 0)
804{ return thisex.simplify_indexed(options); }
805
806inline ex simplify_indexed(const ex & thisex, const scalar_products & sp, unsigned options = 0)
807{ return thisex.simplify_indexed(sp, options); }
808
809inline ex symmetrize(const ex & thisex)
810{ return thisex.symmetrize(); }
811
812inline ex symmetrize(const ex & thisex, const lst & l)
813{ return thisex.symmetrize(l); }
814
815inline ex antisymmetrize(const ex & thisex)
816{ return thisex.antisymmetrize(); }
817
818inline ex antisymmetrize(const ex & thisex, const lst & l)
819{ return thisex.antisymmetrize(l); }
820
821inline ex symmetrize_cyclic(const ex & thisex)
822{ return thisex.symmetrize_cyclic(); }
823
824inline ex symmetrize_cyclic(const ex & thisex, const lst & l)
825{ return thisex.symmetrize_cyclic(l); }
826
827inline ex op(const ex & thisex, size_t i)
828{ return thisex.op(i); }
829
830inline ex lhs(const ex & thisex)
831{ return thisex.lhs(); }
832
833inline ex rhs(const ex & thisex)
834{ return thisex.rhs(); }
835
836inline bool is_zero(const ex & thisex)
837{ return thisex.is_zero(); }
838
839inline void swap(ex & e1, ex & e2)
840{ e1.swap(e2); }
841
842inline ex ex::subs(const exmap & m, unsigned options) const
843{
844 return bp->subs(m, options);
845}
846
847inline ex subs(const ex & thisex, const exmap & m, unsigned options = 0)
848{ return thisex.subs(m, options); }
849
850inline ex subs(const ex & thisex, const lst & ls, const lst & lr, unsigned options = 0)
851{ return thisex.subs(ls, lr, options); }
852
853inline ex subs(const ex & thisex, const ex & e, unsigned options = 0)
854{ return thisex.subs(e, options); }
855
856
857/* Convert function pointer to function object suitable for map(). */
859protected:
860 ex (*ptr)(const ex &);
861public:
862 explicit pointer_to_map_function(ex x(const ex &)) : ptr(x) {}
863 ex operator()(const ex & e) override { return ptr(e); }
864};
865
866template<class T1>
868protected:
869 ex (*ptr)(const ex &, T1);
871public:
872 explicit pointer_to_map_function_1arg(ex x(const ex &, T1), T1 a1) : ptr(x), arg1(a1) {}
873 ex operator()(const ex & e) override { return ptr(e, arg1); }
874};
875
876template<class T1, class T2>
878protected:
879 ex (*ptr)(const ex &, T1, T2);
882public:
883 explicit pointer_to_map_function_2args(ex x(const ex &, T1, T2), T1 a1, T2 a2) : ptr(x), arg1(a1), arg2(a2) {}
884 ex operator()(const ex & e) override { return ptr(e, arg1, arg2); }
885};
886
887template<class T1, class T2, class T3>
889protected:
890 ex (*ptr)(const ex &, T1, T2, T3);
894public:
895 explicit pointer_to_map_function_3args(ex x(const ex &, T1, T2, T3), T1 a1, T2 a2, T3 a3) : ptr(x), arg1(a1), arg2(a2), arg3(a3) {}
896 ex operator()(const ex & e) override { return ptr(e, arg1, arg2, arg3); }
897};
898
899template<class C>
901protected:
902 ex (C::*ptr)(const ex &);
903 C &c;
904public:
905 explicit pointer_to_member_to_map_function(ex (C::*member)(const ex &), C &obj) : ptr(member), c(obj) {}
906 ex operator()(const ex & e) override { return (c.*ptr)(e); }
907};
908
909template<class C, class T1>
911protected:
912 ex (C::*ptr)(const ex &, T1);
913 C &c;
915public:
916 explicit pointer_to_member_to_map_function_1arg(ex (C::*member)(const ex &, T1), C &obj, T1 a1) : ptr(member), c(obj), arg1(a1) {}
917 ex operator()(const ex & e) override { return (c.*ptr)(e, arg1); }
918};
919
920template<class C, class T1, class T2>
922protected:
923 ex (C::*ptr)(const ex &, T1, T2);
924 C &c;
927public:
928 explicit pointer_to_member_to_map_function_2args(ex (C::*member)(const ex&, T1, T2), C &obj, T1 a1, T2 a2) : ptr(member), c(obj), arg1(a1), arg2(a2) {}
929 ex operator()(const ex & e) override { return (c.*ptr)(e, arg1, arg2); }
930};
931
932template<class C, class T1, class T2, class T3>
934protected:
935 ex (C::*ptr)(const ex &, T1, T2, T3);
936 C &c;
940public:
941 explicit pointer_to_member_to_map_function_3args(ex (C::*member)(const ex &, T1, T2, T3), C &obj, T1 a1, T2 a2, T3 a3) : ptr(member), c(obj), arg1(a1), arg2(a2), arg3(a3) {}
942 ex operator()(const ex & e) override { return (c.*ptr)(e, arg1, arg2, arg3); }
943};
944
945inline ex ex::map(ex f(const ex &)) const
946{
947 pointer_to_map_function fcn(f);
948 return bp->map(fcn);
949}
950
951// convenience type checker template functions
952
954template <class T>
955inline bool is_a(const ex &obj)
956{
957 return is_a<T>(*obj.bp);
958}
959
961template <class T>
962inline bool is_exactly_a(const ex &obj)
963{
964 return is_exactly_a<T>(*obj.bp);
965}
966
977template <class T> attribute_pure
978inline const T &ex_to(const ex &e)
979{
980 GINAC_ASSERT(is_a<T>(e));
981 return static_cast<const T &>(*e.bp);
982}
983
984} // namespace GiNaC
985
986
987// Specializations of Standard Library algorithms
988namespace std {
989
991template <>
992inline void swap(GiNaC::ex &a, GiNaC::ex &b)
993{
994 a.swap(b);
995}
996
998template<>
999struct hash<GiNaC::ex>
1000{
1001 std::size_t operator()(const GiNaC::ex & e) const noexcept
1002 {
1003 return e.gethash();
1004 }
1005};
1006
1008template<>
1009struct equal_to<GiNaC::ex>
1010{
1011 bool operator()(const GiNaC::ex &e1, const GiNaC::ex &e2) const noexcept
1012 {
1013 return e1.is_equal(e2);
1014 }
1015};
1016
1017} // namespace std
1018
1019#endif // ndef GINAC_EX_H
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
Definition assertion.h:33
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
bool operator<(const const_iterator &other) const noexcept
Definition ex.h:475
ptrdiff_t difference_type
Definition ex.h:378
friend const_iterator operator+(difference_type n, const const_iterator &it) noexcept
Definition ex.h:431
const_iterator operator+(difference_type n) const noexcept
Definition ex.h:426
bool operator<=(const const_iterator &other) const noexcept
Definition ex.h:485
ex operator*() const
Definition ex.h:390
friend class ex
Definition ex.h:372
bool operator>(const const_iterator &other) const noexcept
Definition ex.h:480
bool operator>=(const const_iterator &other) const noexcept
Definition ex.h:490
std::random_access_iterator_tag iterator_category
Definition ex.h:376
std::unique_ptr< ex > operator->() const
Definition ex.h:397
bool operator!=(const const_iterator &other) const noexcept
Definition ex.h:470
friend difference_type operator-(const const_iterator &lhs, const const_iterator &rhs) noexcept
Definition ex.h:460
const_iterator(const ex &e_, size_t i_) noexcept
Definition ex.h:385
const_iterator operator-(difference_type n) const noexcept
Definition ex.h:455
const_iterator operator++(int) noexcept
Definition ex.h:413
const_iterator & operator--() noexcept
Definition ex.h:436
bool operator==(const const_iterator &other) const noexcept
Definition ex.h:465
const_iterator & operator+=(difference_type n) noexcept
Definition ex.h:420
const_iterator & operator++() noexcept
Definition ex.h:407
ex operator[](difference_type n) const
Definition ex.h:402
const_iterator() noexcept
Definition ex.h:382
const_iterator & operator-=(difference_type n) noexcept
Definition ex.h:449
const_iterator operator--(int) noexcept
Definition ex.h:442
std::forward_iterator_tag iterator_category
Definition ex.h:593
const_postorder_iterator & operator++()
Definition ex.h:617
bool operator!=(const const_postorder_iterator &other) const noexcept
Definition ex.h:635
std::stack< internal::_iter_rep, std::vector< internal::_iter_rep > > s
Definition ex.h:641
pointer operator->() const
Definition ex.h:612
const_postorder_iterator operator++(int)
Definition ex.h:623
reference operator*() const
Definition ex.h:607
const_postorder_iterator() noexcept
Definition ex.h:598
const_postorder_iterator(const ex &e, size_t n)
Definition ex.h:600
bool operator==(const const_postorder_iterator &other) const noexcept
Definition ex.h:630
const_preorder_iterator() noexcept
Definition ex.h:529
pointer operator->() const
Definition ex.h:542
const_preorder_iterator & operator++()
Definition ex.h:547
const_preorder_iterator operator++(int)
Definition ex.h:553
const_preorder_iterator(const ex &e, size_t n)
Definition ex.h:531
reference operator*() const
Definition ex.h:537
bool operator==(const const_preorder_iterator &other) const noexcept
Definition ex.h:560
std::forward_iterator_tag iterator_category
Definition ex.h:524
std::stack< internal::_iter_rep, std::vector< internal::_iter_rep > > s
Definition ex.h:571
bool operator!=(const const_preorder_iterator &other) const noexcept
Definition ex.h:565
Wrapper template for making GiNaC classes out of STL containers.
Definition container.h:73
Lightweight wrapper for GiNaC's symbolic objects.
Definition ex.h:73
static ptr< basic > construct_from_string_and_lst(const std::string &s, const ex &l)
static basic & construct_from_ulonglong(unsigned long long i)
Definition ex.cpp:544
friend bool is_exactly_a(const ex &)
Check if ex is a handle to a T, not including base classes.
Definition ex.h:962
ex to_rational(exmap &repl) const
Rationalization of non-rational functions.
Definition normal.cpp:2627
static basic & construct_from_longlong(long long i)
Definition ex.cpp:535
ex map(map_function &f) const
Definition ex.h:163
void traverse_preorder(visitor &v) const
Traverse expression tree with given visitor, preorder traversal.
Definition ex.cpp:187
ex operator[](const ex &index) const
Definition ex.h:138
static basic & construct_from_int(int i)
Definition ex.cpp:351
numeric integer_content() const
Compute the integer content (= GCD of all numeric coefficients) of an expanded polynomial.
Definition normal.cpp:318
ex primpart(const ex &x) const
Compute primitive part of a multivariate polynomial in Q[x].
Definition normal.cpp:981
ex lcoeff(const ex &s) const
Definition ex.h:177
static basic & construct_from_uint(unsigned int i)
Definition ex.cpp:409
void traverse(visitor &v) const
Definition ex.h:170
friend bool are_ex_trivially_equal(const ex &, const ex &)
Compare two objects of class quickly without doing a deep tree traversal.
Definition ex.h:700
bool match(const ex &pattern) const
Check whether expression matches a specified pattern.
Definition ex.cpp:96
ex map(ex(*f)(const ex &e)) const
bool match(const ex &pattern, exmap &repls) const
Definition ex.h:155
bool is_polynomial(const ex &vars) const
Check whether expression is a polynomial.
Definition ex.cpp:242
const_preorder_iterator preorder_end() const noexcept
Definition ex.h:678
ex operator[](size_t i) const
Definition ex.h:139
unsigned gethash() const
Definition ex.h:234
const_iterator begin() const noexcept
Definition ex.h:663
exvector get_free_indices() const
Definition ex.h:207
static ptr< basic > construct_from_basic(const basic &other)
Helper function for the ex-from-basic constructor.
Definition ex.cpp:293
ex eval_integ() const
Definition ex.h:125
bool find(const ex &pattern, exset &found) const
Find all occurrences of a pattern.
Definition ex.cpp:106
void accept(visitor &v) const
Definition ex.h:167
ex diff(const symbol &s, unsigned nth=1) const
Compute partial derivative of an expression.
Definition ex.cpp:87
ex expand(unsigned options=0) const
Expand an expression.
Definition ex.cpp:74
ex tcoeff(const ex &s) const
Definition ex.h:178
ex numer_denom() const
Get numerator and denominator of an expression.
Definition normal.cpp:2594
bool is_equal(const ex &other) const
Definition ex.h:346
static basic & construct_from_double(double d)
Definition ex.cpp:553
ex normal() const
Normalization of rational functions.
Definition normal.cpp:2519
int degree(const ex &s) const
Definition ex.h:174
friend const T & ex_to(const ex &)
Return a reference to the basic-derived class T object embedded in an expression.
Definition ex.h:978
ptr< basic > bp
pointer to basic object managed by this
Definition ex.h:252
bool has(const ex &pattern, unsigned options=0) const
Definition ex.h:152
ex & let_op(size_t i)
Return modifiable operand/member at position i.
Definition ex.cpp:207
ex evalf() const
Definition ex.h:122
numeric max_coefficient() const
Return maximum (absolute value) coefficient of a polynomial.
Definition normal.cpp:1154
ex eval_ncmul(const exvector &v) const
Definition ex.h:124
ex conjugate() const
Definition ex.h:147
ex simplify_indexed(unsigned options=0) const
Simplify/canonicalize expression containing indexed objects.
Definition indexed.cpp:1257
bool is_zero_matrix() const
Check whether expression is zero or zero matrix.
Definition ex.cpp:256
ex to_polynomial(exmap &repl) const
Definition normal.cpp:2632
static basic & construct_from_ulong(unsigned long i)
Definition ex.cpp:501
const_postorder_iterator postorder_end() const noexcept
Definition ex.h:688
const_preorder_iterator preorder_begin() const
Definition ex.h:673
ex symmetrize_cyclic() const
Symmetrize expression by cyclic permutation over its free indices.
Definition indexed.cpp:1291
unsigned return_type() const
Definition ex.h:231
void unitcontprim(const ex &x, ex &u, ex &c, ex &p) const
Compute unit part, content part, and primitive part of a multivariate polynomial in Q[x].
Definition normal.cpp:1022
return_type_t return_type_tinfo() const
Definition ex.h:232
void share(const ex &other) const
Share equal objects between expressions.
Definition ex.cpp:279
void swap(ex &other) noexcept
Efficiently swap the contents of two expressions.
Definition ex.h:105
const_iterator end() const noexcept
Definition ex.h:668
size_t nops() const
Definition ex.h:136
static basic & construct_from_long(long i)
Definition ex.cpp:443
ex smod(const numeric &xi) const
Definition ex.h:203
ex series(const ex &r, int order, unsigned options=0) const
Compute the truncated series expansion of an expression.
Definition pseries.cpp:1272
ex imag_part() const
Definition ex.h:149
ex subs(const exmap &m, unsigned options=0) const
Definition ex.h:842
bool info(unsigned inf) const
Definition ex.h:133
int compare(const ex &other) const
Definition ex.h:323
ex symmetrize() const
Symmetrize expression over its free indices.
Definition indexed.cpp:1279
friend bool is_a(const ex &)
Check if ex is a handle to a T, including base classes.
Definition ex.h:955
ex lhs() const
Left hand side of relational expression.
Definition ex.cpp:226
ex denom() const
Get denominator of an expression.
Definition normal.cpp:2569
bool is_zero() const
Definition ex.h:214
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
Definition ex.cpp:55
ex collect(const ex &s, bool distributed=false) const
Definition ex.h:182
void dbgprinttree() const
Little wrapper arount printtree to be called within a debugger.
Definition ex.cpp:67
ex op(size_t i) const
Definition ex.h:137
ex content(const ex &x) const
Compute content part (= unit normal GCD of all coefficients) of a multivariate polynomial in Q[x].
Definition normal.cpp:945
int ldegree(const ex &s) const
Definition ex.h:175
ex rhs() const
Right hand side of relational expression.
Definition ex.cpp:234
ex numer() const
Get numerator of an expression.
Definition normal.cpp:2544
ex eval() const
Definition ex.h:121
ex real_part() const
Definition ex.h:148
ex evalm() const
Definition ex.h:123
ex coeff(const ex &s, int n=1) const
Definition ex.h:176
void dbgprint() const
Little wrapper arount print to be called within a debugger.
Definition ex.cpp:61
void traverse_postorder(visitor &v) const
Traverse expression tree with given visitor, postorder traversal.
Definition ex.cpp:197
const_postorder_iterator postorder_begin() const
Definition ex.h:683
void makewriteable()
Make this ex writable (if more than one ex handle the same basic) by unlinking the object and creatin...
Definition ex.cpp:270
ex antisymmetrize() const
Antisymmetrize expression over its free indices.
Definition indexed.cpp:1285
ex() noexcept
Definition ex.h:263
Helper class to initialize the library.
Definition ex.h:51
library_init()
Ctor of static initialization helpers.
Definition utils.cpp:77
static int count
How many static objects were created? Only the first one must create the static flyweights on the hea...
Definition ex.h:57
static void init_unarchivers()
Definition utils.cpp:260
~library_init()
Dtor of static initialization helpers.
Definition utils.cpp:201
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
Definition numeric.h:82
ex(* ptr)(const ex &, T1)
Definition ex.h:869
ex operator()(const ex &e) override
Definition ex.h:873
pointer_to_map_function_1arg(ex x(const ex &, T1), T1 a1)
Definition ex.h:872
ex operator()(const ex &e) override
Definition ex.h:884
pointer_to_map_function_2args(ex x(const ex &, T1, T2), T1 a1, T2 a2)
Definition ex.h:883
ex(* ptr)(const ex &, T1, T2)
Definition ex.h:879
pointer_to_map_function_3args(ex x(const ex &, T1, T2, T3), T1 a1, T2 a2, T3 a3)
Definition ex.h:895
ex operator()(const ex &e) override
Definition ex.h:896
ex(* ptr)(const ex &, T1, T2, T3)
Definition ex.h:890
ex operator()(const ex &e) override
Definition ex.h:863
ex(* ptr)(const ex &)
Definition ex.h:860
pointer_to_map_function(ex x(const ex &))
Definition ex.h:862
ex operator()(const ex &e) override
Definition ex.h:917
pointer_to_member_to_map_function_1arg(ex(C::*member)(const ex &, T1), C &obj, T1 a1)
Definition ex.h:916
ex operator()(const ex &e) override
Definition ex.h:929
pointer_to_member_to_map_function_2args(ex(C::*member)(const ex &, T1, T2), C &obj, T1 a1, T2 a2)
Definition ex.h:928
pointer_to_member_to_map_function_3args(ex(C::*member)(const ex &, T1, T2, T3), C &obj, T1 a1, T2 a2, T3 a3)
Definition ex.h:941
ex operator()(const ex &e) override
Definition ex.h:942
pointer_to_member_to_map_function(ex(C::*member)(const ex &), C &obj)
Definition ex.h:905
ex operator()(const ex &e) override
Definition ex.h:906
Base class for print_contexts.
Definition print.h:102
Class of (intrusively) reference-counted pointers that support copy-on-write semantics.
Definition ptr.h:56
Helper class for storing information about known scalar products which are to be automatically replac...
Definition indexed.h:217
@ dynallocated
heap-allocated (i.e. created by new if we want to be clever and bypass the stack,
Definition flags.h:202
Basic CAS symbol.
Definition symbol.h:39
Degenerate base class for visitors.
Definition basic.h:97
Definition of optimizing macros.
#define attribute_pure
Definition compiler.h:35
ex unit
Definition factor.cpp:2191
unsigned options
Definition factor.cpp:2474
size_t n
Definition factor.cpp:1432
size_t c
Definition factor.cpp:757
ex x
Definition factor.cpp:1610
size_t r
Definition factor.cpp:757
umodpoly lr[2]
Definition factor.cpp:1428
mvec m
Definition factor.cpp:758
ex cont
Definition factor.cpp:2191
Definition add.cpp:36
bool is_zero(const ex &thisex)
Definition ex.h:836
ex real_part(const ex &thisex)
Definition ex.h:737
std::ostream & operator<<(std::ostream &os, const archive_node &n)
Write archive_node to binary data stream.
Definition archive.cpp:199
ex denom(const ex &thisex)
Definition ex.h:764
bool is_polynomial(const ex &thisex, const ex &vars)
Definition ex.h:749
ex to_rational(const ex &thisex, exmap &repl)
Definition ex.h:773
std::map< ex, ex, ex_is_less > exmap
Definition basic.h:50
std::set< ex, ex_is_less > exset
Definition basic.h:49
ex symmetrize(const ex &thisex)
Definition ex.h:809
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:700
ex rhs(const ex &thisex)
Definition ex.h:833
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:978
ex series(const ex &thisex, const ex &r, int order, unsigned options=0)
Definition ex.h:797
ex conjugate(const ex &thisex)
Definition ex.h:734
ex diff(const ex &thisex, const symbol &s, unsigned nth=1)
Definition ex.h:794
ex simplify_indexed(const ex &thisex, unsigned options=0)
Definition ex.h:803
ex subs(const ex &thisex, const exmap &m, unsigned options=0)
Definition ex.h:847
ex eval(const ex &thisex)
Definition ex.h:782
ex lhs(const ex &thisex)
Definition ex.h:830
int degree(const ex &thisex, const ex &s)
Definition ex.h:752
bool match(const ex &thisex, const ex &pattern, exmap &repl_lst)
Definition ex.h:800
int ldegree(const ex &thisex, const ex &s)
Definition ex.h:755
const basic * _num0_bp
Definition utils.cpp:368
bool is_a(const basic &obj)
Check if obj is a T, including base classes.
Definition basic.h:313
ex evalf(const ex &thisex)
Definition ex.h:785
ex normal(const ex &thisex)
Definition ex.h:770
ex antisymmetrize(const ex &thisex)
Definition ex.h:815
ex op(const ex &thisex, size_t i)
Definition ex.h:827
ex coeff(const ex &thisex, const ex &s, int n=1)
Definition ex.h:758
ex numer(const ex &thisex)
Definition ex.h:761
ex collect(const ex &thisex, const ex &s, bool distributed=false)
Definition ex.h:779
ex eval_integ(const ex &thisex)
Definition ex.h:791
void swap(ex &e1, ex &e2)
Definition ex.h:839
bool find(const ex &thisex, const ex &pattern, exset &found)
Definition ex.h:746
ex evalm(const ex &thisex)
Definition ex.h:788
bool is_exactly_a(const basic &obj)
Check if obj is a T, not including base classes.
Definition basic.h:320
ex symmetrize_cyclic(const ex &thisex)
Definition ex.h:821
bool has(const ex &thisex, const ex &pattern, unsigned options=0)
Definition ex.h:743
const ex _ex0
Definition utils.cpp:369
std::vector< ex > exvector
Definition basic.h:48
ex numer_denom(const ex &thisex)
Definition ex.h:767
size_t nops(const ex &thisex)
Definition ex.h:728
ex imag_part(const ex &thisex)
Definition ex.h:740
ex to_polynomial(const ex &thisex, exmap &repl)
Definition ex.h:776
static library_init library_initializer
For construction of flyweights, etc.
Definition ex.h:60
ex expand(const ex &thisex, unsigned options=0)
Definition ex.h:731
Definition ex.h:988
void swap(GiNaC::ex &a, GiNaC::ex &b)
Specialization of std::swap() for ex objects.
Definition ex.h:992
Reference-counted pointer template.
bool operator()(const ex &lh, const ex &rh) const
Definition ex.h:711
bool operator()(const ex &lh, const ex &rh) const
Definition ex.h:707
void operator()(ex &lh, ex &rh) const
Definition ex.h:719
bool operator==(const _iter_rep &other) const noexcept
Definition ex.h:505
bool operator!=(const _iter_rep &other) const noexcept
Definition ex.h:510
_iter_rep(const ex &e_, size_t i_, size_t i_end_)
Definition ex.h:503
Function object for map().
Definition basic.h:85
bool operator()(const ex &lh, const ex &rh) const
Definition ex.h:715
To distinguish between different kinds of non-commutative objects.
Definition registrar.h:43
bool operator()(const GiNaC::ex &e1, const GiNaC::ex &e2) const noexcept
Definition ex.h:1011
std::size_t operator()(const GiNaC::ex &e) const noexcept
Definition ex.h:1001

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