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 "SundanceEvalVector.hpp"
00043 #include "SundanceTempStack.hpp"
00044 #include "PlayaExceptions.hpp"
00045 #include "PlayaTabs.hpp"
00046 #include "SundanceOut.hpp"
00047 #include "Teuchos_TimeMonitor.hpp"
00048
00049 using namespace Sundance;
00050 using namespace Sundance;
00051
00052 using namespace Teuchos;
00053
00054
00055
00056
00057 EvalVector::EvalVector(TempStack* s)
00058 : s_(s),
00059 data_(s->popVectorData()),
00060 str_()
00061 {
00062 data_->resize(s->vecSize());
00063 }
00064
00065
00066 EvalVector::EvalVector(TempStack* s, const RCP<Array<double> >& data,
00067 const std::string& str)
00068 : s_(s),
00069 data_(s->popVectorData()),
00070 str_(str)
00071 {
00072
00073 data_->resize(data->size());
00074 int n = data_->size();
00075
00076 if (n > 0)
00077 {
00078 double* x = &((*data_)[0]);
00079 const double* y = &((*data)[0]);
00080 for (int i=0; i<n; i++)
00081 {
00082 x[i] = y[i];
00083 }
00084 }
00085 }
00086
00087 EvalVector::~EvalVector()
00088 {
00089 s_->pushVectorData(data_);
00090 }
00091
00092
00093 void EvalVector::resize(int n)
00094 {
00095
00096 data_->resize(n);
00097 }
00098
00099 RCP<EvalVector> EvalVector::clone() const
00100 {
00101 return rcp(new EvalVector(s_, data_, str_));
00102 }
00103
00104 void EvalVector::setToConstant(const double& alpha)
00105 {
00106
00107 int n = data_->size();
00108 if (n > 0)
00109 {
00110 double* x = &((*data_)[0]);
00111 for (int i=0; i<n; i++)
00112 {
00113 x[i] = alpha;
00114 }
00115 }
00116 if (shadowOps()) str_ = Teuchos::toString(alpha);
00117 }
00118
00119
00120 void EvalVector::add_SV(const double& alpha,
00121 const EvalVector* B)
00122 {
00123
00124 int n = data_->size();
00125
00126 if (n > 0)
00127 {
00128 double* const x = start();
00129 const double* const Bx = B->start();
00130
00131 for (int i=0; i<n; i++)
00132 {
00133 x[i] += alpha*Bx[i];
00134 }
00135
00136 addFlops(2*n);
00137 }
00138
00139 if (shadowOps())
00140 {
00141 if (str_ != "0") str_ = "(" + str_ + "+"
00142 + Teuchos::toString(alpha) + "*" + B->str_ + ")";
00143 else str_ = Teuchos::toString(alpha) + "*" + B->str_;
00144 }
00145 }
00146
00147 void EvalVector::add_S(const double& alpha)
00148 {
00149
00150 int n = data_->size();
00151
00152 if (n > 0)
00153 {
00154 double* const x = start();
00155
00156 for (int i=0; i<n; i++)
00157 {
00158 x[i] += alpha;
00159 }
00160 addFlops(n);
00161 }
00162
00163 if (shadowOps())
00164 {
00165 if (str_ != "0") str_ = "(" + str_ + "+"
00166 + Teuchos::toString(alpha) + ")";
00167 else str_ = Teuchos::toString(alpha);
00168 }
00169 }
00170
00171
00172 void EvalVector::add_V(const EvalVector* A)
00173 {
00174
00175 int n = data_->size();
00176
00177 if (n > 0)
00178 {
00179 double* const x = start();
00180 const double* const Ax = A->start();
00181
00182 for (int i=0; i<n; i++)
00183 {
00184 x[i] += Ax[i];
00185 }
00186 addFlops(n);
00187 }
00188
00189 if (shadowOps())
00190 {
00191 if (str_ != "0") str_ = "(" + str_ + " + " + A->str_ + ")";
00192 else str_ = A->str_;
00193 }
00194 }
00195
00196 void EvalVector::add_SVV(const double& alpha,
00197 const EvalVector* B,
00198 const EvalVector* C)
00199 {
00200
00201 int n = data_->size();
00202
00203 if (n > 0)
00204 {
00205 double* const x = start();
00206 const double* const Bx = B->start();
00207 const double* const Cx = C->start();
00208
00209 for (int i=0; i<n; i++)
00210 {
00211 x[i] += alpha*Bx[i]*Cx[i];
00212 }
00213 addFlops(3*n);
00214 }
00215
00216 if (shadowOps())
00217 {
00218 if (str_ != "0") str_ = "(" + str_ + " + "
00219 + Teuchos::toString(alpha) + "*" + B->str() + "*" + C->str() + ")";
00220 else str_ = Teuchos::toString(alpha) + "*" + B->str() + "*" + C->str();
00221 }
00222 }
00223
00224 void EvalVector::add_VV(const EvalVector* A,
00225 const EvalVector* B)
00226 {
00227
00228 int n = data_->size();
00229
00230 if (n > 0)
00231 {
00232 double* const x = start();
00233 const double* const Ax = A->start();
00234 const double* const Bx = B->start();
00235
00236 for (int i=0; i<n; i++)
00237 {
00238 x[i] += Ax[i]*Bx[i];
00239 }
00240 addFlops(2*n);
00241 }
00242
00243 if (shadowOps())
00244 {
00245 if (str_ != "0") str_ = "(" + str_ + " + " + A->str()
00246 + "*" + B->str() + ")";
00247 else str_ =A->str() + "*" + B->str();
00248 }
00249 }
00250
00251
00252 void EvalVector::multiply_S_add_SV(const double& alpha,
00253 const double& beta,
00254 const EvalVector* C)
00255 {
00256
00257 int n = data_->size();
00258
00259 if (n > 0)
00260 {
00261 double* const x = start();
00262 const double* const Cx = C->start();
00263
00264 for (int i=0; i<n; i++)
00265 {
00266 x[i] *= alpha;
00267 x[i] += beta*Cx[i];
00268 }
00269 addFlops(3*n);
00270 }
00271
00272 if (shadowOps())
00273 {
00274 if (str_ != "0") str_ = "(" + Teuchos::toString(alpha) + "*" + str_ + "+"
00275 + Teuchos::toString(beta) + "*" + C->str_ + ")";
00276 else str_ = Teuchos::toString(beta) + "*" + C->str_;
00277 }
00278 }
00279
00280
00281 void EvalVector::multiply_S_add_S(const double& alpha,
00282 const double& beta)
00283 {
00284
00285 int n = data_->size();
00286
00287 if (n > 0)
00288 {
00289 double* const x = start();
00290
00291 for (int i=0; i<n; i++)
00292 {
00293 x[i] *= alpha;
00294 x[i] += beta;
00295 }
00296 addFlops(2*n);
00297 }
00298
00299 if (shadowOps())
00300 {
00301 if (str_ != "0") str_ = "(" + Teuchos::toString(alpha) + "*" + str_
00302 + " + " + Teuchos::toString(beta) + ")";
00303 else str_ = Teuchos::toString(beta);
00304 }
00305 }
00306
00307 void EvalVector::multiply_V(const EvalVector* A)
00308 {
00309
00310 int n = data_->size();
00311
00312 if (n > 0)
00313 {
00314 double* const x = start();
00315 const double* const Ax = A->start();
00316
00317 for (int i=0; i<n; i++)
00318 {
00319 x[i] *= Ax[i];
00320 }
00321 addFlops(n);
00322 }
00323
00324 if (shadowOps())
00325 {
00326 if (str_ != "0") str_ = str() + "*" + A->str();
00327 }
00328 }
00329
00330 void EvalVector::multiply_V_add_VVV(const EvalVector* A,
00331 const EvalVector* B,
00332 const EvalVector* C,
00333 const EvalVector* D)
00334 {
00335
00336 int n = data_->size();
00337
00338 if (n > 0)
00339 {
00340 double* const x = start();
00341 const double* const Ax = A->start();
00342 const double* const Bx = B->start();
00343 const double* const Cx = C->start();
00344 const double* const Dx = D->start();
00345
00346 for (int i=0; i<n; i++)
00347 {
00348 x[i] *= Ax[i];
00349 x[i] += Bx[i]*Cx[i]*Dx[i];
00350 }
00351 addFlops(4*n);
00352 }
00353
00354 if (shadowOps())
00355 {
00356 if (str_ != "0") str_ = "(" + str() + "*" + A->str() + " + "
00357 + B->str() + "*" + C->str() + "*" + D->str() + ")";
00358 else str_ = B->str() + "*" + C->str() + "*" + D->str();
00359 }
00360 }
00361
00362 void EvalVector::multiply_V_add_SVV(const EvalVector* A,
00363 const double& beta,
00364 const EvalVector* C,
00365 const EvalVector* D)
00366 {
00367
00368 int n = data_->size();
00369
00370 if (n > 0)
00371 {
00372 double* const x = start();
00373 const double* const Ax = A->start();
00374 const double* const Cx = C->start();
00375 const double* const Dx = D->start();
00376
00377 for (int i=0; i<n; i++)
00378 {
00379 x[i] *= Ax[i];
00380 x[i] += beta*Cx[i]*Dx[i];
00381 }
00382 addFlops(4*n);
00383 }
00384
00385 if (shadowOps())
00386 {
00387 if (beta != 0.0)
00388 {
00389 str_ = "(" + str() + "*" + A->str();
00390 }
00391 else
00392 {
00393 str_ = str() + "*" + A->str();
00394 }
00395 if (beta != 0.0)
00396 {
00397 str_ += " + ";
00398 if (beta != 1.0)
00399 {
00400 str_ += Teuchos::toString(beta) + "*";
00401 }
00402 str_ += C->str() + "*" + D->str();
00403 }
00404 }
00405 }
00406
00407 void EvalVector::multiply_V_add_SV(const EvalVector* A,
00408 const double& beta,
00409 const EvalVector* C)
00410 {
00411
00412 int n = data_->size();
00413
00414 if (n > 0)
00415 {
00416 double* const x = start();
00417 const double* const Ax = A->start();
00418 const double* const Cx = C->start();
00419
00420 for (int i=0; i<n; i++)
00421 {
00422 x[i] *= Ax[i];
00423 x[i] += beta*Cx[i];
00424 }
00425 addFlops(3*n);
00426 }
00427
00428 if (shadowOps())
00429 {
00430 str_ = "(" + str() + "*" + A->str() + " + " + Teuchos::toString(beta)
00431 + "*" + C->str() + ")";
00432 }
00433 }
00434
00435 void EvalVector::multiply_VV(const EvalVector* A,
00436 const EvalVector* B)
00437 {
00438
00439 int n = data_->size();
00440
00441 if (n > 0)
00442 {
00443 double* const x = start();
00444 const double* const Ax = A->start();
00445 const double* const Bx = B->start();
00446
00447 for (int i=0; i<n; i++)
00448 {
00449 x[i] *= Ax[i]*Bx[i];
00450 }
00451 addFlops(2*n);
00452 }
00453
00454 if (shadowOps())
00455 {
00456 str_ = str() + "*" + A->str() + "*" + B->str();
00457 }
00458 }
00459
00460
00461 void EvalVector::multiply_SV(const double& alpha,
00462 const EvalVector* B)
00463 {
00464
00465 int n = data_->size();
00466
00467 if (n > 0)
00468 {
00469 double* const x = start();
00470
00471 const double* const Bx = B->start();
00472
00473 for (int i=0; i<n; i++)
00474 {
00475 x[i] *= alpha*Bx[i];
00476 }
00477 addFlops(2*n);
00478 }
00479
00480 if (shadowOps())
00481 {
00482 str_ = Teuchos::toString(alpha) + "*" + str_ + "*" + B->str();
00483 }
00484 }
00485
00486 void EvalVector::multiply_S(const double& alpha)
00487 {
00488
00489 int n = data_->size();
00490
00491 if (n > 0)
00492 {
00493 double* const x = start();
00494
00495 for (int i=0; i<n; i++)
00496 {
00497 x[i] *= alpha;
00498 }
00499 addFlops(n);
00500 }
00501
00502 if (shadowOps())
00503 {
00504 str_ = Teuchos::toString(alpha) + "*" + str_;
00505 }
00506 }
00507
00508
00509 void EvalVector::setTo_S_add_SVV(const double& alpha,
00510 const double& beta,
00511 const EvalVector* C,
00512 const EvalVector* D)
00513 {
00514
00515 int n = C->data_->size();
00516 resize(n);
00517
00518 if (n > 0)
00519 {
00520 double* const x = start();
00521 const double* const Cx = C->start();
00522 const double* const Dx = D->start();
00523
00524 for (int i=0; i<n; i++)
00525 {
00526 x[i] = alpha + beta*Cx[i]*Dx[i];
00527 }
00528 addFlops(3*n);
00529 }
00530
00531 if (shadowOps())
00532 {
00533 str_ = "(" + Teuchos::toString(alpha) + " + "
00534 + Teuchos::toString(beta) + "*"
00535 + C->str() + "*" + D->str() + ")";
00536 }
00537 }
00538
00539 void EvalVector::setTo_S_add_VV(const double& alpha,
00540 const EvalVector* B,
00541 const EvalVector* C)
00542 {
00543
00544 int n = B->data_->size();
00545 resize(n);
00546
00547 if (n > 0)
00548 {
00549 double* const x = start();
00550 const double* const Bx = B->start();
00551 const double* const Cx = C->start();
00552
00553 for (int i=0; i<n; i++)
00554 {
00555 x[i] = alpha + Bx[i]*Cx[i];
00556 }
00557 addFlops(2*n);
00558 }
00559
00560 if (shadowOps())
00561 {
00562 str_ = "(" + Teuchos::toString(alpha) + " + "
00563 + B->str() + "*" + C->str() + ")";
00564 }
00565 }
00566
00567 void EvalVector::setTo_S_add_SV(const double& alpha,
00568 const double& beta,
00569 const EvalVector* C)
00570 {
00571
00572 int n = C->data_->size();
00573 resize(n);
00574
00575 if (n > 0)
00576 {
00577 double* const x = start();
00578 const double* const Cx = C->start();
00579
00580 for (int i=0; i<n; i++)
00581 {
00582 x[i] = alpha + beta*Cx[i];
00583 }
00584 addFlops(2*n);
00585 }
00586
00587 if (shadowOps())
00588 {
00589 str_ = "(" + Teuchos::toString(alpha) + " + "
00590 + Teuchos::toString(beta) + "*"
00591 + C->str() + ")";
00592 }
00593 }
00594
00595
00596
00597 void EvalVector::setTo_S_add_V(const double& alpha,
00598 const EvalVector* B)
00599 {
00600
00601 int n = B->data_->size();
00602 resize(n);
00603
00604 if (n > 0)
00605 {
00606 double* const x = start();
00607 const double* const Bx = B->start();
00608
00609 for (int i=0; i<n; i++)
00610 {
00611 x[i] = alpha + Bx[i];
00612 }
00613 addFlops(n);
00614 }
00615
00616 if (shadowOps())
00617 {
00618 str_ = "(" + Teuchos::toString(alpha) + " + "
00619 + B->str() + ")";
00620 }
00621 }
00622
00623
00624 void EvalVector::setTo_V(const EvalVector* A)
00625 {
00626
00627 int n = A->data_->size();
00628 resize(n);
00629
00630 if (n > 0)
00631 {
00632 double* const x = start();
00633 const double* const Ax = A->start();
00634
00635 for (int i=0; i<n; i++)
00636 {
00637 x[i] = Ax[i];
00638 }
00639 }
00640
00641 if (shadowOps())
00642 {
00643 str_ = A->str();
00644 }
00645 }
00646
00647
00648
00649 void EvalVector::setTo_SVV(const double& alpha,
00650 const EvalVector* B,
00651 const EvalVector* C)
00652 {
00653
00654 int n = B->data_->size();
00655 resize(n);
00656
00657 if (n > 0)
00658 {
00659 double* const x = start();
00660 const double* const Bx = B->start();
00661 const double* const Cx = C->start();
00662
00663
00664 for (int i=0; i<n; i++)
00665 {
00666 x[i] = alpha*Bx[i]*Cx[i];
00667 }
00668 addFlops(2*n);
00669 }
00670
00671 if (shadowOps())
00672 {
00673 str_ = Teuchos::toString(alpha) + "*"
00674 + B->str() + "*" + C->str();
00675 }
00676 }
00677
00678 void EvalVector::setTo_VV(const EvalVector* A,
00679 const EvalVector* B)
00680 {
00681
00682 int n = A->data_->size();
00683 resize(n);
00684
00685 if (n > 0)
00686 {
00687 double* const x = start();
00688 const double* const Ax = A->start();
00689 const double* const Bx = B->start();
00690
00691
00692 for (int i=0; i<n; i++)
00693 {
00694 x[i] = Ax[i]*Bx[i];
00695 }
00696
00697 addFlops(n);
00698 }
00699
00700 if (shadowOps())
00701 {
00702 str_ = A->str() + "*" + B->str();
00703 }
00704 }
00705
00706 void EvalVector::setTo_SV(const double& alpha,
00707 const EvalVector* B)
00708 {
00709
00710 int n = B->data_->size();
00711 resize(n);
00712
00713 if (n > 0)
00714 {
00715 double* const x = start();
00716 const double* const Bx = B->start();
00717
00718
00719 for (int i=0; i<n; i++)
00720 {
00721 x[i] = alpha*Bx[i];
00722 }
00723 addFlops(n);
00724 }
00725
00726 if (shadowOps())
00727 {
00728 str_ = Teuchos::toString(alpha) + "*"
00729 + B->str();
00730 }
00731 }
00732
00733 void EvalVector::applyUnaryOperator(const UnaryFunctor* func,
00734 Array<RCP<EvalVector> >& opDerivs)
00735 {
00736
00737 int n = data_->size();
00738
00739 int order = opDerivs.size()-1;
00740
00741 TEUCHOS_TEST_FOR_EXCEPTION(order < 0 || order > 2, std::runtime_error,
00742 "illegal order=" << order << " in "
00743 "EvalVector::applyUnaryOperator()");
00744
00745 opDerivs[0] = s_->popVector();
00746 opDerivs[0]->resize(n);
00747 if (order > 0)
00748 {
00749 opDerivs[1] = s_->popVector();
00750 opDerivs[1]->resize(n);
00751 }
00752 if (order > 1)
00753 {
00754 opDerivs[2] = s_->popVector();
00755 opDerivs[2]->resize(n);
00756 }
00757
00758 if (n > 0)
00759 {
00760 double* const x = start();
00761 double* const f = opDerivs[0]->start();
00762 if (order==0)
00763 {
00764 func->eval0(x, n, f);
00765 }
00766 else if (order==1)
00767 {
00768 double* const df = opDerivs[1]->start();
00769 func->eval1(x, n, f, df);
00770 }
00771 else
00772 {
00773 double* const df = opDerivs[1]->start();
00774 double* const df2 = opDerivs[2]->start();
00775 func->eval2(x, n, f, df, df2);
00776 }
00777
00778 }
00779
00780 if (shadowOps())
00781 {
00782 opDerivs[0]->setString(func->name() + "(" + str() + ")");
00783 if (order > 0)
00784 {
00785 opDerivs[1]->setString(func->name() + "'(" + str() + ")");
00786 }
00787 if (order > 1)
00788 {
00789 opDerivs[2]->setString(func->name() + "\"(" + str() + ")");
00790 }
00791 }
00792 }
00793
00794 void EvalVector::print(std::ostream& os) const
00795 {
00796 TEUCHOS_TEST_FOR_EXCEPTION(shadowOps() && str_.size()==0, std::runtime_error, "empty eval vector result string!");
00797 os << str_;
00798
00799 if (data_->size() > 0)
00800 {
00801 os << ", " << *data_;
00802 }
00803 }
00804
00805
00806
00807
00808
00809
00810
00811