SundanceDerivOfSymbFuncEvaluator.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                              Sundance
00005 //                 Copyright (2005) Sandia Corporation
00006 // 
00007 // Copyright (year first published) Sandia Corporation.  Under the terms 
00008 // of Contract DE-AC04-94AL85000 with Sandia Corporation, the U.S. Government 
00009 // retains certain rights in this software.
00010 // 
00011 // This library is free software; you can redistribute it and/or modify
00012 // it under the terms of the GNU Lesser General Public License as
00013 // published by the Free Software Foundation; either version 2.1 of the
00014 // License, or (at your option) any later version.
00015 //  
00016 // This library is distributed in the hope that it will be useful, but
00017 // WITHOUT ANY WARRANTY; without even the implied warranty of
00018 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00019 // Lesser General Public License for more details.
00020 //                                                                                 
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License along with this library; if not, write to the Free Software
00023 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00024 // USA                                                                                
00025 // Questions? Contact Kevin Long (krlong@sandia.gov), 
00026 // Sandia National Laboratories, Livermore, California, USA
00027 // 
00028 // ************************************************************************
00029 /* @HEADER@ */
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   /* If we have a test function, its value will be zero. The only nonzero
00082    * functional derivative will be wrt D[f, mi]. The value of that deriv
00083    * is one. */
00084   if (t != 0)
00085     {
00086       constResultIndex_ = 0;
00087       addConstantIndex(0, constResultIndex_);
00088       evalPtIsZero_ = true;
00089       return;
00090     }
00091 
00092   /* If we have an unknown function, we need to see if it is to
00093    * be evaluated at zero. */
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           /* we have a nonzero evaluation point. We now need to find 
00129            * the index of my multiindex in the function's result set */
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   /* if the function is a test or zero func, we can take a quick way out */
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       /* evaluate the argument */
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 }

Site Contact