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 "SundanceSumEvaluator.hpp"
00043 #include "SundanceEvalManager.hpp"
00044 #include "SundanceSumExpr.hpp"
00045 #include "SundanceProductExpr.hpp"
00046
00047 #include "PlayaTabs.hpp"
00048 #include "SundanceOut.hpp"
00049
00050 using namespace Sundance;
00051 using namespace Sundance;
00052 using namespace Sundance;
00053 using namespace Teuchos;
00054
00055
00056
00057
00058 SumEvaluator::SumEvaluator(const SumExpr* se,
00059 const EvalContext& context)
00060 : BinaryEvaluator<SumExpr>(se, context),
00061 sign_(se->sign()),
00062 singleRightConstant_(),
00063 singleRightVector_(),
00064 singleLeftConstant_(),
00065 singleLeftVector_(),
00066 ccSums_(),
00067 cvSums_(),
00068 vcSums_(),
00069 vvSums_()
00070 {
00071 Tabs tabs(0);
00072 int verb = context.evalSetupVerbosity();
00073
00074 if (verb > 1)
00075 {
00076 Out::os() << tabs << "initializing sum evaluator for "
00077 << se->toString() << std::endl;
00078 }
00079
00080 int constantCounter = 0;
00081 int vectorCounter = 0;
00082
00083 if (verb > 2)
00084 {
00085 Out::os() << std::endl << tabs << "return sparsity ";
00086 this->sparsity()->print(Out::os());
00087 Out::os() << std::endl << tabs << "left sparsity ";
00088 leftSparsity()->print(Out::os());
00089 Out::os() << std::endl << tabs << "right sparsity " ;
00090 rightSparsity()->print(Out::os());
00091 Out::os() << std::endl;
00092
00093 Out::os() << tabs << "left vector index map " << leftEval()->vectorIndexMap() << std::endl;
00094 Out::os() << tabs << "right vector index map " << rightEval()->vectorIndexMap() << std::endl;
00095
00096 Out::os() << tabs << "left constant index map " << leftEval()->constantIndexMap() << std::endl;
00097 Out::os() << tabs << "right constant index map " << rightEval()->constantIndexMap() << std::endl;
00098 }
00099
00100 for (int i=0; i<this->sparsity()->numDerivs(); i++)
00101 {
00102 const MultipleDeriv& d = this->sparsity()->deriv(i);
00103 TEUCHOS_TEST_FOR_EXCEPTION(!leftSparsity()->containsDeriv(d)
00104 && !rightSparsity()->containsDeriv(d),
00105 std::logic_error,
00106 "deriv " << d.toString()
00107 << " was not found in either left or right operand "
00108 "of expr " << expr()->toString());
00109
00110 int iLeft = -1;
00111 int iRight = -1;
00112
00113 if (leftSparsity()->containsDeriv(d))
00114 {
00115 iLeft = leftSparsity()->getIndex(d);
00116 }
00117
00118 if (rightSparsity()->containsDeriv(d))
00119 {
00120 iRight = rightSparsity()->getIndex(d);
00121 }
00122
00123 SUNDANCE_MSG2(verb, tabs << "deriv " << d);
00124
00125 if (iLeft == -1)
00126 {
00127 SUNDANCE_MSG3(verb, tabs << "left operand is zero ");
00128 if (rightSparsity()->state(iRight)==ConstantDeriv)
00129 {
00130 int rc = rightEval()->constantIndexMap().get(iRight);
00131 singleRightConstant_.append(tuple(constantCounter, rc));
00132 addConstantIndex(i, constantCounter++);
00133 SUNDANCE_MSG4(verb, tabs << "single right constant "
00134 << singleRightConstant_[singleRightConstant_.size()-1]);
00135 }
00136 else
00137 {
00138 int rv = rightEval()->vectorIndexMap().get(iRight);
00139 singleRightVector_.append(tuple(vectorCounter, rv));
00140 addVectorIndex(i, vectorCounter++);
00141 SUNDANCE_MSG4(verb, tabs << "single right vector "
00142 << singleRightVector_[singleRightVector_.size()-1]);
00143 }
00144 }
00145 else if (iRight == -1)
00146 {
00147 SUNDANCE_MSG3(verb, tabs << "right operand is zero ");
00148 if (leftSparsity()->state(iLeft)==ConstantDeriv)
00149 {
00150 int lc = leftEval()->constantIndexMap().get(iLeft);
00151 singleLeftConstant_.append(tuple(constantCounter, lc));
00152 addConstantIndex(i, constantCounter++);
00153 SUNDANCE_MSG4(verb, tabs << "single left constant "
00154 << singleLeftConstant_[singleLeftConstant_.size()-1]);
00155 }
00156 else
00157 {
00158 int lv = leftEval()->vectorIndexMap().get(iLeft);
00159 singleLeftVector_.append(tuple(vectorCounter, lv));
00160 addVectorIndex(i, vectorCounter++);
00161 SUNDANCE_MSG4(verb, tabs << "single left vector "
00162 << singleLeftVector_[singleLeftVector_.size()-1]);
00163 }
00164 }
00165 else
00166 {
00167 SUNDANCE_MSG4(verb, tabs << "both operands are nonzero ");
00168 bool leftIsConstant = leftSparsity()->state(iLeft)==ConstantDeriv;
00169 bool rightIsConstant = rightSparsity()->state(iRight)==ConstantDeriv;
00170
00171 if (leftIsConstant && rightIsConstant)
00172 {
00173 SUNDANCE_MSG4(verb, tabs << "both operands are constant");
00174 int lc = leftEval()->constantIndexMap().get(iLeft);
00175 int rc = rightEval()->constantIndexMap().get(iRight);
00176 ccSums_.append(tuple(constantCounter, lc, rc));
00177 addConstantIndex(i, constantCounter++);
00178 SUNDANCE_MSG4(verb, tabs << "c-c sum " << ccSums_[ccSums_.size()-1]);
00179 }
00180 else if (leftIsConstant)
00181 {
00182 SUNDANCE_MSG4(verb, tabs << "left operand is constant");
00183 int lc = leftEval()->constantIndexMap().get(iLeft);
00184 int rv = rightEval()->vectorIndexMap().get(iRight);
00185 cvSums_.append(tuple(vectorCounter, lc, rv));
00186 addVectorIndex(i, vectorCounter++);
00187 SUNDANCE_MSG4(verb, tabs << "c-v sum " << cvSums_[cvSums_.size()-1]);
00188 }
00189 else if (rightIsConstant)
00190 {
00191 SUNDANCE_MSG4(verb, tabs << "right operand is constant");
00192 int lv = leftEval()->vectorIndexMap().get(iLeft);
00193 int rc = rightEval()->constantIndexMap().get(iRight);
00194 vcSums_.append(tuple(vectorCounter, lv, rc));
00195 addVectorIndex(i, vectorCounter++);
00196 SUNDANCE_MSG4(verb, tabs << "v-c sum " << vcSums_[vcSums_.size()-1]);
00197 }
00198 else
00199 {
00200 SUNDANCE_MSG4(verb, tabs << "both operands are vectors");
00201 int lv = leftEval()->vectorIndexMap().get(iLeft);
00202 int rv = rightEval()->vectorIndexMap().get(iRight);
00203 vvSums_.append(tuple(vectorCounter, lv, rv));
00204 addVectorIndex(i, vectorCounter++);
00205 SUNDANCE_MSG4(verb, tabs << "v-v sum " << vvSums_[vvSums_.size()-1]);
00206 }
00207 }
00208 }
00209 }
00210
00211 void SumEvaluator
00212 ::internalEval(const EvalManager& mgr,
00213 Array<double>& constantResults,
00214 Array<RCP<EvalVector> >& vectorResults) const
00215 {
00216
00217 Tabs tabs(0);
00218
00219 SUNDANCE_MSG1(mgr.verb(),
00220 tabs << "SumEvaluator::eval() expr=" << expr()->toString());
00221
00222
00223 Array<RCP<EvalVector> > leftVectorResults;
00224 Array<RCP<EvalVector> > rightVectorResults;
00225 Array<double> leftConstResults;
00226 Array<double> rightConstResults;
00227 evalChildren(mgr, leftConstResults, leftVectorResults,
00228 rightConstResults, rightVectorResults);
00229
00230 if (verb() > 2)
00231 {
00232 Out::os() << tabs << "left operand " << std::endl;
00233 mgr.showResults(Out::os(), leftSparsity(), leftVectorResults,
00234 leftConstResults);
00235 Out::os() << tabs << "right operand " << std::endl;
00236 mgr.showResults(Out::os(), rightSparsity(), rightVectorResults,
00237 rightConstResults);
00238 }
00239
00240 constantResults.resize(this->sparsity()->numConstantDerivs());
00241 vectorResults.resize(this->sparsity()->numVectorDerivs());
00242
00243
00244 for (int i=0; i<singleRightConstant_.size(); i++)
00245 {
00246 Tabs tab1;
00247 constantResults[singleRightConstant_[i][0]]
00248 = sign_*rightConstResults[singleRightConstant_[i][1]];
00249 SUNDANCE_MSG2(mgr.verb(), tab1 << "sum for "
00250 << constantResultDeriv(singleRightConstant_[i][0])
00251 << ": L=0, R="
00252 << sign_*rightConstResults[singleRightConstant_[i][1]]);
00253 }
00254
00255
00256 for (int i=0; i<singleLeftConstant_.size(); i++)
00257 {
00258 Tabs tab1;
00259 constantResults[singleLeftConstant_[i][0]]
00260 = leftConstResults[singleLeftConstant_[i][1]];
00261 SUNDANCE_MSG2(mgr.verb(), tab1 << "sum for "
00262 << constantResultDeriv(singleLeftConstant_[i][0])
00263 << ": L="
00264 << leftConstResults[singleLeftConstant_[i][1]]
00265 << " R=0");
00266 }
00267
00268
00269 for (int i=0; i<singleRightVector_.size(); i++)
00270 {
00271 Tabs tab1;
00272 if (sign_ < 0.0) rightVectorResults[singleRightVector_[i][1]]->multiply_S(sign_);
00273 vectorResults[singleRightVector_[i][0]]
00274 = rightVectorResults[singleRightVector_[i][1]];
00275 SUNDANCE_MSG2(mgr.verb(), tab1 << "sum for "
00276 << vectorResultDeriv(singleRightVector_[i][0])
00277 << ": L=0, R="
00278 << sign_ << "*" <<
00279 rightVectorResults[singleRightVector_[i][1]]->str());
00280 }
00281
00282
00283 for (int i=0; i<singleLeftVector_.size(); i++)
00284 {
00285 Tabs tab1;
00286 vectorResults[singleLeftVector_[i][0]]
00287 = leftVectorResults[singleLeftVector_[i][1]];
00288 SUNDANCE_MSG2(mgr.verb(), tab1 << "sum for "
00289 << vectorResultDeriv(singleLeftVector_[i][0])
00290 << ": L="
00291 << leftVectorResults[singleLeftVector_[i][1]]->str()
00292 << " R=0");
00293 }
00294
00295
00296 for (int i=0; i<ccSums_.size(); i++)
00297 {
00298 Tabs tab1;
00299 constantResults[ccSums_[i][0]]
00300 = leftConstResults[ccSums_[i][1]]
00301 + sign_*rightConstResults[ccSums_[i][2]];
00302 SUNDANCE_MSG2(mgr.verb(), tab1 << "c-c sum for "
00303 << constantResultDeriv(ccSums_[i][0])
00304 << ": L=" << leftConstResults[ccSums_[i][1]]
00305 << " R=" << sign_*rightConstResults[ccSums_[i][2]]);
00306 }
00307
00308
00309 for (int i=0; i<cvSums_.size(); i++)
00310 {
00311 Tabs tab1;
00312 RCP<EvalVector>& v = rightVectorResults[cvSums_[i][2]];
00313 SUNDANCE_MSG2(mgr.verb(), tab1 << "doing c-v sum for "
00314 << vectorResultDeriv(cvSums_[i][0])
00315 << ": L=" << leftConstResults[cvSums_[i][1]]
00316 << " R=" << sign_ << "*"
00317 << rightVectorResults[cvSums_[i][2]]->str());
00318 if (isOne(sign_))
00319 {
00320 v->add_S(leftConstResults[cvSums_[i][1]]);
00321 }
00322 else
00323 {
00324 v->multiply_S_add_S(sign_, leftConstResults[cvSums_[i][1]]);
00325 }
00326 vectorResults[cvSums_[i][0]] = v;
00327 }
00328
00329
00330 for (int i=0; i<vcSums_.size(); i++)
00331 {
00332 Tabs tab1;
00333 RCP<EvalVector>& v = leftVectorResults[vcSums_[i][1]] ;
00334 SUNDANCE_MSG2(mgr.verb(), tab1 << "doing v-c sum for "
00335 << vectorResultDeriv(vcSums_[i][0])
00336 << ": L=" << leftVectorResults[vcSums_[i][1]]->str()
00337 << " R="
00338 << sign_*rightConstResults[vcSums_[i][2]]);
00339 v->add_S(sign_*rightConstResults[vcSums_[i][2]]);
00340 vectorResults[vcSums_[i][0]] = v;
00341 }
00342
00343
00344 for (int i=0; i<vvSums_.size(); i++)
00345 {
00346 Tabs tab1;
00347 RCP<EvalVector>& v = leftVectorResults[vvSums_[i][1]];
00348 SUNDANCE_MSG2(mgr.verb(), tab1 << "doing v-v sum for "
00349 << vectorResultDeriv(vvSums_[i][0])
00350 << ": L="
00351 << leftVectorResults[vvSums_[i][1]]->str()
00352 << " R=" << sign_ << "*"
00353 << rightVectorResults[vvSums_[i][2]]->str());
00354 if (isOne(sign_))
00355 {
00356 v->add_V(rightVectorResults[vvSums_[i][2]].get());
00357 }
00358 else
00359 {
00360 v->add_SV(sign_, rightVectorResults[vvSums_[i][2]].get());
00361 }
00362 vectorResults[vvSums_[i][0]] = v;
00363 }
00364
00365 if (mgr.verb() > 1)
00366 {
00367 Out::os() << tabs << "sum result " << std::endl;
00368 mgr.showResults(Out::os(), this->sparsity(), vectorResults,
00369 constantResults);
00370 }
00371 }
00372
00373