Set<Deriv> FunctionalPolynomial ::findFuncsForSummation(const Set<MultipleDeriv>& prevSet, const MultipleDeriv& currentDeriv) const { Set<Deriv> rtn; for (Set<MultipleDeriv>::const_iterator i = prevSet.begin(); i != prevSet.end(); i++) { const MultipleDeriv& mdPrev = *i; TEUCHOS_TEST_FOR_EXCEPTION(currentDeriv.size()+1 != mdPrev.size(), std::logic_error, "deriv orders must differ by 1. Found " "currentDeriv.size()=" << currentDeriv.size() << " while mdPrev.size()=" << mdPrev.size()); /* We are looking for cases where the previous multiple derivative * is equal to the current plus one *greater* element. In such cases, the * set difference will contain exactly one element, and that element * will be greater than or equal to the the upper bound of the current * set */ Set<Deriv> tmp; set_difference(mdPrev.begin(), mdPrev.end(), currentDeriv.begin(), currentDeriv.end(), inserter(tmp, tmp.begin())); if (tmp.size()==1) { const Deriv& d = *(tmp.begin()); if (currentDeriv.upper_bound(d) == currentDeriv.end()) rtn.put(d); } } return rtn; }
void DiffOp::requestMultiIndexAtEvalPoint(const MultiIndex& mi, const MultipleDeriv& u, const EvalContext& context) const { int verb = context.setupVerbosity(); Tabs tab0(0); SUNDANCE_MSG3(verb, tab0 << "DiffOp::requestMultiIndexAtEvalPoint() for=" << toString()); TEUCHOS_TEST_FOR_EXCEPT(u.size() != 1); const Deriv& d = *(u.begin()); if (d.isFunctionalDeriv()) { const SpatialDerivSpecifier& sds = d.opOnFunc(); TEUCHOS_TEST_FOR_EXCEPTION(sds.isDivergence(), std::logic_error, "divergence operators not possible within DiffOp"); TEUCHOS_TEST_FOR_EXCEPTION(sds.isNormal(), std::logic_error, "normal deriv operators not possible within DiffOp"); const MultiIndex& newMi = sds.mi(); const SymbolicFuncElement* sfe = d.symbFuncElem(); TEUCHOS_TEST_FOR_EXCEPT(sfe == 0); const EvaluatableExpr* evalPt = sfe->evalPt(); const ZeroExpr* z = dynamic_cast<const ZeroExpr*>(evalPt); if (z != 0) return; const DiscreteFuncElement* df = dynamic_cast<const DiscreteFuncElement*>(evalPt); df->addMultiIndex(newMi); df->findW(1, context); df->findV(1, context); df->findC(1, context); } }
MultipleDeriv FunctionalPolynomial::successorTerm(const MultipleDeriv& md) const { MultipleDeriv rtn; unsigned int k = 0; for (MultipleDeriv::const_iterator i=md.begin(); i!=md.end(); i++, k++) { if (k < md.size()-1) rtn.put(*i); } return rtn; }
MultipleDeriv MultipleDeriv::factorOutDeriv(const Deriv& x) const { MultipleDeriv rtn = *this; MultipleDeriv::iterator i = rtn.find(x); /* remove a single copy of the given derivative */ if (i != rtn.end()) rtn.erase(i); if (rtn.size() == this->size()) return MultipleDeriv(); return rtn; }
MultipleDeriv MultipleDeriv::factorOutDeriv(const MultipleDeriv& x) const { MultipleDeriv rtn = *this; for (MultipleDeriv::const_iterator i=x.begin(); i!=x.end(); i++) { MultipleDeriv::iterator j = rtn.find(*i); /* remove a single copy of the given derivative */ if (j != rtn.end()) rtn.erase(j); } if (rtn.size() == this->size()) return MultipleDeriv(); return rtn; }
Set<MultipleDeriv> EvaluatableExpr::setDivision(const Set<MultipleDeriv>& a, const Set<MultipleDeriv>& b) const { Set<MultipleDeriv> rtn; for (Set<MultipleDeriv>::const_iterator i=a.begin(); i!=a.end(); i++) { for (Set<MultipleDeriv>::const_iterator j=b.begin(); j!=b.end(); j++) { MultipleDeriv c = i->factorOutDeriv(*j); if (c.size() != 0) rtn.put(c); if (*i == *j) rtn.put(MultipleDeriv()); } } return rtn; }