*
* 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
*
* 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
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
-// default ctor, dctor, copy ctor assignment operator and helpers
+// default ctor, dtor, copy ctor, assignment operator and helpers
construct_from_2_ex(lh,rh);
GINAC_ASSERT(is_canonical());
}
mul::mul(const exvector & v)
{
construct_from_2_ex(lh,rh);
GINAC_ASSERT(is_canonical());
}
mul::mul(const exvector & v)
{
construct_from_exvector(v);
GINAC_ASSERT(is_canonical());
}
mul::mul(const epvector & v)
{
construct_from_exvector(v);
GINAC_ASSERT(is_canonical());
}
mul::mul(const epvector & v)
{
construct_from_epvector(v);
GINAC_ASSERT(is_canonical());
}
mul::mul(const epvector & v, const ex & oc)
{
construct_from_epvector(v);
GINAC_ASSERT(is_canonical());
}
mul::mul(const epvector & v, const ex & oc)
{
if (is_a<print_tree>(c)) {
inherited::print(c, level);
if (is_a<print_tree>(c)) {
inherited::print(c, level);
- if (!overall_coeff.is_equal(_ex1())) {
- overall_coeff.bp->print(c, precedence());
+ if (!overall_coeff.is_equal(_ex1)) {
+ overall_coeff.print(c, precedence());
it->rest.print(c, precedence());
else {
// Outer parens around ex needed for broken gcc-2.95 parser:
it->rest.print(c, precedence());
else {
// Outer parens around ex needed for broken gcc-2.95 parser:
(!(ex_to<numeric>(i->coeff).is_integer())));
GINAC_ASSERT(!(i->is_canonical_numeric()));
if (is_ex_exactly_of_type(recombine_pair_to_ex(*i), numeric))
print(print_tree(std::cerr));
(!(ex_to<numeric>(i->coeff).is_integer())));
GINAC_ASSERT(!(i->is_canonical_numeric()));
if (is_ex_exactly_of_type(recombine_pair_to_ex(*i), numeric))
print(print_tree(std::cerr));
// *(x;1) -> x
return recombine_pair_to_ex(*(seq.begin()));
} else if ((seq_size==1) &&
is_ex_exactly_of_type((*seq.begin()).rest,add) &&
// *(x;1) -> x
return recombine_pair_to_ex(*(seq.begin()));
} else if ((seq_size==1) &&
is_ex_exactly_of_type((*seq.begin()).rest,add) &&
// *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
const add & addref = ex_to<add>((*seq.begin()).rest);
epvector *distrseq = new epvector();
// *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
const add & addref = ex_to<add>((*seq.begin()).rest);
epvector *distrseq = new epvector();
&& is_ex_of_type(seq[0].rest, matrix))
return ex_to<matrix>(seq[0].rest).mul(ex_to<numeric>(overall_coeff));
&& is_ex_of_type(seq[0].rest, matrix))
return ex_to<matrix>(seq[0].rest).mul(ex_to<numeric>(overall_coeff));
epvector::const_iterator i = seq.begin(), end = seq.end();
epvector::iterator i2 = mulseq.begin();
while (i != end) {
epvector::const_iterator i = seq.begin(), end = seq.end();
epvector::iterator i2 = mulseq.begin();
while (i != end) {
if (is_ex_exactly_of_type(powerref.exponent,numeric))
return expair(powerref.basis,powerref.exponent);
}
if (is_ex_exactly_of_type(powerref.exponent,numeric))
return expair(powerref.basis,powerref.exponent);
}
// we create a temporary power object
// otherwise it would be hard to correctly simplify
// expression like (4^(1/3))^(3/2)
// we create a temporary power object
// otherwise it would be hard to correctly simplify
// expression like (4^(1/3))^(3/2)
return split_ex_to_pair(e);
return split_ex_to_pair(power(e,c));
return split_ex_to_pair(e);
return split_ex_to_pair(power(e,c));
// we create a temporary power object
// otherwise it would be hard to correctly simplify
// expression like (4^(1/3))^(3/2)
// we create a temporary power object
// otherwise it would be hard to correctly simplify
// expression like (4^(1/3))^(3/2)
- GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- GINAC_ASSERT(is_ex_exactly_of_type(c,numeric));
+ GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
+ GINAC_ASSERT(is_exactly_a<numeric>(c));
overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c));
}
void mul::combine_overall_coeff(const ex & c1, const ex & c2)
{
overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c));
}
void mul::combine_overall_coeff(const ex & c1, const ex & c2)
{
- GINAC_ASSERT(is_ex_exactly_of_type(overall_coeff,numeric));
- GINAC_ASSERT(is_ex_exactly_of_type(c1,numeric));
- GINAC_ASSERT(is_ex_exactly_of_type(c2,numeric));
+ GINAC_ASSERT(is_exactly_a<numeric>(overall_coeff));
+ GINAC_ASSERT(is_exactly_a<numeric>(c1));
+ GINAC_ASSERT(is_exactly_a<numeric>(c2));
overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c1).power(ex_to<numeric>(c2)));
}
bool mul::can_make_flat(const expair & p) const
{
overall_coeff = ex_to<numeric>(overall_coeff).mul_dyn(ex_to<numeric>(c1).power(ex_to<numeric>(c2)));
}
bool mul::can_make_flat(const expair & p) const
{
// this assertion will probably fail somewhere
// it would require a more careful make_flat, obeying the power laws
// probably should return true only if p.coeff is integer
// this assertion will probably fail somewhere
// it would require a more careful make_flat, obeying the power laws
// probably should return true only if p.coeff is integer
epvector non_adds;
non_adds.reserve(expanded_seq.size());
epvector::const_iterator cit = expanded_seq.begin(), last = expanded_seq.end();
while (cit != last) {
if (is_ex_exactly_of_type(cit->rest, add) &&
epvector non_adds;
non_adds.reserve(expanded_seq.size());
epvector::const_iterator cit = expanded_seq.begin(), last = expanded_seq.end();
while (cit != last) {
if (is_ex_exactly_of_type(cit->rest, add) &&
++number_of_adds;
if (is_ex_exactly_of_type(last_expanded, add)) {
const add & add1 = ex_to<add>(last_expanded);
++number_of_adds;
if (is_ex_exactly_of_type(last_expanded, add)) {
const add & add1 = ex_to<add>(last_expanded);
- for (int i2=0; i2<n2; ++i2) {
- distrseq.push_back(add1.op(i1) * add2.op(i2));
- }
+ // cache the first operand (for efficiency):
+ const ex op1 = add1.op(i1);
+ for (int i2=0; i2<n2; ++i2)
+ distrseq.push_back(op1 * add2.op(i2));
}
last_expanded = (new add(distrseq))->
setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
}
last_expanded = (new add(distrseq))->
setflag(status_flags::dynallocated | (options == 0 ? status_flags::expanded : 0));
* pointer, if sequence is unchanged. */
epvector * mul::expandchildren(unsigned options) const
{
* pointer, if sequence is unchanged. */
epvector * mul::expandchildren(unsigned options) const
{