Sundance::Map<Expr, int> Expr::getSumTree() const { RCP<ScalarExpr> sThis = rcp_dynamic_cast<ScalarExpr>(ptr()); TEUCHOS_TEST_FOR_EXCEPTION(sThis.get()==0, std::logic_error, "etSumTree() not defined for non-scalar expression " << toString()); const SumExpr* s = dynamic_cast<const SumExpr*>(sThis.get()); const UnaryMinus* u = dynamic_cast<const UnaryMinus*>(sThis.get()); if (s != 0) { return s->getSumTree(); } else if (u != 0) { Sundance::Map<Expr, int> rtn; rtn.put(u->arg(), -1); return rtn; } else { Sundance::Map<Expr, int> rtn; rtn.put(*this, 1); return rtn; } }
void SumOfIntegrals::changeSign() { Sundance::Map<RegionQuadCombo, Expr> newMap; for (Sundance::Map<RegionQuadCombo, Expr>::const_iterator i=rqcToExprMap_.begin(); i!=rqcToExprMap_.end(); i++) { Expr e = i->second; newMap.put(i->first, -e); } rqcToExprMap_ = newMap; }
void SumOfIntegrals::multiplyByConstant(const SpatiallyConstantExpr* expr) { double a = expr->value(); Sundance::Map<RegionQuadCombo, Expr> newMap; for (Sundance::Map<RegionQuadCombo, Expr>::const_iterator i=rqcToExprMap_.begin(); i!=rqcToExprMap_.end(); i++) { Expr e = i->second; newMap.put(i->first, a*e); } rqcToExprMap_ = newMap; }
int factorial(const MultipleDeriv& ms) { Sundance::Map<Deriv, int> counts; for (MultipleDeriv::const_iterator i=ms.begin(); i!=ms.end(); i++) { if (counts.containsKey(*i)) counts[*i]++; else counts.put(*i, 1); } int rtn = 1; for (Sundance::Map<Deriv, int>::const_iterator i=counts.begin(); i!=counts.end(); i++) { int f = 1; for (int j=1; j<=i->second; j++) f *= j; rtn *= f; } return rtn; }
bool ReorderSum::doTransform(const RCP<ScalarExpr>& left, const RCP<ScalarExpr>& right, int sign, RCP<ScalarExpr>& rtn) const { TimeMonitor timer(reorderSumTimer()); /* first we check to see whether the terms are already in order. * The left and right trees are already ordered, so that if the * first term on the right is after the last term on the left, the * combination of both is already ordered. In that case, nothing more needs * to be done. */ Expr L = Expr::handle(left); Expr R = Expr::handle(right); Sundance::Map<Expr, int> tree = L.getSumTree(); Sundance::Map<Expr, int>::const_reverse_iterator iL = tree.rbegin(); Expr endOfLeft = iL->first; Sundance::Map<Expr, int> rightTree = R.getSumTree(); Sundance::Map<Expr, int>::const_iterator iR = rightTree.begin(); Expr startOfRight = iR->first; if (endOfLeft.lessThan(startOfRight)) { Tabs tab1; SUNDANCE_VERB_MEDIUM(tab1 << "Terms are already ordered, doing nothing"); return false; } else { Tabs tab1; for (Map<Expr, int>::const_iterator i=rightTree.begin(); i!=rightTree.end(); i++) { int leftCount = 0; if (tree.containsKey(i->first)) { leftCount = tree[i->first]; } int count = leftCount + sign * i->second; tree.put(i->first, count); } SUNDANCE_VERB_MEDIUM(tab1 << "Ordered terms are: " << tree); Expr sum = new ZeroExpr(); /* add up all terms. If no terms are left after cancellations, the result will * be zero. */ for (Map<Expr, int>::const_iterator i=tree.begin(); i!=tree.end(); i++) { const Expr& term = i->first; int count = i->second; if (count==0) continue; if (count==1) sum = sum + term; else if (count==-1) sum = sum - term; else sum = sum + count*term; } rtn = getScalar(sum); return true; } }