SundanceEvalVector.cpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                             Sundance
00005 //                 Copyright 2011 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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   //TimeMonitor t(evalVecTimer());
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 

Site Contact