X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fmul.cpp;h=6f99c515062ff86c64a253ae9ce80adf512680bb;hp=2c8456510a44d35201f5659dec50f27f32206e02;hb=d54e497297f4687c385ff8fbc91296365887c7c0;hpb=5ef801553eb39aed7bd2df9dd1aff9d752c3ea9d diff --git a/ginac/mul.cpp b/ginac/mul.cpp index 2c845651..6f99c515 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -36,7 +36,13 @@ namespace GiNaC { -GINAC_IMPLEMENT_REGISTERED_CLASS(mul, expairseq) +GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mul, expairseq, + print_func(&mul::do_print). + print_func(&mul::do_print_latex). + print_func(&mul::do_print_csrc). + print_func(&inherited::do_print_tree). + print_func(&mul::do_print_python_repr)) + ////////// // default constructor @@ -85,13 +91,12 @@ mul::mul(const epvector & v, const ex & oc) GINAC_ASSERT(is_canonical()); } -mul::mul(epvector * vp, const ex & oc) +mul::mul(std::auto_ptr vp, const ex & oc) { tinfo_key = TINFO_mul; GINAC_ASSERT(vp!=0); overall_coeff = oc; construct_from_epvector(*vp); - delete vp; GINAC_ASSERT(is_canonical()); } @@ -118,159 +123,154 @@ DEFAULT_ARCHIVING(mul) // functions overriding virtual functions from base classes ////////// -// public -void mul::print(const print_context & c, unsigned level) const +void mul::print_overall_coeff(const print_context & c, const char *mul_sym) const { - if (is_a(c)) { + const numeric &coeff = ex_to(overall_coeff); + if (coeff.csgn() == -1) + c.s << '-'; + if (!coeff.is_equal(_num1) && + !coeff.is_equal(_num_1)) { + if (coeff.is_rational()) { + if (coeff.is_negative()) + (-coeff).print(c); + else + coeff.print(c); + } else { + if (coeff.csgn() == -1) + (-coeff).print(c, precedence()); + else + coeff.print(c, precedence()); + } + c.s << mul_sym; + } +} - inherited::print(c, level); +void mul::do_print(const print_context & c, unsigned level) const +{ + if (precedence() <= level) + c.s << '('; - } else if (is_a(c)) { + print_overall_coeff(c, "*"); - if (precedence() <= level) - c.s << "("; + epvector::const_iterator it = seq.begin(), itend = seq.end(); + bool first = true; + while (it != itend) { + if (!first) + c.s << '*'; + else + first = false; + recombine_pair_to_ex(*it).print(c, precedence()); + ++it; + } - if (!overall_coeff.is_equal(_ex1)) { - overall_coeff.print(c, precedence()); - c.s << "*"; - } + if (precedence() <= level) + c.s << ')'; +} - // Print arguments, separated by "*" or "/" - epvector::const_iterator it = seq.begin(), itend = seq.end(); - while (it != itend) { - - // If the first argument is a negative integer power, it gets printed as "1.0/" - bool needclosingparenthesis = false; - if (it == seq.begin() && it->coeff.info(info_flags::negint)) { - if (is_a(c)) { - c.s << "recip("; - needclosingparenthesis = true; - } else - c.s << "1.0/"; - } +void mul::do_print_latex(const print_latex & c, unsigned level) const +{ + if (precedence() <= level) + c.s << "{("; - // If the exponent is 1 or -1, it is left out - if (it->coeff.is_equal(_ex1) || it->coeff.is_equal(_ex_1)) - it->rest.print(c, precedence()); - else if (it->coeff.info(info_flags::negint)) - // Outer parens around ex needed for broken GCC parser: - (ex(power(it->rest, -ex_to(it->coeff)))).print(c, level); - else - // Outer parens around ex needed for broken GCC parser: - (ex(power(it->rest, ex_to(it->coeff)))).print(c, level); - - if (needclosingparenthesis) - c.s << ")"; - - // Separator is "/" for negative integer powers, "*" otherwise - ++it; - if (it != itend) { - if (it->coeff.info(info_flags::negint)) - c.s << "/"; - else - c.s << "*"; - } - } + print_overall_coeff(c, " "); - if (precedence() <= level) - c.s << ")"; + // Separate factors into those with negative numeric exponent + // and all others + epvector::const_iterator it = seq.begin(), itend = seq.end(); + exvector neg_powers, others; + while (it != itend) { + GINAC_ASSERT(is_exactly_a(it->coeff)); + if (ex_to(it->coeff).is_negative()) + neg_powers.push_back(recombine_pair_to_ex(expair(it->rest, -(it->coeff)))); + else + others.push_back(recombine_pair_to_ex(*it)); + ++it; + } - } else if (is_a(c)) { - c.s << class_name() << '('; - op(0).print(c); - for (size_t i=1; i(c)) - c.s << "{("; - else - c.s << "("; - } + // Factors with negative exponent are printed as a fraction + c.s << "\\frac{"; + mul(others).eval().print(c); + c.s << "}{"; + mul(neg_powers).eval().print(c); + c.s << "}"; - // First print the overall numeric coefficient - const numeric &coeff = ex_to(overall_coeff); - if (coeff.csgn() == -1) - c.s << '-'; - if (!coeff.is_equal(_num1) && - !coeff.is_equal(_num_1)) { - if (coeff.is_rational()) { - if (coeff.is_negative()) - (-coeff).print(c); - else - coeff.print(c); - } else { - if (coeff.csgn() == -1) - (-coeff).print(c, precedence()); - else - coeff.print(c, precedence()); - } - if (is_a(c)) - c.s << ' '; - else - c.s << '*'; - } + } else { - // Then proceed with the remaining factors - epvector::const_iterator it = seq.begin(), itend = seq.end(); - if (is_a(c)) { - - // Separate factors into those with negative numeric exponent - // and all others - exvector neg_powers, others; - while (it != itend) { - GINAC_ASSERT(is_exactly_a(it->coeff)); - if (ex_to(it->coeff).is_negative()) - neg_powers.push_back(recombine_pair_to_ex(expair(it->rest, -(it->coeff)))); - else - others.push_back(recombine_pair_to_ex(*it)); - ++it; - } + // All other factors are printed in the ordinary way + exvector::const_iterator vit = others.begin(), vitend = others.end(); + while (vit != vitend) { + c.s << ' '; + vit->print(c, precedence()); + ++vit; + } + } - if (!neg_powers.empty()) { + if (precedence() <= level) + c.s << ")}"; +} - // Factors with negative exponent are printed as a fraction - c.s << "\\frac{"; - mul(others).eval().print(c); - c.s << "}{"; - mul(neg_powers).eval().print(c); - c.s << "}"; +void mul::do_print_csrc(const print_csrc & c, unsigned level) const +{ + if (precedence() <= level) + c.s << "("; - } else { + if (!overall_coeff.is_equal(_ex1)) { + overall_coeff.print(c, precedence()); + c.s << "*"; + } - // All other factors are printed in the ordinary way - exvector::const_iterator vit = others.begin(), vitend = others.end(); - while (vit != vitend) { - c.s << ' '; - vit->print(c, precedence()); - ++vit; - } - } + // Print arguments, separated by "*" or "/" + epvector::const_iterator it = seq.begin(), itend = seq.end(); + while (it != itend) { + + // If the first argument is a negative integer power, it gets printed as "1.0/" + bool needclosingparenthesis = false; + if (it == seq.begin() && it->coeff.info(info_flags::negint)) { + if (is_a(c)) { + c.s << "recip("; + needclosingparenthesis = true; + } else + c.s << "1.0/"; + } - } else { + // If the exponent is 1 or -1, it is left out + if (it->coeff.is_equal(_ex1) || it->coeff.is_equal(_ex_1)) + it->rest.print(c, precedence()); + else if (it->coeff.info(info_flags::negint)) + // Outer parens around ex needed for broken GCC parser: + (ex(power(it->rest, -ex_to(it->coeff)))).print(c, level); + else + // Outer parens around ex needed for broken GCC parser: + (ex(power(it->rest, ex_to(it->coeff)))).print(c, level); - bool first = true; - while (it != itend) { - if (!first) - c.s << '*'; - else - first = false; - recombine_pair_to_ex(*it).print(c, precedence()); - ++it; - } - } + if (needclosingparenthesis) + c.s << ")"; - if (precedence() <= level) { - if (is_a(c)) - c.s << ")}"; + // Separator is "/" for negative integer powers, "*" otherwise + ++it; + if (it != itend) { + if (it->coeff.info(info_flags::negint)) + c.s << "/"; else - c.s << ")"; + c.s << "*"; } } + + if (precedence() <= level) + c.s << ")"; +} + +void mul::do_print_python_repr(const print_python_repr & c, unsigned level) const +{ + c.s << class_name() << '('; + op(0).print(c); + for (size_t i=1; i evaled_seqp = evalchildren(level); + if (evaled_seqp.get()) { // do more evaluation later - return (new mul(evaled_seqp,overall_coeff))-> + return (new mul(evaled_seqp, overall_coeff))-> setflag(status_flags::dynallocated); } @@ -424,7 +424,7 @@ ex mul::eval(int level) const ex_to((*seq.begin()).coeff).is_equal(_num1)) { // *(+(x,y,...);c) -> +(*(x,c),*(y,c),...) (c numeric(), no powers of +()) const add & addref = ex_to((*seq.begin()).rest); - epvector *distrseq = new epvector(); + std::auto_ptr distrseq(new epvector); distrseq->reserve(addref.seq.size()); epvector::const_iterator i = addref.seq.begin(), end = addref.seq.end(); while (i != end) { @@ -447,7 +447,7 @@ ex mul::evalf(int level) const if (level==-max_recursion_level) throw(std::runtime_error("max recursion level reached")); - epvector *s = new epvector(); + std::auto_ptr s(new epvector); s->reserve(seq.size()); --level; @@ -470,7 +470,7 @@ ex mul::evalm() const // Evaluate children first, look whether there are any matrices at all // (there can be either no matrices or one matrix; if there were more // than one matrix, it would be a non-commutative product) - epvector *s = new epvector; + std::auto_ptr s(new epvector); s->reserve(seq.size()); bool have_matrix = false; @@ -598,7 +598,7 @@ ex mul::algebraic_subs_mul(const exmap & m, unsigned options) const subsresult[j] = op(j); else { foundfirstsubsedfactor = true; - subsresult[j] = op(j) * power(it->second.subs(ex(repls), subs_options::subs_no_pattern) / it->first.subs(ex(repls), subs_options::subs_no_pattern), nummatches); + subsresult[j] = op(j) * power(it->second.subs(ex(repls), subs_options::no_pattern) / it->first.subs(ex(repls), subs_options::no_pattern), nummatches); } subsed[j] = true; } @@ -612,7 +612,7 @@ ex mul::algebraic_subs_mul(const exmap & m, unsigned options) const for (size_t j=0; jnops(); j++) { if (!subsed[j] && tryfactsubs(op(j), it->first, nummatches, repls)) { subsed[j] = true; - subsresult[j] = op(j) * power(it->second.subs(ex(repls), subs_options::subs_no_pattern) / it->first.subs(ex(repls), subs_options::subs_no_pattern), nummatches); + subsresult[j] = op(j) * power(it->second.subs(ex(repls), subs_options::no_pattern) / it->first.subs(ex(repls), subs_options::no_pattern), nummatches); } } } @@ -626,7 +626,7 @@ ex mul::algebraic_subs_mul(const exmap & m, unsigned options) const } } if (!subsfound) - return subs_one_level(m, options | subs_options::subs_algebraic); + return subs_one_level(m, options | subs_options::algebraic); exvector ev; ev.reserve(nops()); for (size_t i=0; isetflag(status_flags::dynallocated); } -ex mul::thisexpairseq(epvector * vp, const ex & oc) const +ex mul::thisexpairseq(std::auto_ptr vp, const ex & oc) const { return (new mul(vp, oc))->setflag(status_flags::dynallocated); } @@ -827,8 +827,8 @@ bool mul::can_make_flat(const expair & p) const ex mul::expand(unsigned options) const { // First, expand the children - epvector * expanded_seqp = expandchildren(options); - const epvector & expanded_seq = (expanded_seqp == NULL) ? seq : *expanded_seqp; + std::auto_ptr expanded_seqp = expandchildren(options); + const epvector & expanded_seq = (expanded_seqp.get() ? *expanded_seqp : seq); // 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 @@ -905,8 +905,6 @@ ex mul::expand(unsigned options) const } ++cit; } - if (expanded_seqp) - delete expanded_seqp; // Now the only remaining thing to do is to multiply the factors which // were not sums into the "last_expanded" sum @@ -948,7 +946,7 @@ ex mul::expand(unsigned options) const * @see mul::expand() * @return pointer to epvector containing expanded representation or zero * pointer, if sequence is unchanged. */ -epvector * mul::expandchildren(unsigned options) const +std::auto_ptr mul::expandchildren(unsigned options) const { const epvector::const_iterator last = seq.end(); epvector::const_iterator cit = seq.begin(); @@ -958,7 +956,7 @@ epvector * mul::expandchildren(unsigned options) const if (!are_ex_trivially_equal(factor,expanded_factor)) { // something changed, copy seq, eval and return it - epvector *s = new epvector; + std::auto_ptr s(new epvector); s->reserve(seq.size()); // copy parts of seq which are known not to have changed @@ -967,9 +965,11 @@ epvector * mul::expandchildren(unsigned options) const s->push_back(*cit2); ++cit2; } + // copy first changed element s->push_back(split_ex_to_pair(expanded_factor)); ++cit2; + // copy rest while (cit2!=last) { s->push_back(split_ex_to_pair(recombine_pair_to_ex(*cit2).expand(options))); @@ -980,7 +980,7 @@ epvector * mul::expandchildren(unsigned options) const ++cit; } - return 0; // nothing has changed + return std::auto_ptr(0); // nothing has changed } } // namespace GiNaC