* Implementation of GiNaC's products of expressions. */
/*
- * GiNaC Copyright (C) 1999-2007 Johannes Gutenberg University Mainz, Germany
+ * GiNaC Copyright (C) 1999-2009 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
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
-#include <iostream>
-#include <vector>
-#include <stdexcept>
-#include <limits>
-
#include "mul.h"
#include "add.h"
#include "power.h"
#include "symbol.h"
#include "compiler.h"
+#include <iostream>
+#include <limits>
+#include <stdexcept>
+#include <vector>
+
namespace GiNaC {
GINAC_IMPLEMENT_REGISTERED_CLASS_OPT(mul, expairseq,
mul::mul()
{
- tinfo_key = &mul::tinfo_static;
}
//////////
mul::mul(const ex & lh, const ex & rh)
{
- tinfo_key = &mul::tinfo_static;
overall_coeff = _ex1;
construct_from_2_ex(lh,rh);
GINAC_ASSERT(is_canonical());
mul::mul(const exvector & v)
{
- tinfo_key = &mul::tinfo_static;
overall_coeff = _ex1;
construct_from_exvector(v);
GINAC_ASSERT(is_canonical());
mul::mul(const epvector & v)
{
- tinfo_key = &mul::tinfo_static;
overall_coeff = _ex1;
construct_from_epvector(v);
GINAC_ASSERT(is_canonical());
mul::mul(const epvector & v, const ex & oc, bool do_index_renaming)
{
- tinfo_key = &mul::tinfo_static;
overall_coeff = oc;
construct_from_epvector(v, do_index_renaming);
GINAC_ASSERT(is_canonical());
mul::mul(std::auto_ptr<epvector> vp, const ex & oc, bool do_index_renaming)
{
- tinfo_key = &mul::tinfo_static;
GINAC_ASSERT(vp.get()!=0);
overall_coeff = oc;
construct_from_epvector(*vp, do_index_renaming);
mul::mul(const ex & lh, const ex & mh, const ex & rh)
{
- tinfo_key = &mul::tinfo_static;
exvector factors;
factors.reserve(3);
factors.push_back(lh);
// archiving
//////////
-DEFAULT_ARCHIVING(mul)
-
//////////
// functions overriding virtual functions from base classes
//////////
// XXX: What is the best way to check if the polynomial is a primitive?
numeric c = i->rest.integer_content();
- const numeric& lead_coeff =
- ex_to<numeric>(ex_to<add>(i->rest).seq.begin()->coeff).div_dyn(c);
+ const numeric lead_coeff =
+ ex_to<numeric>(ex_to<add>(i->rest).seq.begin()->coeff).div(c);
const bool canonicalizable = lead_coeff.is_integer();
// XXX: The main variable is chosen in a random way, so this code
return inherited::eval_ncmul(v);
}
-bool tryfactsubs(const ex & origfactor, const ex & patternfactor, int & nummatches, lst & repls)
+bool tryfactsubs(const ex & origfactor, const ex & patternfactor, int & nummatches, exmap& repls)
{
ex origbase;
int origexponent;
patternexpsign = 1;
}
- lst saverepls = repls;
+ exmap saverepls = repls;
if (origexponent < patternexponent || origexpsign != patternexpsign || !origbase.match(patternbase,saverepls))
return false;
repls = saverepls;
* that already have been replaced by previous substitutions and matched[i]
* is true for factors that have been matched by the current match.
*/
-bool algebraic_match_mul_with_mul(const mul &e, const ex &pat, lst &repls,
+bool algebraic_match_mul_with_mul(const mul &e, const ex &pat, exmap& repls,
int factor, int &nummatches, const std::vector<bool> &subsed,
std::vector<bool> &matched)
{
- if (factor == pat.nops())
+ if (factor == (int)pat.nops())
return true;
for (size_t i=0; i<e.nops(); ++i) {
if(subsed[i] || matched[i])
continue;
- lst newrepls = repls;
+ exmap newrepls = repls;
int newnummatches = nummatches;
if (tryfactsubs(e.op(i), pat.op(factor), newnummatches, newrepls)) {
matched[i] = true;
if(!(options&has_options::algebraic))
return basic::has(pattern,options);
if(is_a<mul>(pattern)) {
- lst repls;
+ exmap repls;
int nummatches = std::numeric_limits<int>::max();
std::vector<bool> subsed(seq.size(), false);
std::vector<bool> matched(seq.size(), false);
retry1:
int nummatches = std::numeric_limits<int>::max();
std::vector<bool> currsubsed(seq.size(), false);
- lst repls;
+ exmap repls;
if(!algebraic_match_mul_with_mul(*this, it->first, repls, 0, nummatches, subsed, currsubsed))
continue;
if (currsubsed[j])
subsed[j] = true;
ex subsed_pattern
- = it->first.subs(ex(repls), subs_options::no_pattern);
+ = it->first.subs(repls, subs_options::no_pattern);
divide_by *= power(subsed_pattern, nummatches);
ex subsed_result
- = it->second.subs(ex(repls), subs_options::no_pattern);
+ = it->second.subs(repls, subs_options::no_pattern);
multiply_by *= power(subsed_result, nummatches);
goto retry1;
for (size_t j=0; j<this->nops(); j++) {
int nummatches = std::numeric_limits<int>::max();
- lst repls;
+ exmap repls;
if (!subsed[j] && tryfactsubs(op(j), it->first, nummatches, repls)){
subsed[j] = true;
ex subsed_pattern
- = it->first.subs(ex(repls), subs_options::no_pattern);
+ = it->first.subs(repls, subs_options::no_pattern);
divide_by *= power(subsed_pattern, nummatches);
ex subsed_result
- = it->second.subs(ex(repls), subs_options::no_pattern);
+ = it->second.subs(repls, subs_options::no_pattern);
multiply_by *= power(subsed_result, nummatches);
}
}
return all_commutative ? return_types::commutative : return_types::noncommutative;
}
-tinfo_t mul::return_type_tinfo() const
+return_type_t mul::return_type_tinfo() const
{
if (seq.empty())
- return this; // mul without factors: should not happen
+ return make_return_type_t<mul>(); // mul without factors: should not happen
// return type_info of first noncommutative element
epvector::const_iterator i = seq.begin(), end = seq.end();
++i;
}
// no noncommutative element found, should not happen
- return this;
+ return make_return_type_t<mul>();
}
ex mul::thisexpairseq(const epvector & v, const ex & oc, bool do_index_renaming) const
ex mul::expand(unsigned options) const
{
{
- // trivial case: expanding the monomial (~ 30% of all calls)
+ // trivial case: expanding the monomial (~ 30% of all calls)
epvector::const_iterator i = seq.begin(), seq_end = seq.end();
while ((i != seq.end()) && is_a<symbol>(i->rest) && i->coeff.info(info_flags::integer))
++i;
- if (i == seq_end)
- return (new mul(*this))->setflag(status_flags::dynallocated | status_flags::expanded);
+ if (i == seq_end) {
+ setflag(status_flags::expanded);
+ return *this;
+ }
}
// do not rename indices if the object has no indices at all
return std::auto_ptr<epvector>(0); // nothing has changed
}
+GINAC_BIND_UNARCHIVER(mul);
+
} // namespace GiNaC