-
- if (is_ex_exactly_of_type(lh,numeric)) {
- if (is_ex_exactly_of_type(rh,numeric)) {
- combine_overall_coeff(lh);
- combine_overall_coeff(rh);
- } else {
- combine_overall_coeff(lh);
- seq.push_back(split_ex_to_pair(rh));
- }
- } else {
- if (is_ex_exactly_of_type(rh,numeric)) {
- combine_overall_coeff(rh);
- seq.push_back(split_ex_to_pair(lh));
- } else {
- expair p1=split_ex_to_pair(lh);
- expair p2=split_ex_to_pair(rh);
-
- int cmpval=p1.rest.compare(p2.rest);
- if (cmpval==0) {
- p1.coeff=ex_to_numeric(p1.coeff).add_dyn(ex_to_numeric(p2.coeff));
- if (!ex_to_numeric(p1.coeff).is_zero()) {
- // no further processing is necessary, since this
- // one element will usually be recombined in eval()
- seq.push_back(p1);
- }
- } else {
- seq.reserve(2);
- if (cmpval<0) {
- seq.push_back(p1);
- seq.push_back(p2);
- } else {
- seq.push_back(p2);
- seq.push_back(p1);
- }
- }
- }
- }
-}
-
-void expairseq::construct_from_2_expairseq(expairseq const & s1,
- expairseq const & s2)
-{
- combine_overall_coeff(s1.overall_coeff);
- combine_overall_coeff(s2.overall_coeff);
-
- epvector::const_iterator first1=s1.seq.begin();
- epvector::const_iterator last1=s1.seq.end();
- epvector::const_iterator first2=s2.seq.begin();
- epvector::const_iterator last2=s2.seq.end();
-
- seq.reserve(s1.seq.size()+s2.seq.size());
-
- bool needs_further_processing=false;
-
- while (first1!=last1 && first2!=last2) {
- int cmpval=(*first1).rest.compare((*first2).rest);
- if (cmpval==0) {
- // combine terms
- numeric const & newcoeff=ex_to_numeric((*first1).coeff).
- add(ex_to_numeric((*first2).coeff));
- if (!newcoeff.is_zero()) {
- seq.push_back(expair((*first1).rest,newcoeff));
- if (expair_needs_further_processing(seq.end()-1)) {
- needs_further_processing = true;
- }
- }
- ++first1;
- ++first2;
- } else if (cmpval<0) {
- seq.push_back(*first1);
- ++first1;
- } else {
- seq.push_back(*first2);
- ++first2;
- }
- }
-
- while (first1!=last1) {
- seq.push_back(*first1);
- ++first1;
- }
- while (first2!=last2) {
- seq.push_back(*first2);
- ++first2;
- }
-
- if (needs_further_processing) {
- epvector v=seq;
- seq.clear();
- construct_from_epvector(v);
- }
-}
-
-void expairseq::construct_from_expairseq_ex(expairseq const & s,
- ex const & e)
-{
- combine_overall_coeff(s.overall_coeff);
- if (is_ex_exactly_of_type(e,numeric)) {
- combine_overall_coeff(e);
- seq=s.seq;
- return;
- }
-
- epvector::const_iterator first=s.seq.begin();
- epvector::const_iterator last=s.seq.end();
- expair p=split_ex_to_pair(e);
-
- seq.reserve(s.seq.size()+1);
- bool p_pushed=0;
-
- bool needs_further_processing=false;
-
- // merge p into s.seq
- while (first!=last) {
- int cmpval=(*first).rest.compare(p.rest);
- if (cmpval==0) {
- // combine terms
- numeric const & newcoeff=ex_to_numeric((*first).coeff).
- add(ex_to_numeric(p.coeff));
- if (!newcoeff.is_zero()) {
- seq.push_back(expair((*first).rest,newcoeff));
- if (expair_needs_further_processing(seq.end()-1)) {
- needs_further_processing = true;
- }
- }
- ++first;
- p_pushed=1;
- break;
- } else if (cmpval<0) {
- seq.push_back(*first);
- ++first;
- } else {
- seq.push_back(p);
- p_pushed=1;
- break;
- }
- }
-
- if (p_pushed) {
- // while loop exited because p was pushed, now push rest of s.seq
- while (first!=last) {
- seq.push_back(*first);
- ++first;
- }
- } else {
- // while loop exited because s.seq was pushed, now push p
- seq.push_back(p);
- }
-
- if (needs_further_processing) {
- epvector v=seq;
- seq.clear();
- construct_from_epvector(v);
- }
-}
-
-void expairseq::construct_from_exvector(exvector const & v)
-{
- // simplifications: +(a,+(b,c),d) -> +(a,b,c,d) (associativity)
- // +(d,b,c,a) -> +(a,b,c,d) (canonicalization)
- // +(...,x,*(x,c1),*(x,c2)) -> +(...,*(x,1+c1+c2)) (c1, c2 numeric())
- // (same for (+,*) -> (*,^)
-
- make_flat(v);
+
+ if (is_ex_exactly_of_type(lh,numeric)) {
+ if (is_ex_exactly_of_type(rh,numeric)) {
+ combine_overall_coeff(lh);
+ combine_overall_coeff(rh);
+ } else {
+ combine_overall_coeff(lh);
+ seq.push_back(split_ex_to_pair(rh));
+ }
+ } else {
+ if (is_ex_exactly_of_type(rh,numeric)) {
+ combine_overall_coeff(rh);
+ seq.push_back(split_ex_to_pair(lh));
+ } else {
+ expair p1=split_ex_to_pair(lh);
+ expair p2=split_ex_to_pair(rh);
+
+ int cmpval=p1.rest.compare(p2.rest);
+ if (cmpval==0) {
+ p1.coeff=ex_to_numeric(p1.coeff).add_dyn(ex_to_numeric(p2.coeff));
+ if (!ex_to_numeric(p1.coeff).is_zero()) {
+ // no further processing is necessary, since this
+ // one element will usually be recombined in eval()
+ seq.push_back(p1);
+ }
+ } else {
+ seq.reserve(2);
+ if (cmpval<0) {
+ seq.push_back(p1);
+ seq.push_back(p2);
+ } else {
+ seq.push_back(p2);
+ seq.push_back(p1);
+ }
+ }
+ }
+ }
+}
+
+void expairseq::construct_from_2_expairseq(const expairseq & s1,
+ const expairseq & s2)
+{
+ combine_overall_coeff(s1.overall_coeff);
+ combine_overall_coeff(s2.overall_coeff);
+
+ epvector::const_iterator first1=s1.seq.begin();
+ epvector::const_iterator last1=s1.seq.end();
+ epvector::const_iterator first2=s2.seq.begin();
+ epvector::const_iterator last2=s2.seq.end();
+
+ seq.reserve(s1.seq.size()+s2.seq.size());
+
+ bool needs_further_processing=false;
+
+ while (first1!=last1 && first2!=last2) {
+ int cmpval=(*first1).rest.compare((*first2).rest);
+ if (cmpval==0) {
+ // combine terms
+ const numeric & newcoeff = ex_to_numeric((*first1).coeff).
+ add(ex_to_numeric((*first2).coeff));
+ if (!newcoeff.is_zero()) {
+ seq.push_back(expair((*first1).rest,newcoeff));
+ if (expair_needs_further_processing(seq.end()-1)) {
+ needs_further_processing = true;
+ }
+ }
+ ++first1;
+ ++first2;
+ } else if (cmpval<0) {
+ seq.push_back(*first1);
+ ++first1;
+ } else {
+ seq.push_back(*first2);
+ ++first2;
+ }
+ }
+
+ while (first1!=last1) {
+ seq.push_back(*first1);
+ ++first1;
+ }
+ while (first2!=last2) {
+ seq.push_back(*first2);
+ ++first2;
+ }
+
+ if (needs_further_processing) {
+ epvector v=seq;
+ seq.clear();
+ construct_from_epvector(v);
+ }
+}
+
+void expairseq::construct_from_expairseq_ex(const expairseq & s,
+ const ex & e)
+{
+ combine_overall_coeff(s.overall_coeff);
+ if (is_ex_exactly_of_type(e,numeric)) {
+ combine_overall_coeff(e);
+ seq=s.seq;
+ return;
+ }
+
+ epvector::const_iterator first=s.seq.begin();
+ epvector::const_iterator last=s.seq.end();
+ expair p=split_ex_to_pair(e);
+
+ seq.reserve(s.seq.size()+1);
+ bool p_pushed=0;
+
+ bool needs_further_processing=false;
+
+ // merge p into s.seq
+ while (first!=last) {
+ int cmpval=(*first).rest.compare(p.rest);
+ if (cmpval==0) {
+ // combine terms
+ const numeric & newcoeff = ex_to_numeric((*first).coeff).
+ add(ex_to_numeric(p.coeff));
+ if (!newcoeff.is_zero()) {
+ seq.push_back(expair((*first).rest,newcoeff));
+ if (expair_needs_further_processing(seq.end()-1)) {
+ needs_further_processing = true;
+ }
+ }
+ ++first;
+ p_pushed=1;
+ break;
+ } else if (cmpval<0) {
+ seq.push_back(*first);
+ ++first;
+ } else {
+ seq.push_back(p);
+ p_pushed=1;
+ break;
+ }
+ }
+
+ if (p_pushed) {
+ // while loop exited because p was pushed, now push rest of s.seq
+ while (first!=last) {
+ seq.push_back(*first);
+ ++first;
+ }
+ } else {
+ // while loop exited because s.seq was pushed, now push p
+ seq.push_back(p);
+ }
+
+ if (needs_further_processing) {
+ epvector v=seq;
+ seq.clear();
+ construct_from_epvector(v);
+ }
+}
+
+void expairseq::construct_from_exvector(const exvector & v)
+{
+ // simplifications: +(a,+(b,c),d) -> +(a,b,c,d) (associativity)
+ // +(d,b,c,a) -> +(a,b,c,d) (canonicalization)
+ // +(...,x,*(x,c1),*(x,c2)) -> +(...,*(x,1+c1+c2)) (c1, c2 numeric())
+ // (same for (+,*) -> (*,^)
+
+ make_flat(v);