- debugmsg("mul constructor from ex,ex,ex",LOGLEVEL_CONSTRUCT);
+ debugmsg("mul ctor from ex,ex,ex",LOGLEVEL_CONSTRUCT);
/** Construct object from archive_node. */
mul::mul(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
{
/** Construct object from archive_node. */
mul::mul(const archive_node &n, const lst &sym_lst) : inherited(n, sym_lst)
{
void mul::print(std::ostream & os, unsigned upper_precedence) const
{
debugmsg("mul print",LOGLEVEL_PRINT);
if (precedence<=upper_precedence) os << "(";
void mul::print(std::ostream & os, unsigned upper_precedence) const
{
debugmsg("mul print",LOGLEVEL_PRINT);
if (precedence<=upper_precedence) os << "(";
// first print the overall numeric coefficient:
numeric coeff = ex_to_numeric(overall_coeff);
if (coeff.csgn()==-1) os << '-';
// first print the overall numeric coefficient:
numeric coeff = ex_to_numeric(overall_coeff);
if (coeff.csgn()==-1) os << '-';
if (n==0) {
// product of individual coeffs
// if a non-zero power of s is found, the resulting product will be 0
if (n==0) {
// product of individual coeffs
// if a non-zero power of s is found, the resulting product will be 0
// *(+(x,y,...);c) -> *(+(*(x,c),*(y,c),...)) (c numeric())
// *(x;1) -> x
// *(;c) -> c
// *(+(x,y,...);c) -> *(+(*(x,c),*(y,c),...)) (c numeric())
// *(x;1) -> x
// *(;c) -> c
if (evaled_seqp!=0) {
// do more evaluation later
return (new mul(evaled_seqp,overall_coeff))->
if (evaled_seqp!=0) {
// do more evaluation later
return (new mul(evaled_seqp,overall_coeff))->
- GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul))||
- (!(ex_to_numeric((*cit).coeff).is_integer())));
- GINAC_ASSERT(!((*cit).is_numeric_with_coeff_1()));
- if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric)) {
- printtree(cerr,0);
- }
+ GINAC_ASSERT((!is_ex_exactly_of_type((*cit).rest,mul)) ||
+ (!(ex_to_numeric((*cit).coeff).is_integer())));
+ GINAC_ASSERT(!(cit->is_canonical_numeric()));
+ if (is_ex_exactly_of_type(recombine_pair_to_ex(*cit),numeric))
+ printtree(std::cerr,0);
GINAC_ASSERT(p.rest.is_equal((*cit).rest));
GINAC_ASSERT(p.coeff.is_equal((*cit).coeff));
/* end paranoia */
}
#endif // def DO_GINAC_ASSERT
GINAC_ASSERT(p.rest.is_equal((*cit).rest));
GINAC_ASSERT(p.coeff.is_equal((*cit).coeff));
/* end paranoia */
}
#endif // def DO_GINAC_ASSERT
// *(x;1) -> x
return recombine_pair_to_ex(*(seq.begin()));
} else if ((seq_size==1) &&
is_ex_exactly_of_type((*seq.begin()).rest,add) &&
ex_to_numeric((*seq.begin()).coeff).is_equal(_num1())) {
// *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
// *(x;1) -> x
return recombine_pair_to_ex(*(seq.begin()));
} else if ((seq_size==1) &&
is_ex_exactly_of_type((*seq.begin()).rest,add) &&
ex_to_numeric((*seq.begin()).coeff).is_equal(_num1())) {
// *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +())
epvector distrseq;
distrseq.reserve(addref.seq.size());
for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) {
epvector distrseq;
distrseq.reserve(addref.seq.size());
for (epvector::const_iterator cit=addref.seq.begin(); cit!=addref.seq.end(); ++cit) {
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
exvector subiv=(*cit).rest.get_indices();
iv.reserve(iv.size()+subiv.size());
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
exvector subiv=(*cit).rest.get_indices();
iv.reserve(iv.size()+subiv.size());
// mul without factors: should not happen, but commutes
return return_types::commutative;
}
// mul without factors: should not happen, but commutes
return return_types::commutative;
}
bool all_commutative = 1;
unsigned rt;
epvector::const_iterator cit_noncommutative_element; // point to first found nc element
bool all_commutative = 1;
unsigned rt;
epvector::const_iterator cit_noncommutative_element; // point to first found nc element
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
rt=(*cit).rest.return_type();
if (rt==return_types::noncommutative_composite) return rt; // one ncc -> mul also ncc
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
rt=(*cit).rest.return_type();
if (rt==return_types::noncommutative_composite) return rt; // one ncc -> mul also ncc
// return type_info of first noncommutative element
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
// return type_info of first noncommutative element
for (epvector::const_iterator cit=seq.begin(); cit!=seq.end(); ++cit) {
expair mul::split_ex_to_pair(const ex & e) const
{
if (is_ex_exactly_of_type(e,power)) {
expair mul::split_ex_to_pair(const ex & e) const
{
if (is_ex_exactly_of_type(e,power)) {
- const power & powerref=ex_to_power(e);
- if (is_ex_exactly_of_type(powerref.exponent,numeric)) {
+ const power & powerref = ex_to_power(e);
+ if (is_ex_exactly_of_type(powerref.exponent,numeric))
if (is_ex_exactly_of_type((*it).rest,mul) &&
ex_to_numeric((*it).coeff).is_integer()) {
// combined pair is product with integer power -> expand it
if (is_ex_exactly_of_type((*it).rest,mul) &&
ex_to_numeric((*it).coeff).is_integer()) {
// combined pair is product with integer power -> expand it
return true;
}
if (is_ex_exactly_of_type((*it).rest,numeric)) {
expair ep=split_ex_to_pair(recombine_pair_to_ex(*it));
if (!ep.is_equal(*it)) {
// combined pair is a numeric power which can be simplified
return true;
}
if (is_ex_exactly_of_type((*it).rest,numeric)) {
expair ep=split_ex_to_pair(recombine_pair_to_ex(*it));
if (!ep.is_equal(*it)) {
// combined pair is a numeric power which can be simplified
non_adds.reserve(expanded_seq.size());
epvector::const_iterator cit = expanded_seq.begin();
epvector::const_iterator last = expanded_seq.end();
non_adds.reserve(expanded_seq.size());
epvector::const_iterator cit = expanded_seq.begin();
epvector::const_iterator last = expanded_seq.end();
while (cit!=last) {
if (is_ex_exactly_of_type((*cit).rest,add) &&
((*cit).coeff.is_equal(_ex1()))) {
while (cit!=last) {
if (is_ex_exactly_of_type((*cit).rest,add) &&
((*cit).coeff.is_equal(_ex1()))) {
+
+/** Member-wise expand the expairs representing this sequence. This must be
+ * overridden from expairseq::expandchildren() and done iteratively in order
+ * to allow for early cancallations and thus safe memory.
+ *
+ * @see mul::expand()
+ * @return pointer to epvector containing expanded representation or zero
+ * pointer, if sequence is unchanged. */
if (!are_ex_trivially_equal(factor,expanded_factor)) {
// something changed, copy seq, eval and return it
if (!are_ex_trivially_equal(factor,expanded_factor)) {
// something changed, copy seq, eval and return it