X-Git-Url: https://ginac.de/ginac.git//ginac.git?a=blobdiff_plain;f=ginac%2Fmul.cpp;h=02029c54791df100aba6d89f8655334b85324168;hb=19d82770007e4d565ce4d07e3e7a02a1809de4eb;hp=ad7aa13e3d5e5568241398f18ab55788241e94ad;hpb=8397b7a8f4d9a8e6db0025813f125ee365b15e6a;p=ginac.git diff --git a/ginac/mul.cpp b/ginac/mul.cpp index ad7aa13e..02029c54 100644 --- a/ginac/mul.cpp +++ b/ginac/mul.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's products of expressions. */ /* - * GiNaC Copyright (C) 1999-2000 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2001 Johannes Gutenberg University Mainz, Germany * * 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 @@ -48,28 +48,6 @@ mul::mul() tinfo_key = TINFO_mul; } -mul::~mul() -{ - debugmsg("mul destructor",LOGLEVEL_DESTRUCT); - destroy(false); -} - -mul::mul(const mul & other) -{ - debugmsg("mul copy constructor",LOGLEVEL_CONSTRUCT); - copy(other); -} - -const mul & mul::operator=(const mul & other) -{ - debugmsg("mul operator=",LOGLEVEL_ASSIGNMENT); - if (this != &other) { - destroy(true); - copy(other); - } - return *this; -} - // protected void mul::copy(const mul & other) @@ -177,12 +155,6 @@ void mul::archive(archive_node &n) const // public -basic * mul::duplicate() const -{ - debugmsg("mul duplicate",LOGLEVEL_ASSIGNMENT); - return new mul(*this); -} - void mul::print(std::ostream & os, unsigned upper_precedence) const { debugmsg("mul print",LOGLEVEL_PRINT); @@ -659,74 +631,64 @@ ex mul::expand(unsigned options) const exvector sub_expanded_seq; intvector positions_of_adds; - intvector number_of_add_operands; epvector * expanded_seqp = expandchildren(options); const epvector & expanded_seq = expanded_seqp==0 ? seq : *expanded_seqp; - positions_of_adds.resize(expanded_seq.size()); - number_of_add_operands.resize(expanded_seq.size()); - int number_of_adds = 0; - int number_of_expanded_terms = 1; - - unsigned current_position = 0; + epvector non_adds; + non_adds.reserve(expanded_seq.size()); + epvector::const_iterator cit = expanded_seq.begin(); epvector::const_iterator last = expanded_seq.end(); - for (epvector::const_iterator cit = expanded_seq.begin(); cit!=last; ++cit) { + ex last_expanded=_ex1(); + while (cit!=last) { if (is_ex_exactly_of_type((*cit).rest,add) && ((*cit).coeff.is_equal(_ex1()))) { - positions_of_adds[number_of_adds] = current_position; - const add & expanded_addref = ex_to_add((*cit).rest); - unsigned addref_nops = expanded_addref.nops(); - number_of_add_operands[number_of_adds] = addref_nops; - number_of_expanded_terms *= addref_nops; ++number_of_adds; + if (is_ex_exactly_of_type(last_expanded,add)) { + // expand adds + const add & add1 = ex_to_add(last_expanded); + const add & add2 = ex_to_add((*cit).rest); + int n1 = add1.nops(); + int n2 = add2.nops(); + exvector distrseq; + distrseq.reserve(n1*n2); + for (int i1=0; i1setflag(status_flags::dynallocated | status_flags::expanded); + } else { + non_adds.push_back(split_ex_to_pair(last_expanded)); + last_expanded = (*cit).rest; + } + } else { + non_adds.push_back(*cit); } - ++current_position; - } - - if (number_of_adds==0) { - if (expanded_seqp==0) - return this->setflag(status_flags::expanded); - else - return ((new mul(expanded_seqp,overall_coeff))-> - setflag(status_flags::dynallocated | status_flags::expanded)); + ++cit; } - - exvector distrseq; - distrseq.reserve(number_of_expanded_terms); - - intvector k; - k.resize(number_of_adds, 0); - - for (;;) { - epvector term; - term = expanded_seq; - for (int l=0; l - setflag(status_flags::dynallocated | status_flags::expanded)); - - // increment k[] - int l = number_of_adds-1; - while ((l>=0) && ((++k[l])>=number_of_add_operands[l])) { - k[l] = 0; - --l; + + if (is_ex_exactly_of_type(last_expanded,add)) { + add const & finaladd = ex_to_add(last_expanded); + exvector distrseq; + int n = finaladd.nops(); + distrseq.reserve(n); + for (int i=0; isetflag(status_flags::dynallocated | status_flags::expanded)); } - if (l < 0) break; + return ((new add(distrseq))-> + setflag(status_flags::dynallocated | status_flags::expanded)); } - - if (expanded_seqp!=0) - delete expanded_seqp; - - return (new add(distrseq))->setflag(status_flags::dynallocated | - status_flags::expanded); + non_adds.push_back(split_ex_to_pair(last_expanded)); + return (new mul(non_adds,overall_coeff))-> + setflag(status_flags::dynallocated | status_flags::expanded); } + ////////// // new virtual functions which can be overridden by derived classes ////////// @@ -780,14 +742,6 @@ epvector * mul::expandchildren(unsigned options) const unsigned mul::precedence = 50; - -////////// -// global constants -////////// - -const mul some_mul; -const std::type_info & typeid_mul = typeid(some_mul); - #ifndef NO_NAMESPACE_GINAC } // namespace GiNaC #endif // ndef NO_NAMESPACE_GINAC