58 bool operator()(
const epp &lh,
const epp &rh)
const
60 return (*lh).is_less(*rh);
113 inherited::read_archive(
n, sym_lst);
114 auto range =
n.find_property_range(
"rest",
"coeff");
115 seq.reserve((range.end-range.begin)/2);
117 for (
auto loc = range.begin; loc < range.end;) {
120 n.find_ex_by_loc(loc++, rest, sym_lst);
121 n.find_ex_by_loc(loc++,
coeff, sym_lst);
133 inherited::archive(
n);
134 for (
auto & i :
seq) {
135 n.add_ex(
"rest", i.rest);
136 n.add_ex(
"coeff", i.coeff);
157 c.s << std::string(level,
' ') << class_name() <<
" @" <<
this
158 << std::hex <<
", hash=0x" <<
hashvalue <<
", flags=0x" <<
flags << std::dec
159 <<
", nops=" <<
nops()
161 size_t num =
seq.size();
162 for (
size_t i=0; i<num; ++i) {
163 seq[i].rest.print(
c, level +
c.delta_indent);
164 seq[i].coeff.print(
c, level +
c.delta_indent);
166 c.s << std::string(level +
c.delta_indent,
' ') <<
"-----" << std::endl;
169 c.s << std::string(level +
c.delta_indent,
' ') <<
"-----" << std::endl
170 << std::string(level +
c.delta_indent,
' ') <<
"overall_coeff" << std::endl;
173 c.s << std::string(level +
c.delta_indent,
' ') <<
"=====" << std::endl;
186 for (
auto & i :
seq) {
188 this->
setflag(status_flags::has_indices);
189 this->
clearflag(status_flags::has_no_indices);
193 this->
clearflag(status_flags::has_indices);
194 this->
setflag(status_flags::has_no_indices);
198 return inherited::info(inf);
220 v.reserve(
seq.size()+1);
222 for (
auto & it :
seq)
229 if(is_a<numeric>(newcoeff))
254 for (
auto i=epv.begin(); i!=epv.end(); ++i) {
256 newepv->push_back(i->conjugate());
264 newepv->reserve(epv.size());
265 for (
auto j=epv.begin(); j!=i; ++j) {
266 newepv->push_back(*j);
268 newepv->push_back(
x);
291 if (
typeid(*
this) ==
typeid(ex_to<basic>(pattern))) {
295 bool has_global_wildcard =
false;
297 for (
size_t i=0; i<pattern.
nops(); i++) {
298 if (is_exactly_a<wildcard>(pattern.
op(i))) {
299 has_global_wildcard =
true;
300 global_wildcard = pattern.
op(i);
309 exmap tmp_repl = repl_lst;
317 for (
size_t i=0; i<
nops(); i++)
318 ops.push_back(
op(i));
322 for (
size_t i=0; i<pattern.
nops(); i++) {
323 ex p = pattern.
op(i);
324 if (has_global_wildcard && p.
is_equal(global_wildcard))
326 auto it = ops.
begin(), itend = ops.end();
327 while (it != itend) {
328 if (it->match(p, tmp_repl)) {
338 if (has_global_wildcard) {
343 size_t num = ops.size();
346 for (
size_t i=0; i<num; i++)
349 for (
auto & it : tmp_repl) {
350 if (it.first.is_equal(global_wildcard)) {
359 repl_lst[global_wildcard] = rest;
373 return inherited::match(pattern, repl_lst);
382 return static_cast<const mul *
>(
this)->algebraic_subs_mul(
m,
options);
397 if (
seq.size() != o.
seq.size())
398 return (
seq.size()<o.
seq.size()) ? -1 : 1;
405 auto cit1 =
seq.begin(), last1 =
seq.end();
406 auto cit2 = o.
seq.begin(), last2 = o.
seq.end();
407 for (; (cit1!=last1) && (cit2!=last2); ++cit1, ++cit2) {
408 cmpval = (*cit1).compare(*cit2);
409 if (cmpval!=0)
return cmpval;
423 if (
seq.size()!=o.
seq.size())
430 auto cit2 = o.
seq.begin();
431 for (
auto & cit1 :
seq) {
432 if (!cit1.is_equal(*cit2))
448 for (
auto & i :
seq) {
449 v ^= i.rest.gethash();
451 v ^= i.coeff.gethash();
468 if (!expanded.empty()) {
490 return expairseq(v, oc, do_index_renaming);
495 return expairseq(std::move(vp), oc, do_index_renaming);
508 unsigned this_precedence,
509 unsigned upper_precedence)
const
511 if (this_precedence <= upper_precedence)
513 auto it =
seq.begin(), it_last =
seq.end() - 1;
514 for (; it!=it_last; ++it) {
524 if (this_precedence <= upper_precedence)
565 if (is_exactly_a<numeric>(it->rest) &&
566 it->coeff.is_equal(
_ex1)) {
591 add_dyn(ex_to<numeric>(c1).
mul(ex_to<numeric>(c2)));
606 const std::type_info& typeid_this =
typeid(*this);
607 if (
typeid(ex_to<basic>(lh)) == typeid_this) {
608 if (
typeid(ex_to<basic>(rh)) == typeid_this) {
613 ex_to<expairseq>(newrh));
617 ex_to<expairseq>(rh));
623 }
else if (
typeid(ex_to<basic>(rh)) == typeid_this) {
628 if (is_exactly_a<numeric>(lh)) {
629 if (is_exactly_a<numeric>(rh)) {
637 if (is_exactly_a<numeric>(rh)) {
647 if (!ex_to<numeric>(p1.
coeff).is_zero()) {
672 auto first1 = s1.
seq.begin(), last1 = s1.
seq.end();
673 auto first2 = s2.
seq.begin(), last2 = s2.
seq.end();
675 seq.reserve(s1.
seq.size()+s2.
seq.size());
677 bool needs_further_processing=
false;
679 while (first1!=last1 && first2!=last2) {
680 int cmpval = (*first1).rest.compare((*first2).rest);
684 const numeric &newcoeff = ex_to<numeric>(first1->coeff).
685 add(ex_to<numeric>(first2->coeff));
687 seq.push_back(
expair(first1->rest,newcoeff));
689 needs_further_processing =
true;
694 }
else if (cmpval<0) {
695 seq.push_back(*first1);
698 seq.push_back(*first2);
703 while (first1!=last1) {
704 seq.push_back(*first1);
707 while (first2!=last2) {
708 seq.push_back(*first2);
712 if (needs_further_processing) {
723 if (is_exactly_a<numeric>(e)) {
729 auto first = s.
seq.begin(),
last = s.
seq.end();
732 seq.reserve(s.
seq.size()+1);
733 bool p_pushed =
false;
735 bool needs_further_processing=
false;
738 while (first!=
last) {
739 int cmpval = (*first).rest.compare(p.
rest);
742 const numeric &newcoeff = ex_to<numeric>(first->coeff).
745 seq.push_back(
expair(first->rest,newcoeff));
747 needs_further_processing =
true;
752 }
else if (cmpval<0) {
753 seq.push_back(*first);
764 while (first!=
last) {
765 seq.push_back(*first);
773 if (needs_further_processing) {
811 make_flat(std::move(v), do_index_renaming);
824 bool do_idx_rename =
false;
826 const std::type_info& typeid_this =
typeid(*this);
827 for (
auto & cit : v) {
828 if (
typeid(ex_to<basic>(cit)) == typeid_this) {
830 noperands += ex_to<expairseq>(cit).seq.size();
832 if (is_a<mul>(*
this) && (!do_idx_rename) &&
834 do_idx_rename =
true;
838 seq.reserve(v.size()+noperands-nexpairseqs);
842 for (
auto & cit : v) {
843 if (
typeid(ex_to<basic>(cit)) == typeid_this) {
845 const expairseq &subseqref = ex_to<expairseq>(newfactor);
847 for (
auto & cit_s : subseqref.
seq) {
848 seq.push_back(cit_s);
851 if (is_exactly_a<numeric>(cit))
869 bool really_need_rename_inds =
false;
871 const std::type_info& typeid_this =
typeid(*this);
872 for (
auto & cit : v) {
873 if (
typeid(ex_to<basic>(cit.rest)) == typeid_this) {
875 noperands += ex_to<expairseq>(cit.rest).seq.size();
877 if ((!really_need_rename_inds) && is_a<mul>(*
this) &&
879 really_need_rename_inds =
true;
881 do_index_renaming = do_index_renaming && really_need_rename_inds;
884 seq.reserve(v.size()+noperands-nexpairseqs);
888 for (
auto & cit : v) {
889 if (
typeid(ex_to<basic>(cit.rest)) == typeid_this &&
892 const expairseq &subseqref = ex_to<expairseq>(newrest);
894 for (
auto & cit_s : subseqref.
seq) {
896 ex_to<numeric>(cit_s.coeff).mul_dyn(ex_to<numeric>(cit.coeff))));
899 if (cit.is_canonical_numeric())
928 bool needs_further_processing =
false;
930 auto itin1 =
seq.begin();
931 auto itin2 = itin1 + 1;
936 bool must_copy =
false;
937 while (itin2!=
last) {
938 if (itin1->rest.compare(itin2->rest)==0) {
939 itin1->coeff = ex_to<numeric>(itin1->coeff).
940 add_dyn(ex_to<numeric>(itin2->coeff));
942 needs_further_processing =
true;
945 if (!ex_to<numeric>(itin1->coeff).is_zero()) {
954 if (!ex_to<numeric>(itin1->coeff).is_zero()) {
962 if (needs_further_processing) {
976 auto it =
seq.begin(), itend =
seq.end();
978 for (++it; it!=itend; it_last=it, ++it) {
979 if (!(it_last->is_less(*it) || it_last->is_equal(*it))) {
980 if (!is_exactly_a<numeric>(it_last->rest) ||
981 !is_exactly_a<numeric>(it->rest)) {
983 if (!is_exactly_a<numeric>(it_last->rest) ||
984 !is_exactly_a<numeric>(it->rest)) {
989 std::clog <<
"pair1:" << std::endl;
992 std::clog <<
"pair2:" << std::endl;
1017 s.reserve(
seq.size());
1020 s.insert(s.begin(),
seq.begin(), cit);
1027 while (cit !=
last) {
1055 s.reserve(
seq.size());
1058 s.insert(s.begin(),
seq.begin(), cit);
1061 s.push_back(evaled_pair);
1065 while (cit !=
last) {
1091 for (
auto & it :
m) {
1092 if (is_exactly_a<mul>(it.first) || is_exactly_a<power>(it.first)) {
1105 while (cit !=
last) {
1113 s.reserve(
seq.size());
1116 s.insert(s.begin(),
seq.begin(), cit);
1123 while (cit !=
last) {
1137 while (cit !=
last) {
1145 s.reserve(
seq.size());
1148 s.insert(s.begin(),
seq.begin(), cit);
1151 s.push_back(subsed_pair);
1155 while (cit !=
last) {
Interface to GiNaC's sums of expressions.
Archiving of GiNaC expressions.
#define GINAC_ASSERT(X)
Assertion macro for checking invariances.
This class stores all properties needed to record/retrieve the state of one object of class basic (or...
This class is the ABC (abstract base class) of GiNaC's class hierarchy.
const basic & clearflag(unsigned f) const
Clear some status_flags.
const basic & setflag(unsigned f) const
Set some status_flags.
unsigned hashvalue
hash value
unsigned flags
of type status_flags
ex subs_one_level(const exmap &m, unsigned options) const
Helper function for subs().
const basic & hold() const
Stop further evaluation.
virtual int compare_same_type(const basic &other) const
Returns order relation between two objects of same type.
virtual ex coeff(const ex &s, int n=1) const
Return coefficient of degree n in object s.
Wrapper template for making GiNaC classes out of STL containers.
Lightweight wrapper for GiNaC's symbolic objects.
const_iterator begin() const noexcept
ex expand(unsigned options=0) const
Expand an expression.
bool is_equal(const ex &other) const
ex subs(const exmap &m, unsigned options=0) const
bool info(unsigned inf) const
int compare(const ex &other) const
void print(const print_context &c, unsigned level=0) const
Print expression to stream.
ex coeff(const ex &s, int n=1) const
ex rest
first member of pair, an arbitrary expression
ex coeff
second member of pair, must be numeric
bool is_equal(const expair &other) const
Member-wise check for canonical ordering equality.
A sequence of class expair.
ex eval() const override
Perform coefficient-wise automatic term rewriting rules in this class.
epvector subschildren(const exmap &m, unsigned options=0) const
Member-wise substitute in this sequence.
void combine_same_terms_sorted_seq()
Compact a presorted expairseq by combining all matching expairs to one each.
size_t nops() const override
Number of operands/members.
bool is_equal_same_type(const basic &other) const override
Returns true if two objects of same type are equal.
expairseq(const ex &lh, const ex &rh)
virtual bool expair_needs_further_processing(epp it)
ex conjugate() const override
void construct_from_2_expairseq(const expairseq &s1, const expairseq &s2)
bool match(const ex &pattern, exmap &repl_lst) const override
Check whether the expression matches a given pattern.
ex subs(const exmap &m, unsigned options=0) const override
Substitute a set of objects by arbitrary expressions.
unsigned return_type() const override
void construct_from_epvector(const epvector &v, bool do_index_renaming=false)
void construct_from_2_ex(const ex &lh, const ex &rh)
virtual ex default_overall_coeff() const
void archive(archive_node &n) const override
Save (serialize) the object into archive node.
virtual void printpair(const print_context &c, const expair &p, unsigned upper_precedence) const
bool is_canonical() const
Check if this expairseq is in sorted (canonical) form.
unsigned precedence() const override
Return relative operator precedence (for parenthezing output).
virtual ex thisexpairseq(const epvector &v, const ex &oc, bool do_index_renaming=false) const
Create an object of this type.
virtual expair combine_pair_with_coeff_to_pair(const expair &p, const ex &c) const
bool info(unsigned inf) const override
Information about the object.
void construct_from_exvector(const exvector &v)
void read_archive(const archive_node &n, lst &syms) override
Load (deserialize) the object from an archive node.
virtual expair combine_ex_with_coeff_to_pair(const ex &e, const ex &c) const
void make_flat(const exvector &v)
Combine this expairseq with argument exvector.
virtual void printseq(const print_context &c, char delim, unsigned this_precedence, unsigned upper_precedence) const
virtual bool can_make_flat(const expair &p) const
ex expand(unsigned options=0) const override
Expand expression, i.e.
void construct_from_expairseq_ex(const expairseq &s, const ex &e)
void do_print(const print_context &c, unsigned level) const
epvector evalchildren() const
Member-wise evaluate the expairs in this sequence.
ex op(size_t i) const override
Return operand/member at position i.
virtual ex recombine_pair_to_ex(const expair &p) const
Form an ex out of an expair, using the corresponding semantics.
void do_print_tree(const print_tree &c, unsigned level) const
virtual void combine_overall_coeff(const ex &c)
ex map(map_function &f) const override
Construct new expression by applying the specified function to all sub-expressions (one level only,...
epvector expandchildren(unsigned options) const
Member-wise expand the expairs in this sequence.
void canonicalize()
Brings this expairseq into a sorted (canonical) form.
unsigned calchash() const override
Compute the hash value of an object and if it makes sense to store it in the objects status_flags,...
virtual expair split_ex_to_pair(const ex &e) const
Form an expair from an ex, using the corresponding semantics.
Class to handle the renaming of dummy indices.
ex handle_factor(const ex &x, const ex &coeff)
This class is a wrapper around CLN-numbers within the GiNaC class hierarchy.
bool is_zero() const
True if object is zero.
Base class for print_contexts.
Context for tree-like output for debugging.
@ noncommutative_composite
@ expanded
.expand(0) has already done its job (other expand() options ignore this flag)
@ evaluated
.eval() has already done its job
@ hash_calculated
.calchash() has already done its job
@ pattern_is_not_product
used internally by expairseq::subschildren()
@ pattern_is_product
used internally by expairseq::subschildren()
@ algebraic
enable algebraic substitutions
Definition of optimizing macros.
Interface to sequences of expression pairs.
Interface to GiNaC's indexed expressions.
Definition of GiNaC's lst.
Interface to GiNaC's products of expressions.
std::map< ex, ex, ex_is_less > exmap
std::vector< expair > epvector
expair-vector
epvector * conjugateepvector(const epvector &epv)
Complex conjugate every element of an epvector.
bool are_ex_trivially_equal(const ex &e1, const ex &e2)
Compare two objects of class quickly without doing a deep tree traversal.
print_func< print_context >(&varidx::do_print). print_func< print_latex >(&varidx
static unsigned make_hash_seed(const std::type_info &tinfo)
We need a hash function which gives different values for objects of different types.
unsigned rotate_left(unsigned n)
Rotate bits of unsigned value by one bit to the left.
epvector::iterator epp
expair-vector pointer
lst rename_dummy_indices_uniquely(const exvector &va, const exvector &vb)
Similar to above, where va and vb are the same and the return value is a list of two lists for substi...
std::vector< ex > exvector
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.
Interface to relations between expressions.
Function object not caring about the numerical coefficients for insertion into third argument of STL'...
Function object for map().
Interface to several small and furry utilities needed within GiNaC but not of any interest to the use...
Interface to GiNaC's wildcard objects.