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