X-Git-Url: https://www.ginac.de/ginac.git//ginac.git?p=ginac.git;a=blobdiff_plain;f=ginac%2Fbasic.cpp;h=a3de04aab9cd306eda820e8d7b50dadc492f3164;hp=2dd853d9f76f09d05842406919cce0a90d97ba0f;hb=7d870583a6bf21a2ffb7b6f051b702064623892e;hpb=695f6ae955ec530cded8f21efd5569df39447f76 diff --git a/ginac/basic.cpp b/ginac/basic.cpp index 2dd853d9..a3de04aa 100644 --- a/ginac/basic.cpp +++ b/ginac/basic.cpp @@ -3,7 +3,7 @@ * Implementation of GiNaC's ABC. */ /* - * GiNaC Copyright (C) 1999-2005 Johannes Gutenberg University Mainz, Germany + * GiNaC Copyright (C) 1999-2008 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 @@ -17,7 +17,7 @@ * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ #include @@ -30,6 +30,7 @@ #include "ex.h" #include "numeric.h" #include "power.h" +#include "add.h" #include "symbol.h" #include "lst.h" #include "ncmul.h" @@ -38,6 +39,7 @@ #include "wildcard.h" #include "archive.h" #include "utils.h" +#include "inifcns.h" namespace GiNaC { @@ -286,13 +288,13 @@ ex & basic::operator[](size_t i) * the pattern itself or one of the children 'has' it. As a consequence * (according to the definition of children) given e=x+y+z, e.has(x) is true * but e.has(x+y) is false. */ -bool basic::has(const ex & pattern) const +bool basic::has(const ex & pattern, unsigned options) const { lst repl_lst; if (match(pattern, repl_lst)) return true; for (size_t i=0; i(var)); +} + /** Return degree of highest power in object s. */ int basic::degree(const ex & s) const { @@ -362,56 +370,32 @@ ex basic::collect(const ex & s, bool distributed) const else if (distributed) { - // Get lower/upper degree of all symbols in list - size_t num = s.nops(); - struct sym_info { - ex sym; - int ldeg, deg; - int cnt; // current degree, 'counter' - ex coeff; // coefficient for degree 'cnt' - }; - sym_info *si = new sym_info[num]; - ex c = *this; - for (size_t i=0; ildegree(si[i].sym); - si[i].deg = this->degree(si[i].sym); - c = si[i].coeff = c.coeff(si[i].sym, si[i].cnt); - } - - while (true) { - - // Calculate coeff*x1^c1*...*xn^cn - ex y = _ex1; - for (size_t i=0; iexpand(); + if (! is_a(x)) + return x; + const lst& l(ex_to(s)); + + exmap cmap; + cmap[_ex1] = _ex0; + for (const_iterator xi=x.begin(); xi!=x.end(); ++xi) { + ex key = _ex1; + ex pre_coeff = *xi; + for (lst::const_iterator li=l.begin(); li!=l.end(); ++li) { + int cexp = pre_coeff.degree(*li); + pre_coeff = pre_coeff.coeff(*li, cexp); + key *= pow(*li, cexp); } + exmap::iterator ci = cmap.find(key); + if (ci != cmap.end()) + ci->second += pre_coeff; + else + cmap.insert(exmap::value_type(key, pre_coeff)); } -done: delete[] si; + exvector resv; + for (exmap::const_iterator mi=cmap.begin(); mi != cmap.end(); ++mi) + resv.push_back((mi->first)*(mi->second)); + return (new add(resv))->setflag(status_flags::dynallocated); } else { @@ -705,6 +689,16 @@ ex basic::conjugate() const return *this; } +ex basic::real_part() const +{ + return real_part_function(*this).hold(); +} + +ex basic::imag_part() const +{ + return imag_part_function(*this).hold(); +} + ex basic::eval_ncmul(const exvector & v) const { return hold_ncmul(v); @@ -775,9 +769,9 @@ unsigned basic::return_type() const return return_types::commutative; } -unsigned basic::return_type_tinfo() const +tinfo_t basic::return_type_tinfo() const { - return tinfo(); + return tinfo_key; } /** Compute the hash value of an object and if it makes sense to store it in @@ -788,7 +782,7 @@ unsigned basic::return_type_tinfo() const * would all end up with the same hashvalue. */ unsigned basic::calchash() const { - unsigned v = golden_ratio_hash(tinfo()); + unsigned v = golden_ratio_hash((p_int)tinfo()); for (size_t i=0; iop(i).gethash(); @@ -845,8 +839,8 @@ int basic::compare(const basic & other) const compare_statistics.compare_same_hashvalue++; #endif - const unsigned typeid_this = tinfo(); - const unsigned typeid_other = other.tinfo(); + const tinfo_t typeid_this = tinfo(); + const tinfo_t typeid_other = other.tinfo(); if (typeid_this==typeid_other) { GINAC_ASSERT(typeid(*this)==typeid(other)); // int cmpval = compare_same_type(other);