Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042 #include "SundanceDerivOfSymbFuncEvaluator.hpp"
00043 #include "SundanceEvalManager.hpp"
00044 #include "SundanceDerivOfSymbFunc.hpp"
00045
00046 #include "PlayaTabs.hpp"
00047 #include "SundanceOut.hpp"
00048 #include "SundanceUnknownFuncElement.hpp"
00049 #include "SundanceTestFuncElement.hpp"
00050 #include "SundanceDiscreteFuncElement.hpp"
00051 #include "SundanceDiscreteFuncEvaluator.hpp"
00052 #include "SundanceZeroExpr.hpp"
00053
00054 using namespace Sundance;
00055 using namespace Sundance;
00056 using namespace Sundance;
00057 using namespace Teuchos;
00058
00059
00060
00061
00062
00063 DerivOfSymbFuncEvaluator
00064 ::DerivOfSymbFuncEvaluator(const DerivOfSymbFunc* expr,
00065 const EvalContext& context)
00066 : UnaryEvaluator<DerivOfSymbFunc>(expr, context),
00067 funcEvaluator_(),
00068 funcMiIndex_(-1),
00069 evalPtIsZero_(false),
00070 constResultIndex_(-1),
00071 funcSparsitySuperset_()
00072 {
00073 Tabs tabs;
00074 int verb = context.setupVerbosity();
00075 SUNDANCE_MSG1(verb, tabs << "initializing DerivOfSymbFunc evaluator for "
00076 << expr->toString());
00077
00078 SUNDANCE_MSG2(verb, tabs << "return sparsity " << std::endl << *(this->sparsity)());
00079
00080 const MultiIndex& mi = expr->mi();
00081 const SymbolicFuncElement* sf
00082 = dynamic_cast<const SymbolicFuncElement*>(expr->evaluatableArg());
00083
00084 TEUCHOS_TEST_FOR_EXCEPTION(sf==0, std::logic_error,
00085 "Non-symbolic function detected where a symbolic "
00086 "function was expected in "
00087 "DerivOfSymbFuncEvaluator ctor");
00088
00089 const TestFuncElement* t = dynamic_cast<const TestFuncElement*>(sf);
00090 const UnknownFuncElement* u = dynamic_cast<const UnknownFuncElement*>(sf);
00091
00092
00093
00094
00095 if (t != 0)
00096 {
00097 constResultIndex_ = 0;
00098 addConstantIndex(0, constResultIndex_);
00099 evalPtIsZero_ = true;
00100 return;
00101 }
00102
00103
00104
00105
00106 TEUCHOS_TEST_FOR_EXCEPTION(u==0, std::logic_error,
00107 "Non-unknown function detected where an unknown "
00108 "function was expected in "
00109 "DerivOfSymbFuncEvaluator ctor");
00110
00111 const EvaluatableExpr* evalPt = u->evalPt();
00112 const ZeroExpr* z = dynamic_cast<const ZeroExpr*>(evalPt);
00113
00114 if (z != 0)
00115 {
00116 constResultIndex_ = 0;
00117 addConstantIndex(0, constResultIndex_);
00118 evalPtIsZero_ = true;
00119 return;
00120 }
00121 else
00122 {
00123 SUNDANCE_MSG2(verb, tabs << "setting up evaluation for discrete eval pt");
00124 u->setupEval(context);
00125 }
00126
00127 int vecResultIndex = 0;
00128 for (int i=0; i<this->sparsity()->numDerivs(); i++)
00129 {
00130 if (this->sparsity()->state(i)==ConstantDeriv)
00131 {
00132 constResultIndex_ = 0;
00133 addConstantIndex(i, constResultIndex_);
00134 continue;
00135 }
00136 else
00137 {
00138 addVectorIndex(i, vecResultIndex++);
00139
00140
00141
00142 const DiscreteFuncElement* df
00143 = dynamic_cast<const DiscreteFuncElement*>(evalPt);
00144
00145 TEUCHOS_TEST_FOR_EXCEPTION(df==0, std::logic_error,
00146 "DerivOfSymbFuncEvaluator ctor: evaluation point of "
00147 "unknown function " << u->toString()
00148 << " is not a discrete function");
00149
00150 const SymbolicFuncElementEvaluator* uEval
00151 = dynamic_cast<const SymbolicFuncElementEvaluator*>(u->evaluator(context).get());
00152 TEUCHOS_TEST_FOR_EXCEPTION(uEval==0, std::logic_error,
00153 "DerivOfSymbFuncEvaluator ctor: null evaluator for "
00154 "evaluation point");
00155
00156 const DiscreteFuncElementEvaluator* dfEval = uEval->dfEval();
00157
00158 TEUCHOS_TEST_FOR_EXCEPTION(dfEval==0, std::logic_error,
00159 "DerivOfSymbFuncEvaluator ctor: evaluator for "
00160 "evaluation point is not a "
00161 "DiscreteFuncElementEvaluator");
00162
00163 funcEvaluator_.append(dfEval);
00164 funcSparsitySuperset_ = dfEval->sparsity();
00165
00166
00167 TEUCHOS_TEST_FOR_EXCEPTION(!dfEval->hasMultiIndex(mi), std::logic_error,
00168 "DerivOfSymbFuncEvaluator ctor: evaluator for "
00169 "discrete function " << df->toString()
00170 << " does not know about multiindex "
00171 << mi.toString());
00172
00173 funcMiIndex_ = dfEval->miIndex(mi);
00174 }
00175 }
00176 }
00177
00178
00179
00180 void DerivOfSymbFuncEvaluator::internalEval(const EvalManager& mgr,
00181 Array<double>& constantResults,
00182 Array<RCP<EvalVector> >& vectorResults) const
00183 {
00184 Tabs tabs;
00185 SUNDANCE_MSG1(mgr.verb(), tabs << "DerivOfSymbFuncEvaluator::eval() expr="
00186 << expr()->toString());
00187
00188
00189 if (evalPtIsZero_)
00190 {
00191 Tabs tabs1;
00192 SUNDANCE_MSG2(mgr.verb(), tabs1 << "taking zero function shortcut");
00193 constantResults.resize(1);
00194 constantResults[0] = 1.0;
00195 return;
00196 }
00197
00198 if (constResultIndex_ >= 0)
00199 {
00200 constantResults.resize(1);
00201 constantResults[0] = 1.0;
00202 }
00203 if (funcMiIndex_ >= 0)
00204 {
00205 Tabs tabs1;
00206 SUNDANCE_MSG2(mgr.verb(), tabs1 << "evaluating argument");
00207
00208 Array<RCP<EvalVector> > funcVectorResults;
00209 Array<double> funcConstantResults;
00210
00211 funcEvaluator_[0]->eval(mgr,
00212 funcConstantResults, funcVectorResults);
00213 if (mgr.verb() > 1)
00214 {
00215 Out::os() << tabs1 << "DerivOfSymbFunc results" << std::endl;
00216 funcSparsitySuperset_->print(Out::os(), funcVectorResults,
00217 funcConstantResults);
00218 }
00219 vectorResults.resize(1);
00220 vectorResults[0] = funcVectorResults[funcMiIndex_];
00221 }
00222 }
00223
00224
00225
00226 void DerivOfSymbFuncEvaluator::resetNumCalls() const
00227 {
00228 if (funcEvaluator_.size() > 0)
00229 {
00230 funcEvaluator_[0]->resetNumCalls();
00231 }
00232 Evaluator::resetNumCalls();
00233 }