]> www.ginac.de Git - ginac.git/blobdiff - ginac/expairseq.cpp
Finalize 1.7.6 release.
[ginac.git] / ginac / expairseq.cpp
index 9ca4070934e41fd60ea9bc111153279c07fbe0d4..a1361532fc9994c7c920560f3893bca469aea286 100644 (file)
@@ -3,7 +3,7 @@
  *  Implementation of sequences of expression pairs. */
 
 /*
- *  GiNaC Copyright (C) 1999-2015 Johannes Gutenberg University Mainz, Germany
+ *  GiNaC Copyright (C) 1999-2019 Johannes Gutenberg University Mainz, Germany
  *
  *  This program is free software; you can redistribute it and/or modify
  *  it under the terms of the GNU General Public License as published by
@@ -239,12 +239,12 @@ ex expairseq::map(map_function &f) const
 }
 
 /** Perform coefficient-wise automatic term rewriting rules in this class. */
-ex expairseq::eval(int level) const
+ex expairseq::eval() const
 {
-       if ((level==1) && (flags &status_flags::evaluated))
+       if (flags &status_flags::evaluated)
                return *this;
 
-       const epvector evaled = evalchildren(level);
+       const epvector evaled = evalchildren();
        if (!evaled.empty())
                return dynallocate<expairseq>(std::move(evaled), overall_coeff).setflag(status_flags::evaluated);
        else
@@ -265,7 +265,7 @@ epvector* conjugateepvector(const epvector&epv)
                }
                newepv = new epvector;
                newepv->reserve(epv.size());
-               for (epvector::const_iterator j=epv.begin(); j!=i; ++j) {
+               for (auto j=epv.begin(); j!=i; ++j) {
                        newepv->push_back(*j);
                }
                newepv->push_back(x);
@@ -565,6 +565,11 @@ ex expairseq::recombine_pair_to_ex(const expair &p) const
 
 bool expairseq::expair_needs_further_processing(epp it)
 {
+       if (is_exactly_a<numeric>(it->rest) &&
+           it->coeff.is_equal(_ex1)) {
+               // the pair {<n>, 1} has yet to be absorbed into overall_coeff
+               return true;
+       }
        return false;
 }
 
@@ -599,19 +604,11 @@ bool expairseq::can_make_flat(const expair &p) const
 // non-virtual functions in this class
 //////////
 
-void expairseq::construct_from_2_ex_via_exvector(const ex &lh, const ex &rh)
-{
-       exvector v;
-       v.reserve(2);
-       v.push_back(lh);
-       v.push_back(rh);
-       construct_from_exvector(v);
-}
-
 void expairseq::construct_from_2_ex(const ex &lh, const ex &rh)
 {
-       if (typeid(ex_to<basic>(lh)) == typeid(*this)) {
-               if (typeid(ex_to<basic>(rh)) == typeid(*this)) {
+       const std::type_info& typeid_this = typeid(*this);
+       if (typeid(ex_to<basic>(lh)) == typeid_this) {
+               if (typeid(ex_to<basic>(rh)) == typeid_this) {
                        if (is_a<mul>(lh) && lh.info(info_flags::has_indices) && 
                                rh.info(info_flags::has_indices)) {
                                ex newrh=rename_dummy_indices_uniquely(lh, rh);
@@ -626,7 +623,7 @@ void expairseq::construct_from_2_ex(const ex &lh, const ex &rh)
                        construct_from_expairseq_ex(ex_to<expairseq>(lh), rh);
                        return;
                }
-       } else if (typeid(ex_to<basic>(rh)) == typeid(*this)) {
+       } else if (typeid(ex_to<basic>(rh)) == typeid_this) {
                construct_from_expairseq_ex(ex_to<expairseq>(rh),lh);
                return;
        }
@@ -828,9 +825,10 @@ void expairseq::make_flat(const exvector &v)
        int nexpairseqs = 0;
        int noperands = 0;
        bool do_idx_rename = false;
-       
+
+       const std::type_info& typeid_this = typeid(*this);
        for (auto & cit : v) {
-               if (typeid(ex_to<basic>(cit)) == typeid(*this)) {
+               if (typeid(ex_to<basic>(cit)) == typeid_this) {
                        ++nexpairseqs;
                        noperands += ex_to<expairseq>(cit).seq.size();
                }
@@ -845,7 +843,7 @@ void expairseq::make_flat(const exvector &v)
        // copy elements and split off numerical part
        make_flat_inserter mf(v, do_idx_rename);
        for (auto & cit : v) {
-               if (typeid(ex_to<basic>(cit)) == typeid(*this)) {
+               if (typeid(ex_to<basic>(cit)) == typeid_this) {
                        ex newfactor = mf.handle_factor(cit, _ex1);
                        const expairseq &subseqref = ex_to<expairseq>(newfactor);
                        combine_overall_coeff(subseqref.overall_coeff);
@@ -872,9 +870,10 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming)
        int nexpairseqs = 0;
        int noperands = 0;
        bool really_need_rename_inds = false;
-       
+
+       const std::type_info& typeid_this = typeid(*this);
        for (auto & cit : v) {
-               if (typeid(ex_to<basic>(cit.rest)) == typeid(*this)) {
+               if (typeid(ex_to<basic>(cit.rest)) == typeid_this) {
                        ++nexpairseqs;
                        noperands += ex_to<expairseq>(cit.rest).seq.size();
                }
@@ -890,12 +889,11 @@ void expairseq::make_flat(const epvector &v, bool do_index_renaming)
        
        // copy elements and split off numerical part
        for (auto & cit : v) {
-               if (typeid(ex_to<basic>(cit.rest)) == typeid(*this) &&
+               if (typeid(ex_to<basic>(cit.rest)) == typeid_this &&
                    this->can_make_flat(cit)) {
                        ex newrest = mf.handle_factor(cit.rest, cit.coeff);
                        const expairseq &subseqref = ex_to<expairseq>(newrest);
-                       combine_overall_coeff(ex_to<numeric>(subseqref.overall_coeff),
-                                             ex_to<numeric>(cit.coeff));
+                       combine_overall_coeff(subseqref.overall_coeff, cit.coeff);
                        for (auto & cit_s : subseqref.seq) {
                                seq.push_back(expair(cit_s.rest,
                                                     ex_to<numeric>(cit_s.coeff).mul_dyn(ex_to<numeric>(cit.coeff))));
@@ -1048,15 +1046,11 @@ epvector expairseq::expandchildren(unsigned options) const
  *  @see expairseq::eval()
  *  @return epvector containing evaluated pairs, empty if no members
  *    had to be changed. */
-epvector expairseq::evalchildren(int level) const
+epvector expairseq::evalchildren() const
 {
-       if (level == -max_recursion_level)
-               throw(std::runtime_error("max recursion level reached"));
-
        auto cit = seq.begin(), last = seq.end();
        while (cit!=last) {
-               const ex evaled_rest = level==1 ? cit->rest : cit->rest.eval(level-1);
-               const expair evaled_pair = combine_ex_with_coeff_to_pair(evaled_rest, cit->coeff);
+               const expair evaled_pair = combine_ex_with_coeff_to_pair(cit->rest, cit->coeff);
                if (unlikely(!evaled_pair.is_equal(*cit))) {
 
                        // something changed: copy seq, eval and return it
@@ -1072,8 +1066,7 @@ epvector expairseq::evalchildren(int level) const
 
                        // copy rest
                        while (cit != last) {
-                               const ex evaled_rest = level==1 ? cit->rest : cit->rest.eval(level-1);
-                               s.push_back(combine_ex_with_coeff_to_pair(evaled_rest, cit->coeff));
+                               s.push_back(combine_ex_with_coeff_to_pair(cit->rest, cit->coeff));
                                ++cit;
                        }
                        return s;