void DiscreteFuncElementEvaluator ::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tabs(0); SUNDANCE_MSG1(mgr.verb(), tabs << "DiscreteFuncElementEvaluator::eval: expr=" << expr()->toString()); vectorResults.resize(mi_.size()); for (int i=0; i<mi_.size(); i++) { Tabs tab2; vectorResults[i] = mgr.popVector(); TEUCHOS_TEST_FOR_EXCEPTION(!vectorResults[i]->isValid(), std::logic_error, "invalid evaluation vector allocated in " "DiscreteFuncElementEvaluator::internalEval()"); SUNDANCE_MSG2(mgr.verb(),tab2<< "setting string rep " << stringReps_[i]); vectorResults[i]->setString(stringReps_[i]); } mgr.evalDiscreteFuncElement(expr(), mi_, vectorResults); mgr.stack().setVecSize(vectorResults[0]->length()); if (mgr.verb() > 1) { Out::os() << tabs << "results " << std::endl; mgr.showResults(Out::os(), sparsity(), vectorResults, constantResults); } SUNDANCE_MSG1(mgr.verb(), tabs << "DiscreteFuncEvaluator::eval() done"); }
void CurveNormEvaluator::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tabs(0); SUNDANCE_MSG2(mgr.verb(), tabs << "CurveNormEvaluator::eval() expr=" << expr()->toString()); if (mgr.verb() > 2) { Out::os() << tabs << "sparsity = " << std::endl << tabs << *(this->sparsity)() << std::endl; } if (this->sparsity()->numDerivs() > 0) { vectorResults.resize(1); vectorResults[0] = mgr.popVector(); SUNDANCE_MSG3(mgr.verb(), tabs << "forwarding to evaluation manager"); mgr.evalCurveNormExpr(expr(), vectorResults[0]); mgr.stack().setVecSize(vectorResults[0]->length()); if (EvalVector::shadowOps()) vectorResults[0]->setString(stringRep_); } if (mgr.verb() > 1) { Out::os() << tabs << "results " << std::endl; mgr.showResults(Out::os(), this->sparsity(), vectorResults, constantResults); } }
void EFDEEvaluator::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { TimeMonitor timer(efdeEvalTimer()); Tabs tabs; SUNDANCE_MSG1(mgr.verb(), tabs << "EFDEEvaluator::eval() expr=" << expr()->toString()); SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " << std::endl << *(this->sparsity)()); constantResults.resize(constValIndexToArgIndexMap_.size()); vectorResults.resize(varValIndexToArgIndexMap_.size()); /* evaluate the argument */ Array<RCP<EvalVector> > argVectorResults; Array<double> argConstantResults; evalOperand(mgr, argConstantResults, argVectorResults); if (mgr.verb() > 2) { Tabs tab1; Out::os() << tab1 << "EFDE operand results" << std::endl; argSparsitySuperset()->print(Out::os(), argVectorResults, argConstantResults); } for (int i=0; i<constantResults.size(); i++) { constantResults[i] = argConstantResults[constValIndexToArgIndexMap_[i]]; } for (int i=0; i<vectorResults.size(); i++) { vectorResults[i] = mgr.popVector(); const RCP<EvalVector>& v = argVectorResults[varValIndexToArgIndexMap_[i]]; vectorResults[i]->setTo_V(v.get()); } if (mgr.verb() > 2) { Tabs tab1; Out::os() << tab1 << "results " << std::endl; this->sparsity()->print(Out::os(), vectorResults, constantResults); } }
void NullEvaluator::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tab; SUNDANCE_MSG1(mgr.verb(), tab << "doing null evaluation... nothing to do"); }
void UnaryMinusEvaluator ::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tab; SUNDANCE_MSG1(mgr.verb(), tab << "UnaryMinusEvaluator::eval() expr=" << expr()->toString()); /* evaluate the argument */ evalOperand(mgr, constantResults, vectorResults); if (mgr.verb() > 2) { Out::os() << tab << "UnaryMinus operand results" << std::endl; argSparsitySuperset()->print(Out::os(), vectorResults, constantResults); } for (int i=0; i<constantResults.size(); i++) { constantResults[i] *= -1; } for (int i=0; i<vectorResults.size(); i++) { vectorResults[i]->multiply_S(-1.0); } if (mgr.verb() > 1) { Out::os() << tab << "UnaryMinus results" << std::endl; sparsity()->print(Out::os(), vectorResults, constantResults); } }
void CoordExprEvaluator::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tabs(0); SUNDANCE_MSG1(mgr.verb(), tabs << "CoordExprEvaluator::eval() expr=" << expr()->toString()); SUNDANCE_MSG2(mgr.verb(), tabs << "sparsity = " << std::endl << *(this->sparsity)()) if (doValue_) { Tabs tab2; SUNDANCE_MSG3(mgr.verb(), tab2 << "computing value"); vectorResults.resize(1); vectorResults[0] = mgr.popVector(); mgr.evalCoordExpr(expr(), vectorResults[0]); mgr.stack().setVecSize(vectorResults[0]->length()); vectorResults[0]->setString(stringRep_); } if (doDeriv_) { Tabs tab2; SUNDANCE_MSG3(mgr.verb(), tab2 << "computing derivative"); constantResults.resize(1); constantResults[0] = 1.0; } if (mgr.verb() > 1) { Tabs tab1; Out::os() << tab1 << "results " << std::endl; mgr.showResults(Out::os(), this->sparsity(), vectorResults, constantResults); } }
void ProductEvaluator ::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tabs(0); SUNDANCE_MSG1(mgr.verb(), tabs << "ProductEvaluator::eval() expr=" << expr()->toString()); /* evaluate the children */ Array<RCP<EvalVector> > leftVectorResults; Array<RCP<EvalVector> > rightVectorResults; Array<double> leftConstantResults; Array<double> rightConstantResults; evalChildren(mgr, leftConstantResults, leftVectorResults, rightConstantResults, rightVectorResults); if (mgr.verb() > 2) { Out::os() << tabs << "left operand results" << std::endl; mgr.showResults(Out::os(), leftSparsity(), leftVectorResults, leftConstantResults); Out::os() << tabs << "right operand results" << std::endl; mgr.showResults(Out::os(), rightSparsity(), rightVectorResults, rightConstantResults); } constantResults.resize(this->sparsity()->numConstantDerivs()); vectorResults.resize(this->sparsity()->numVectorDerivs()); /* Evaluate from high to low differentiation order. This is necessary * so that we can do in-place evaluation of derivatives, overwriting * one of the operands' vectors */ for (int order=maxOrder_; order>=0; order--) { for (int i=0; i<resultIndex_[order].size(); i++) { double constantVal = 0.0; const Array<Array<int> >& ccTerms = ccTerms_[order][i]; for (int j=0; j<ccTerms.size(); j++) { /* add L*R*multiplicity to result */ constantVal += leftConstantResults[ccTerms[j][0]] * rightConstantResults[ccTerms[j][1]] * ccTerms[j][2]; } /* If this derivative is a constant, we're done. */ if (resultIsConstant_[order][i]) { constantResults[resultIndex_[order][i]] = constantVal; continue; } /* For the vector case, the first thing to do is get storage * for the result. If we can reuse one of the operands' results * as workspace, great. If not, we'll need to allocate a new * vector. */ RCP<EvalVector> result; if (hasWorkspace_[order][i]) { int index = workspaceIndex_[order][i]; int coeffIndex = workspaceCoeffIndex_[order][i]; bool coeffIsConstant = workspaceCoeffIsConstant_[order][i]; if (workspaceIsLeft_[order][i]) { result = leftVectorResults[index]; if (coeffIsConstant) { const double& coeff = rightConstantResults[coeffIndex]; if (!isOne(coeff)) result->multiply_S(coeff); } else { const RCP<EvalVector>& coeff = rightVectorResults[coeffIndex]; result->multiply_V(coeff.get()); } } else { result = rightVectorResults[index]; if (coeffIsConstant) { const double& coeff = leftConstantResults[coeffIndex]; if (!isOne(coeff)) result->multiply_S(coeff); } else { const RCP<EvalVector>& coeff = leftVectorResults[coeffIndex]; result->multiply_V(coeff.get()); } } SUNDANCE_MSG5(mgr.verb(), tabs << "workspace = " << result->str()); } else { result = mgr.popVector(); const Array<int>& sv = startingVectors_[order][i]; int multiplicity = sv[2]; switch(startingParities_[order][i]) { case VecVec: if (!isZero(constantVal)) { if (!isOne(multiplicity)) { result->setTo_S_add_SVV(constantVal, multiplicity, leftVectorResults[sv[0]].get(), rightVectorResults[sv[1]].get()); } else { result->setTo_S_add_VV(constantVal, leftVectorResults[sv[0]].get(), rightVectorResults[sv[1]].get()); } } else { if (!isOne(multiplicity)) { result->setTo_SVV(multiplicity, leftVectorResults[sv[0]].get(), rightVectorResults[sv[1]].get()); } else { result->setTo_VV(leftVectorResults[sv[0]].get(), rightVectorResults[sv[1]].get()); } } SUNDANCE_MSG5(mgr.verb(), tabs << "init to v-v prod, m=" << multiplicity << ", left=" << leftVectorResults[sv[0]]->str() << ", right=" << rightVectorResults[sv[1]]->str() << ", result=" << result->str()); break; case VecConst: if (!isZero(constantVal)) { if (!isOne(multiplicity*rightConstantResults[sv[1]])) { result->setTo_S_add_SV(constantVal, multiplicity *rightConstantResults[sv[1]], leftVectorResults[sv[0]].get()); } else { result->setTo_S_add_V(constantVal, leftVectorResults[sv[0]].get()); } } else { if (!isOne(multiplicity*rightConstantResults[sv[1]])) { result->setTo_SV(multiplicity *rightConstantResults[sv[1]], leftVectorResults[sv[0]].get()); } else { result->setTo_V(leftVectorResults[sv[0]].get()); } } SUNDANCE_MSG5(mgr.verb(), tabs << "init to v-c prod, m=" << multiplicity << ", left=" << leftVectorResults[sv[0]]->str() << ", right=" << rightConstantResults[sv[1]] << ", result=" << result->str()); break; case ConstVec: if (!isZero(constantVal)) { if (!isOne(multiplicity*leftConstantResults[sv[0]])) { result->setTo_S_add_SV(constantVal, multiplicity *leftConstantResults[sv[0]], rightVectorResults[sv[1]].get()); } else { result->setTo_S_add_V(constantVal, rightVectorResults[sv[1]].get()); } } else { if (!isOne(multiplicity*leftConstantResults[sv[0]])) { result->setTo_SV(multiplicity *leftConstantResults[sv[0]], rightVectorResults[sv[1]].get()); } else { result->setTo_V(rightVectorResults[sv[1]].get()); } } SUNDANCE_MSG5(mgr.verb(), tabs << "init to c-v prod, m=" << multiplicity << ", left=" << leftConstantResults[sv[0]] << ", right=" << rightVectorResults[sv[1]]->str() << ", result=" << result->str()); } SUNDANCE_MSG4(mgr.verb(), tabs << "starting value = " << result->str()); } vectorResults[resultIndex_[order][i]] = result; const Array<Array<int> >& cvTerms = cvTerms_[order][i]; const Array<Array<int> >& vcTerms = vcTerms_[order][i]; const Array<Array<int> >& vvTerms = vvTerms_[order][i]; for (int j=0; j<cvTerms.size(); j++) { SUNDANCE_MSG4(mgr.verb(), tabs << "adding c-v term " << cvTerms[j]); double multiplicity = cvTerms[j][2]; double scalar = multiplicity*leftConstantResults[cvTerms[j][0]]; const EvalVector* vec = rightVectorResults[cvTerms[j][1]].get(); if (!isOne(scalar)) { result->add_SV(scalar, vec); } else { result->add_V(vec); } } for (int j=0; j<vcTerms.size(); j++) { SUNDANCE_MSG4(mgr.verb(), tabs << "adding v-c term " << vcTerms[j]); double multiplicity = vcTerms[j][2]; double scalar = multiplicity*rightConstantResults[vcTerms[j][1]]; const EvalVector* vec = leftVectorResults[vcTerms[j][0]].get(); if (!isOne(scalar)) { result->add_SV(scalar, vec); } else { result->add_V(vec); } } for (int j=0; j<vvTerms.size(); j++) { SUNDANCE_MSG4(mgr.verb(), tabs << "adding v-v term " << vvTerms[j]); double multiplicity = vvTerms[j][2]; const EvalVector* vec1 = leftVectorResults[vvTerms[j][0]].get(); const EvalVector* vec2 = rightVectorResults[vvTerms[j][1]].get(); if (!isOne(multiplicity)) { result->add_SVV(multiplicity, vec1, vec2); } else { result->add_VV(vec1, vec2); } } } } if (mgr.verb() > 1) { Out::os() << tabs << "product result " << std::endl; mgr.showResults(Out::os(), this->sparsity(), vectorResults, constantResults); } }
void DiffOpEvaluator::internalEval(const EvalManager& mgr, Array<double>& constantResults, Array<RCP<EvalVector> >& vectorResults) const { Tabs tabs; SUNDANCE_MSG1(mgr.verb(), tabs << "DiffOpEvaluator::eval() expr=" << expr()->toString()); /* evaluate the argument */ Array<RCP<EvalVector> > argVectorResults; Array<double> argConstantResults; SUNDANCE_MSG2(mgr.verb(), tabs << "evaluating operand"); evalOperand(mgr, argConstantResults, argVectorResults); if (mgr.verb() > 2) { Tabs tab1; Out::os() << tabs << "DiffOp operand results" << std::endl; mgr.showResults(Out::os(), argSparsitySuperset(), argVectorResults, argConstantResults); } /* evaluate the required discrete functions */ SUNDANCE_MSG2(mgr.verb(), tabs << "evaluating discrete functions, num funcs= " << funcEvaluators_.size()); Array<Array<RCP<EvalVector> > > funcVectorResults(funcEvaluators_.size()); Array<double> funcConstantResults; for (int i=0; i<funcEvaluators_.size(); i++) { funcEvaluators_[i]->eval(mgr, funcConstantResults, funcVectorResults[i]); } constantResults.resize(this->sparsity()->numConstantDerivs()); vectorResults.resize(this->sparsity()->numVectorDerivs()); SUNDANCE_MSG3(mgr.verb(), tabs << "summing spatial/functional chain rule"); for (int i=0; i<this->sparsity()->numDerivs(); i++) { Tabs tab1; SUNDANCE_MSG4(mgr.verb(), tab1 << "working on deriv " << this->sparsity()->deriv(i)); /* add constant monomials */ SUNDANCE_MSG4(mgr.verb(), tab1 << "have " << constantMonomials_[i].size() << " constant monomials"); double constantVal = 0.0; for (int j=0; j<constantMonomials_[i].size(); j++) { SUNDANCE_MSG4(mgr.verb(), tab1 << "adding in constant monomial (index " << constantMonomials_[i][j] << " in arg results)"); constantVal += argConstantResults[constantMonomials_[i][j]]; } if (isConstant_[i]) { constantResults[resultIndices_[i]] = constantVal; SUNDANCE_MSG4(mgr.verb(), tab1 << "result is constant: value=" << constantVal); continue; } RCP<EvalVector> result; bool vecHasBeenAllocated = false; /* add in the vector monomials */ const Array<int>& vm = vectorMonomials_[i]; SUNDANCE_MSG4(mgr.verb(), tab1 << "have " << vm.size() << " vector monomials"); for (int j=0; j<vm.size(); j++) { Tabs tab2; const RCP<EvalVector>& v = argVectorResults[vm[j]]; SUNDANCE_MSG4(mgr.verb(), tab2 << "found vec monomial term " << v->str()); /* if we've not yet allocated a vector for the results, * do so now, and set it to the initial value */ if (!vecHasBeenAllocated) { SUNDANCE_MSG4(mgr.verb(), tab2 << "allocated result vector"); result = mgr.popVector(); vecHasBeenAllocated = true; if (isZero(constantVal)) { result->setTo_V(v.get()); } else { result->setTo_S_add_V(constantVal, v.get()); } } else { result->add_V(v.get()); } SUNDANCE_MSG4(mgr.verb(), tab2 << "result is " << result->str()); } /* add in the function terms with constant coeffs */ const Array<int>& cf = constantFuncCoeffs_[i]; SUNDANCE_MSG4(mgr.verb(), tab1 << "adding " << cf.size() << " func terms with constant coeffs"); for (int j=0; j<cf.size(); j++) { Tabs tab2; const double& coeff = argConstantResults[cf[j]]; int fIndex = constantCoeffFuncIndices_[i][j]; int miIndex = constantCoeffFuncMi_[i][j]; const RCP<EvalVector>& fValue = funcVectorResults[fIndex][miIndex]; SUNDANCE_MSG4(mgr.verb(), tab2 << "found term: coeff= " << coeff << ", func value=" << fValue->str()); /* if we've not yet allocated a vector for the results, * do so now, and set it to the initial value */ if (!vecHasBeenAllocated) { SUNDANCE_MSG4(mgr.verb(), tab2 << "allocated result vector"); result = mgr.popVector(); vecHasBeenAllocated = true; if (isOne(coeff)) { if (isZero(constantVal)) { result->setTo_V(fValue.get()); } else { result->setTo_S_add_V(constantVal, fValue.get()); } } else { if (isZero(constantVal)) { result->setTo_SV(coeff, fValue.get()); } else { result->setTo_S_add_SV(constantVal, coeff, fValue.get()); } } } else { if (isOne(coeff)) { result->add_V(fValue.get()); } else { result->add_SV(coeff, fValue.get()); } } SUNDANCE_MSG4(mgr.verb(), tab2 << "result is " << result->str()); } /* add in the function terms with vector coeffs */ const Array<int>& vf = vectorFuncCoeffs_[i]; SUNDANCE_MSG4(mgr.verb(), tab1 << "adding " << vf.size() << " func terms with vector coeffs"); for (int j=0; j<vf.size(); j++) { Tabs tab2; const RCP<EvalVector>& coeff = argVectorResults[vf[j]]; int fIndex = vectorCoeffFuncIndices_[i][j]; int miIndex = vectorCoeffFuncMi_[i][j]; const RCP<EvalVector>& fValue = funcVectorResults[fIndex][miIndex]; SUNDANCE_MSG4(mgr.verb(), tab2 << "found term: coeff= " << coeff->str() << ", func value=" << fValue->str()); /* if we've not yet allocated a vector for the results, * do so now, and set it to the initial value */ if (!vecHasBeenAllocated) { SUNDANCE_MSG4(mgr.verb(), tab2 << "allocated result vector"); result = mgr.popVector(); vecHasBeenAllocated = true; result->setTo_VV(coeff.get(), fValue.get()); } else { result->add_VV(coeff.get(), fValue.get()); } SUNDANCE_MSG4(mgr.verb(), tab2 << "result is " << result->str()); } TEUCHOS_TEST_FOR_EXCEPTION(!vecHasBeenAllocated, std::logic_error, "created empty vector in DiffOpEvaluator::internalEval"); vectorResults[resultIndices_[i]] = result; } if (mgr.verb() > 1) { Out::os() << tabs << "diff op results" << std::endl; mgr.showResults(Out::os(), sparsity(), vectorResults, constantResults); } SUNDANCE_MSG1(mgr.verb(), tabs << "done spatial/functional chain rule"); }