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