author Christian Bauer Thu, 18 Dec 2003 18:33:01 +0000 (18:33 +0000) committer Christian Bauer Thu, 18 Dec 2003 18:33:01 +0000 (18:33 +0000)
 ginac/mul.cpp patch | blob | history ginac/mul.h patch | blob | history

@@ -824,6 +824,20 @@ bool mul::can_make_flat(const expair & p) const
return ex_to<numeric>(p.coeff).is_equal(_num1);
}

+bool mul::can_be_further_expanded(const ex & e)
+{
+       if (is_exactly_a<mul>(e)) {
+               for (epvector::const_iterator cit = ex_to<mul>(e).seq.begin(); cit != ex_to<mul>(e).seq.end(); ++cit) {
+                               return true;
+               }
+       } else if (is_exactly_a<power>(e)) {
+                       return true;
+       }
+       return false;
+}
+
ex mul::expand(unsigned options) const
{
// First, expand the children
@@ -833,18 +847,15 @@ ex mul::expand(unsigned options) const
// Now, look for all the factors that are sums and multiply each one out
// with the next one that is found while collecting the factors which are
// not sums
ex last_expanded = _ex1;
+       bool need_reexpand = false;

-       bool non_adds_has_sums = false; // Look for sums or powers of sums in the non_adds (we need this later)

-       epvector::const_iterator cit = expanded_seq.begin(), last = expanded_seq.end();
-       while (cit != last) {
+       for (epvector::const_iterator cit = expanded_seq.begin(); cit != expanded_seq.end(); ++cit) {
(cit->coeff.is_equal(_ex1))) {

// Expand a product of two sums, aggressive version.
@@ -862,6 +873,7 @@ ex mul::expand(unsigned options) const
epvector distrseq;
+
// Multiply add2 with the overall coefficient of add1 and append it to distrseq:
@@ -870,6 +882,7 @@ ex mul::expand(unsigned options) const
}
+
// Multiply add1 with the overall coefficient of add2 and append it to distrseq:
@@ -878,8 +891,10 @@ ex mul::expand(unsigned options) const
}
+
// Compute the new overall coefficient and put it together:
+
// We really have to combine terms here in order to compactify
@@ -889,7 +904,7 @@ ex mul::expand(unsigned options) const
// Don't push_back expairs which might have a rest that evaluates to a numeric,
// since that would violate an invariant of expairseq:
-                                               const ex rest = ex((new mul(i1->rest, i2->rest))->setflag(status_flags::dynallocated)).expand();
+                                               const ex rest = (new mul(i1->rest, i2->rest))->setflag(status_flags::dynallocated);
if (is_exactly_a<numeric>(rest))
oc += ex_to<numeric>(rest).mul(ex_to<numeric>(i1->coeff).mul(ex_to<numeric>(i2->coeff)));
else
@@ -900,47 +915,49 @@ ex mul::expand(unsigned options) const
last_expanded = tmp_accu;

} else {
+                               if (!last_expanded.is_equal(_ex1))
last_expanded = cit->rest;
}
+
} else {
}
-               ++cit;
}

// Now the only remaining thing to do is to multiply the factors which
// were not sums into the "last_expanded" sum
-
+               size_t n = last_expanded.nops();
exvector distrseq;
distrseq.reserve(n);

for (size_t i=0; i<n; ++i) {
-                       factors.push_back(new_factor);
-
-                       const mul & term = static_cast<const mul &>((new mul(factors, overall_coeff))->setflag(status_flags::dynallocated));
-
-                       // The new term may have sums in it if e.g. a sqrt() of a sum in
-                       // the non_adds meets a sqrt() of a sum in the factor from
-                       // last_expanded. In this case we should re-expand the term.
-                               distrseq.push_back(ex(term).expand());
-                       else
-                               distrseq.push_back(term.setflag(options == 0 ? status_flags::expanded : 0));
+                       factors.push_back(split_ex_to_pair(last_expanded.op(i)));
+                       ex term = (new mul(factors, overall_coeff))->setflag(status_flags::dynallocated);
+                       if (can_be_further_expanded(term))
+                               distrseq.push_back(term.expand());
+                       else {
+                               if (options == 0)
+                                       ex_to<basic>(term).setflag(status_flags::expanded);
+                               distrseq.push_back(term);
+                       }
}
+
setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0)));
}
+
-               setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
+       ex result = (new mul(non_adds, overall_coeff))->setflag(status_flags::dynallocated);
+       if (can_be_further_expanded(result)) {
+               return result.expand();
+       } else {
+               if (options == 0)
+                       ex_to<basic>(result).setflag(status_flags::expanded);
+               return result;
+       }
}

index 25c48f4f71beb6de3e08f0b41707afe5f7827725..278446832f563790ced62c12045954f120b063e8 100644 (file)
@@ -91,6 +91,7 @@ protected:
void do_print_latex(const print_latex & c, unsigned level) const;
void do_print_csrc(const print_csrc & c, unsigned level) const;
void do_print_python_repr(const print_python_repr & c, unsigned level) const;
+       static bool can_be_further_expanded(const ex & e);
std::auto_ptr<epvector> expandchildren(unsigned options) const;
};