PlayaVectorFunctorsImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 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 #ifndef PLAYA_VECTORFUNCTORSIMPL_HPP
00043 #define PLAYA_VECTORFUNCTORSIMPL_HPP
00044 
00045 
00046 #include "PlayaDefs.hpp"
00047 #include "PlayaVectorFunctorsDecl.hpp"
00048 #include "PlayaMPIComm.hpp"
00049 #include "PlayaRand.hpp"
00050 
00051 namespace PlayaFunctors
00052 {
00053 
00054 /** \brief Elementwise absolute value */
00055 template <class Scalar>
00056 class Abs
00057 {
00058 public:
00059   /** */
00060   Abs() {}
00061 
00062   /** */
00063   Scalar operator()(const Scalar& x) const 
00064     {return ::fabs(x);}
00065 
00066   /** */
00067   std::string description() const {return "Abs()";}
00068 };
00069 
00070 /** \brief Elementwise reciprocal */
00071 template <class Scalar>
00072 class Reciprocal
00073 {
00074 public:
00075   /** */
00076   Reciprocal() {}
00077 
00078   /** */
00079   Scalar operator()(const Scalar& x) const 
00080     {return 1.0/x;}
00081 
00082   /** */
00083   std::string description() const {return "Reciprocal()";}
00084 };
00085 
00086 /** \brief Set each element to a random scalar */
00087 template <class Scalar>
00088 class Random
00089 {
00090 public:
00091   /** */
00092   Random() {}
00093 
00094   /** */
00095   Scalar operator()(const Scalar& x) const 
00096     {return Playa::Rand::val();}
00097 
00098   /** */
00099   std::string description() const {return "Random()";}
00100 };
00101 
00102 /** \brief Multiplication by a scalar */
00103 template <class Scalar>
00104 class ScalarMult
00105 {
00106 public:
00107   /** */
00108   ScalarMult(const Scalar& alpha) : alpha_(alpha) {}
00109 
00110   /** */
00111   Scalar operator()(const Scalar& x) const 
00112     {return alpha_*x;}
00113 
00114   /** */
00115   std::string description() const 
00116     {
00117       std::ostringstream oss;
00118       oss << "ScalarMult(alpha=" << alpha_ << ")";
00119       return oss.str();
00120     }
00121 private:
00122   Scalar alpha_;
00123 };
00124 
00125 /** \brief Identity functor, used for copying */
00126 template <class Scalar>
00127 class Identity
00128 {
00129 public:
00130   /** */
00131   Identity() {}
00132 
00133   /** */
00134   Scalar operator()(const Scalar& x) const 
00135     {return x;}
00136 
00137   /** */
00138   std::string description() const {return "Identity()";}
00139 };
00140 
00141 /** \brief Setting all elements to a constant */
00142 template <class Scalar>
00143 class SetConstant
00144 {
00145 public:
00146   /** */
00147   SetConstant(const Scalar& alpha) : alpha_(alpha) {}
00148 
00149   /** */
00150   Scalar operator()(const Scalar& x) const 
00151     {return alpha_;}
00152 
00153   /** */
00154   std::string description() const 
00155     {
00156       std::ostringstream oss;
00157       oss << "SetConstant(alpha=" << alpha_ << ")";
00158       return oss.str();
00159     }
00160 private:
00161   Scalar alpha_;
00162 };
00163 
00164 
00165 /** \brief Elementwise product (matlab dot star) */
00166 template <class Scalar>
00167 class DotStar
00168 {
00169 public:
00170   /** */
00171   DotStar() {}
00172 
00173   /** */
00174   Scalar operator()(const Scalar& x, const Scalar& y) const 
00175     {return x*y;}
00176 
00177   /** */
00178   std::string description() const {return "dotStar()";}
00179 };
00180 
00181 
00182 /** \brief Elementwise quotient (matlab dot slash) */
00183 template <class Scalar>
00184 class DotSlash
00185 {
00186 public:
00187   /** */
00188   DotSlash() {}
00189 
00190   /** */
00191   Scalar operator()(const Scalar& x, const Scalar& y) const 
00192     {return x/y;}
00193 
00194   /** */
00195   std::string description() const {return "dotSlash()";}
00196 };
00197 
00198 /** \brief x + b*y */
00199 template <class Scalar>
00200 class XPlusBetaY
00201 {
00202 public:
00203   /** */
00204   XPlusBetaY(const Scalar& b) : b_(b) {}
00205 
00206   /** */
00207   Scalar operator()(const Scalar& x, const Scalar& y) const 
00208     {return x + b_*y;}
00209 
00210   /** */
00211   std::string description() const 
00212     {
00213       std::ostringstream oss;
00214       oss << "XPlusBetaY(b=" << b_ << ")";
00215       return oss.str();
00216     }
00217 private:
00218   Scalar b_;
00219 };
00220 
00221 /** \brief Linear combination of two vectors */
00222 template <class Scalar>
00223 class LC2
00224 {
00225 public:
00226   /** */
00227   LC2(const Scalar& a, const Scalar& b) : a_(a), b_(b) {}
00228 
00229   /** */
00230   Scalar operator()(const Scalar& x, const Scalar& y) const 
00231     {return a_*x + b_*y;}
00232 
00233   /** */
00234   std::string description() const 
00235     {
00236       std::ostringstream oss;
00237       oss << "LC2(a=" << a_ << ", b=" << b_ << ")";
00238       return oss.str();
00239     }
00240 private:
00241   Scalar a_;
00242   Scalar b_;
00243 };
00244 
00245 
00246 /** \brief Linear combination of three vectors */
00247 template <class Scalar>
00248 class LC3
00249 {
00250 public:
00251   /** */
00252   LC3(const Scalar& a, const Scalar& b, const Scalar& c)
00253     : a_(a), b_(b), c_(c) {}
00254 
00255   /** */
00256   Scalar operator()(const Scalar& x, const Scalar& y, const Scalar& z) const 
00257     {return a_*x + b_*y + c_*z;}
00258 
00259 
00260   /** */
00261   std::string description() const 
00262     {
00263       std::ostringstream oss;
00264       oss << "LC3(a=" << a_ << ", b=" << b_ << ", c=" << c_ << ")";
00265       return oss.str();
00266     }
00267 private:
00268   Scalar a_;
00269   Scalar b_;
00270   Scalar c_;
00271 };
00272 
00273 
00274 /** \brief Euclidean norm of a vector */
00275 template <class Scalar>
00276 class Norm2 : public ReductionFunctorBase<Scalar>
00277 {
00278 public:
00279   Norm2(const MPIComm& comm)
00280     : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00281 
00282   void step(int i, const Scalar& x) const 
00283     {
00284       val_ += x*x;
00285     }
00286 
00287   void postProc() const 
00288     {
00289       Scalar final = val_;
00290       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::sumOp());
00291       val_ = final;
00292     }
00293 
00294   Scalar result() const 
00295     {
00296       return ::sqrt(val_);
00297     }
00298 
00299   /** */
00300   std::string description() const {return "Norm2()";}
00301 
00302 private:
00303   mutable Scalar val_;
00304 };
00305 
00306 /** \brief Weighted 2-norm of a vector */
00307 template <class Scalar>
00308 class WeightedNorm2 : public ReductionFunctorBase<Scalar>
00309 {
00310 public:
00311   WeightedNorm2(const MPIComm& comm)
00312     : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00313 
00314   void step(int i, const Scalar& x, const Scalar& y) const 
00315     {
00316       val_ += y*x*x;
00317     }
00318 
00319   void postProc() const 
00320     {
00321       Scalar final = val_;
00322       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::sumOp());
00323       val_ = final;
00324     }
00325 
00326   Scalar result() const 
00327     {
00328       return ::sqrt(val_);
00329     }
00330 
00331   /** */
00332   std::string description() const {return "WeightedNorm2()";}
00333 
00334 private:
00335   MPIComm comm_;
00336   mutable Scalar val_;
00337 };
00338 
00339 /** \brief 1-norm of a vector */
00340 template <class Scalar>
00341 class Norm1 : public ReductionFunctorBase<Scalar>
00342 {
00343 public:
00344   Norm1(const MPIComm& comm)
00345     : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00346 
00347   void step(int i, const Scalar& x) const 
00348     {
00349       val_ += ::fabs(x);
00350     }
00351 
00352   void postProc() const 
00353     {
00354       Scalar final = val_;
00355       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::sumOp());
00356       val_ = final;
00357     }
00358 
00359   Scalar result() const 
00360     {
00361       return val_;
00362     }
00363 
00364   /** */
00365   std::string description() const {return "Norm1()";}
00366 
00367 private:
00368   mutable Scalar val_;
00369 };
00370 
00371 /** \brief Infinity norm of a vector */
00372 template <class Scalar>
00373 class NormInf : public ReductionFunctorBase<Scalar>
00374 {
00375 public:
00376   NormInf(const MPIComm& comm)
00377     : ReductionFunctorBase<Scalar>(comm), val_(-1.0) {}
00378 
00379   void step(int i, const Scalar& x) const 
00380     {
00381       Scalar z = ::fabs(x);
00382       if (z > val_) val_ = z;
00383     }
00384 
00385   void postProc() const 
00386     {
00387       Scalar final = val_;
00388       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::maxOp());
00389       val_ = final;
00390     }
00391 
00392   Scalar result() const 
00393     {
00394       return val_;
00395     }
00396 
00397   /** */
00398   std::string description() const {return "NormInf()";}
00399 
00400 private:
00401   mutable Scalar val_;
00402 };
00403 
00404 /** \brief Dot product of two vectors */
00405 template <class Scalar>
00406 class DotProduct : public ReductionFunctorBase<Scalar>
00407 {
00408 public:
00409   DotProduct(const MPIComm& comm)
00410     : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00411 
00412   void step(int i, const Scalar& x, const Scalar& y) const 
00413     {
00414       val_ += x*y;
00415     }
00416 
00417   void postProc() const 
00418     {
00419       Scalar final = val_;
00420       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::sumOp());
00421       val_ = final;
00422     }
00423 
00424   Scalar result() const 
00425     {
00426       return val_;
00427     }
00428 
00429   /** */
00430   std::string description() const {return "DotProduct()";}
00431 
00432 private:
00433   mutable Scalar val_;
00434 };
00435 
00436 
00437 /** \brief Find value of minimum element of a vector */
00438 template <class Scalar>
00439 class Min : public ReductionFunctorBase<Scalar>
00440 {
00441 public:
00442   Min(const MPIComm& comm)
00443     : ReductionFunctorBase<Scalar>(comm), val_(HUGE_VAL) {}
00444 
00445   void step(int i, const Scalar& x) const 
00446     {
00447       if (x < val_) val_ = x;
00448     }
00449 
00450   void postProc() const 
00451     {
00452       Scalar final = val_;
00453       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::minOp());
00454       val_ = final;
00455     }
00456 
00457   Scalar result() const 
00458     {
00459       return val_;
00460     }
00461 
00462   /** */
00463   std::string description() const {return "Min()";}
00464 
00465 private:
00466   mutable Scalar val_;
00467 };
00468 
00469 
00470 /** \brief Find value of minimum element of a vector */
00471 template <class Scalar>
00472 class Max : public ReductionFunctorBase<Scalar>
00473 {
00474 public:
00475   Max(const MPIComm& comm)
00476     : ReductionFunctorBase<Scalar>(comm), val_(-HUGE_VAL) {}
00477 
00478   void step(int i, const Scalar& x) const 
00479     {
00480       if (x > val_) val_ = x;
00481     }
00482 
00483   void postProc() const 
00484     {
00485       Scalar final = val_;
00486       this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::maxOp());
00487       val_ = final;
00488     }
00489 
00490   Scalar result() const 
00491     {
00492       return val_;
00493     }
00494 
00495   /** */
00496   std::string description() const {return "Max()";}
00497 
00498 private:
00499   mutable Scalar val_;
00500 };
00501 
00502 
00503 
00504 
00505 }
00506 
00507 
00508 #endif
00509 
00510 
00511 

Site Contact