MultipleDeriv MultipleDeriv::product(const MultipleDeriv& other) const { MultipleDeriv rtn; for (MultipleDeriv::const_iterator i=this->begin(); i!=this->end(); i++) { rtn.put(*i); } for (MultipleDeriv::const_iterator i=other.begin(); i!=other.end(); i++) { rtn.put(*i); } return rtn; }
void SparsitySuperset::addDeriv(const Deriv& d, const DerivState& state) { MultipleDeriv md; md.put(d); addDeriv(md, state); }
Set<MultipleDeriv> applyTx(const Set<MultipleDeriv>& s, const MultiIndex& x) { Set<MultipleDeriv> rtn; for (Set<MultipleDeriv>::const_iterator i=s.begin(); i!=s.end(); i++) { const MultipleDeriv& md = *i; for (MultipleDeriv::const_iterator j=md.begin(); j!=md.end(); j++) { const Deriv& d = *j; if (d.isFunctionalDeriv()) { const MultiIndex& mi = d.opOnFunc().mi(); MultiIndex miNew = mi+x; if (miNew.isValid()) { Deriv dNew = d.derivWrtMultiIndex(miNew); MultipleDeriv mdNew = md; mdNew.erase(mdNew.find(d)); mdNew.put(dNew); rtn.put(mdNew); } } } } return rtn; }
void MultipleDeriv ::productRulePermutations(ProductRulePerms& perms) const { int N = order(); if (N==0) { MultipleDeriv md0; DerivPair p(md0, md0); perms.put(p, 1); return; } int p2 = pow2(N); for (int i=0; i<p2; i++) { MultipleDeriv left; MultipleDeriv right; Array<int> bits = bitsOfAnInteger(i, N); int j=0; MultipleDeriv::const_iterator iter; for (iter=this->begin(); iter != this->end(); iter++, j++) { if (bits[j]==true) { left.put(*iter); } else { right.put(*iter); } } DerivPair p(left, right); if (!perms.containsKey(p)) { perms.put(p, 1); } else { int count = perms.get(p); perms.put(p, count+1); } } }
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; }
FunctionalPolynomial::FunctionalPolynomial(const RCP<ScalarExpr>& expr) : funcs_(), funcMultiIndices_(), coeffs_(), keys_() { TEUCHOS_TEST_FOR_EXCEPTION(!isConvertibleToPoly(expr.get()), std::logic_error, "FunctionalPolynomial ctor called with an argument that " "cannot be converted to a polynomial"); int funcID; MultiIndex mi; Deriv deriv; const SymbolicFuncElement* s = dynamic_cast<const SymbolicFuncElement*>(expr.get()); if (s != 0) { mi = MultiIndex(); deriv = funcDeriv(s); } const DerivOfSymbFunc* d = dynamic_cast<const DerivOfSymbFunc*>(expr.get()); if (d != 0) { deriv = d->representMeAsFunctionalDeriv(); } MultipleDeriv mu; mu.put(deriv); if (d != 0 || s != 0) { funcs_.put(funcID, expr); Set<MultiIndex> miSet; miSet.put(mi); funcMultiIndices_.put(funcID, miSet); Expr coeff = 1.0; RCP<ScalarExpr> cPtr = rcp_dynamic_cast<ScalarExpr>(coeff.ptr()); coeffs_.resize(2); keys_.resize(2); coeffs_[1].put(mu, cPtr); keys_[1].put(mu); } else { TEUCHOS_TEST_FOR_EXCEPTION(true, std::logic_error, "impossible case in FunctionalPolynomial ctor"); } }
Set<MultipleDeriv> DiffOpEvaluator ::increasedDerivs(const MultipleDeriv& mu, const Set<MultipleDeriv>& W1, int verb) const { Tabs tabs; SUNDANCE_MSG3(verb, tabs << "computing increased derivs"); Set<MultipleDeriv> rtn; for (Set<MultipleDeriv>::const_iterator i=W1.begin(); i!=W1.end(); i++) { MultipleDeriv md = *i; TEUCHOS_TEST_FOR_EXCEPT(md.order() != 1); Deriv lambda = *(md.begin()); MultipleDeriv lambdaMu = mu; lambdaMu.put(lambda); rtn.put(lambdaMu); } SUNDANCE_MSG3(verb, tabs << "increased derivs = " << rtn); return rtn; }
Set<MultipleDeriv> DiffOpEvaluator ::backedDerivs(const MultipleDeriv& mu, const Set<MultipleDeriv>& W1, int verb) const { Tabs tabs; SUNDANCE_MSG3(verb, tabs << "computing backed-out derivs for mu= " << mu << ", W1=" << W1); Set<MultipleDeriv> rtn; if (mu.order() != 0) { const MultiIndex& alpha = expr()->mi(); for (Set<MultipleDeriv>::const_iterator i=W1.begin(); i!=W1.end(); i++) { const MultipleDeriv& md = *i; TEUCHOS_TEST_FOR_EXCEPT(md.order() != 1); Deriv lambda = *(md.begin()); if (lambda.isCoordDeriv()) continue; TEUCHOS_TEST_FOR_EXCEPT(!lambda.isFunctionalDeriv()); FunctionIdentifier lambda_fid = lambda.fid(); const MultiIndex& lambda_mi = lambda.opOnFunc().mi(); for (MultipleDeriv::const_iterator j=mu.begin(); j!=mu.end(); j++) { const Deriv& d = *j; if (d.isCoordDeriv()) continue; FunctionIdentifier d_fid = d.fid(); const MultiIndex& d_mi = d.opOnFunc().mi(); if (d_fid != lambda_fid) continue; if (!(alpha + lambda_mi == d_mi)) continue; MultipleDeriv z = mu.factorOutDeriv(d); z.put(lambda); rtn.put(z); } } } SUNDANCE_MSG3(verb, tabs << "backed-out derivs = " << rtn); return rtn; }
void FunctionalPolynomial ::stepRecurrence(int level, const Map<MultipleDeriv, std::string>& sPrev, Map<MultipleDeriv, std::string>& sCurr) const { Set<MultipleDeriv> allKeys; Set<MultipleDeriv> inducedKeys; Set<MultipleDeriv> prevKeys; for (Map<MultipleDeriv, std::string>::const_iterator i = sPrev.begin(); i != sPrev.end(); i++) { inducedKeys.put(successorTerm(i->first)); } for (Map<MultipleDeriv, std::string>::const_iterator i = sPrev.begin(); i != sPrev.end(); i++) { prevKeys.put(i->first); } Out::os() << "keys from prev level are " << prevKeys << std::endl; Out::os() << "induced keys are " << inducedKeys << std::endl; Out::os() << "natural keys are " << keys_[level] << std::endl; allKeys.merge(inducedKeys); allKeys.merge(keys_[level]); Out::os() << "keys active at this level are " << allKeys << std::endl; for (Set<MultipleDeriv>::const_iterator i = allKeys.begin(); i != allKeys.end(); i++) { const MultipleDeriv& key = *i; Out::os() << "working on key " << key << std::endl; std::string str; if (coeffs_[level].containsKey(key)) { str = coeffs_[level].get(key)->toString(); } Set<Deriv> funcs = findFuncsForSummation(prevKeys, key); Out::os() << "funcs to sum are " << funcs << std::endl; for (Set<Deriv>::const_iterator j = funcs.begin(); j != funcs.end(); j++) { MultipleDeriv prevKey = key; Out::os() << "prev key = " << prevKey << std::endl; Out::os() << "func = " << *j << std::endl; // if (key.size() > 0 && key.upper_bound(*j) == key.end()) // { // Out::os() << "skipping" << std::endl; // continue; // } prevKey.put(*j); TEUCHOS_TEST_FOR_EXCEPTION(!sPrev.containsKey(prevKey), std::logic_error, "inconsisent key lookup"); const std::string& prevStr = sPrev.get(prevKey); std::string funcStr = (*j).toString(); if (str.length() > 0) str += " + "; str += funcStr + "*(" + prevStr + ")"; } if (str.length() > 0) sCurr.put(key, str); } }
MultipleDeriv makeMultiDeriv(const Deriv& d) { MultipleDeriv rtn; rtn.put(d); return rtn; }
EFDEEvaluator::EFDEEvaluator( const ExplicitFunctionalDerivativeElement* expr, const EvalContext& context ) : UnaryEvaluator<ExplicitFunctionalDerivativeElement>(expr, context), constValIndexToArgIndexMap_(), varValIndexToArgIndexMap_() { Tabs tabs; SUNDANCE_VERB_LOW(tabs << "initializing EFDE evaluator for " << expr->toString()); SUNDANCE_VERB_MEDIUM(tabs << "return sparsity " << std::endl << *(this->sparsity)()); /* * This evaluator requires no calculations. All that is done is to * map derivatives (md, fd) in the argument's result arrays to * derivatives (md) in this expression's result arrays. */ int vecResultIndex = 0; int constResultIndex = 0; const Deriv& fd = expr->fd(); for (int i=0; i<this->sparsity()->numDerivs(); i++) { const MultipleDeriv& d = this->sparsity()->deriv(i); const DerivState& myState = this->sparsity()->state(i); if (myState==ConstantDeriv) { Tabs tab2; SUNDANCE_VERB_HIGH(tab2 << "deriv is constant, will be stored at index " << constResultIndex << " in the const result array"); addConstantIndex(i, constResultIndex++); } else { Tabs tab2; SUNDANCE_VERB_HIGH(tab2 << "deriv is variable, will be stored at index " << vecResultIndex << " in the var result array"); addVectorIndex(i, vecResultIndex++); } MultipleDeriv dArg = d; dArg.put(fd); int argIndex = argSparsitySuperset()->getIndex(dArg); TEST_FOR_EXCEPTION(argIndex==-1, RuntimeError, "Derivative " << dArg << " expected in argument but not found"); const DerivState& argState = argSparsitySuperset()->state(argIndex); TEST_FOR_EXCEPTION(argState != myState, InternalError, "mismatched states"); if (argState==ConstantDeriv) { int constArgIndex = argEval()->constantIndexMap().get(argIndex); constValIndexToArgIndexMap_.append(constArgIndex); } else { int vectorArgIndex = argEval()->vectorIndexMap().get(argIndex); varValIndexToArgIndexMap_.append(vectorArgIndex); } } SUNDANCE_VERB_HIGH(tabs << " constant index map " << constValIndexToArgIndexMap_ << std::endl << " vector index map " << varValIndexToArgIndexMap_ ); }