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 #ifndef PLAYA_VECTOROPSIMPL_HPP
00043 #define PLAYA_VECTOROPSIMPL_HPP
00044
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaVectorImpl.hpp"
00047 #include "PlayaVectorOpsDecl.hpp"
00048 #include "PlayaMPIComm.hpp"
00049 #include "Teuchos_RCP.hpp"
00050
00051 namespace PlayaFunctors
00052 {
00053 template <class Scalar> class BoundedMinLocFunctor;
00054
00055 template <class Scalar> class BoundedMaxLocFunctor;
00056
00057 template <class Scalar> class Norm2Dist;
00058
00059 template <class Scalar> class Norm1Dist;
00060
00061 template <class Scalar> class NormInfDist;
00062 }
00063
00064 namespace Playa
00065 {
00066
00067 using namespace PlayaFunctors;
00068
00069
00070 template <class Scalar> inline
00071 Scalar minloc(const Vector<Scalar>& x, int& gni)
00072 {
00073 return minlocWithBound(-HUGE_VAL, x, gni);
00074 }
00075
00076
00077 template <class Scalar> inline
00078 Scalar maxloc(const Vector<Scalar>& x, int& gni)
00079 {
00080 return maxlocWithBound(-HUGE_VAL, x, gni);
00081 }
00082
00083
00084 template <class Scalar> inline
00085 Scalar minlocWithBound(const Scalar& lowerBound,
00086 const Vector<Scalar>& x, int& gni)
00087 {
00088 IndexedValue<Scalar> y =
00089 x.applyUnaryReductionFunctor(BoundedMinLocFunctor<Scalar>(x.comm(), lowerBound, x.space().baseGlobalNaturalIndex()));
00090 gni = y.where;
00091 return y.what;
00092 }
00093
00094
00095 template <class Scalar> inline
00096 Scalar maxlocWithBound(const Scalar& upperBound,
00097 const Vector<Scalar>& x, int& gni)
00098 {
00099 IndexedValue<Scalar> y =
00100 x.applyUnaryReductionFunctor(BoundedMaxLocFunctor<Scalar>(x.comm(), upperBound, x.space().baseGlobalNaturalIndex()));
00101 gni = y.where;
00102 return y.what;
00103 }
00104
00105
00106
00107 template <class Scalar>
00108 Scalar norm2Dist(const Vector<Scalar>& x, const Vector<Scalar>& y)
00109 {
00110 return x.applyBinaryReductionFunctor(
00111 PlayaFunctors::Norm2Dist<Scalar>(x.comm()), y);
00112 }
00113
00114
00115 template <class Scalar>
00116 Scalar norm1Dist(const Vector<Scalar>& x, const Vector<Scalar>& y)
00117 {
00118 return x.applyBinaryReductionFunctor(
00119 PlayaFunctors::Norm1Dist<Scalar>(x.comm()), y);
00120 }
00121
00122
00123 template <class Scalar>
00124 Scalar normInfDist(const Vector<Scalar>& x, const Vector<Scalar>& y)
00125 {
00126 return x.applyBinaryReductionFunctor(
00127 PlayaFunctors::NormInfDist<Scalar>(x.comm()), y);
00128 }
00129
00130
00131 template <class Scalar>
00132 Scalar norm2(const Vector<Scalar>& x) {return x.norm2();}
00133
00134
00135 template <class Scalar>
00136 Scalar norm1(const Vector<Scalar>& x) {return x.norm1();}
00137
00138
00139 template <class Scalar>
00140 Scalar normInf(const Vector<Scalar>& x) {return x.normInf();}
00141
00142 }
00143
00144 namespace PlayaFunctors
00145 {
00146
00147
00148 using namespace Playa;
00149
00150
00151
00152 template <class Scalar>
00153 class BoundedMinLocFunctor : public ReductionFunctorBase<Scalar>
00154 {
00155 public:
00156
00157 BoundedMinLocFunctor(const MPIComm& comm, const Scalar& bound,
00158 int baseGNI)
00159 : ReductionFunctorBase<Scalar>(comm), min_(),
00160 bound_(bound), baseGNI_(baseGNI)
00161 {
00162 min_.what = HUGE_VAL;
00163 min_.where = -1;
00164 }
00165
00166
00167 void step(int i, const Scalar& x) const
00168 {
00169 if (x < min_.what && x > bound_)
00170 {
00171 min_.what = x;
00172 min_.where = i;
00173 }
00174 }
00175
00176
00177 void postProc() const
00178 {
00179 min_.where += baseGNI_;
00180
00181 IndexedValue<Scalar> out = min_;
00182
00183 this->comm().allReduce(&min_, &out, 1, MPIDataType::doubleIntPairType(),
00184 MPIOp::minlocOp());
00185 min_ = out;
00186 }
00187
00188
00189 IndexedValue<Scalar> result() const
00190 {
00191 return min_;
00192 }
00193
00194
00195 std::string description() const {return "MinLoc()";}
00196
00197 private:
00198 MPIComm comm_;
00199 mutable IndexedValue<Scalar> min_;
00200 Scalar bound_;
00201 int baseGNI_;
00202 };
00203
00204
00205
00206
00207 template <class Scalar>
00208 class BoundedMaxLocFunctor : public ReductionFunctorBase<Scalar>
00209 {
00210 public:
00211
00212 BoundedMaxLocFunctor(const MPIComm& comm, const Scalar& bound,
00213 int baseGNI)
00214 : ReductionFunctorBase<Scalar>(comm), max_(),
00215 bound_(bound), baseGNI_(baseGNI)
00216 {
00217 max_.what = -HUGE_VAL;
00218 max_.where = -1;
00219 }
00220
00221
00222 void step(int i, const Scalar& x) const
00223 {
00224 if (x > max_.what && x < bound_)
00225 {
00226 max_.what = x;
00227 max_.where = i;
00228 }
00229 }
00230
00231
00232 void postProc() const
00233 {
00234 max_.where += baseGNI_;
00235
00236 IndexedValue<Scalar> out = max_;
00237
00238 this->comm().allReduce(&max_, &out, 1, MPIDataType::doubleIntPairType(),
00239 MPIOp::minlocOp());
00240 max_ = out;
00241 }
00242
00243
00244 IndexedValue<Scalar> result() const
00245 {
00246 return max_;
00247 }
00248
00249
00250 std::string description() const {return "MinLoc()";}
00251
00252 private:
00253 MPIComm comm_;
00254 mutable IndexedValue<Scalar> max_;
00255 Scalar bound_;
00256 int baseGNI_;
00257 };
00258
00259
00260
00261
00262 template <class Scalar>
00263 class Norm2Dist : public ReductionFunctorBase<Scalar>
00264 {
00265 public:
00266 Norm2Dist(const MPIComm& comm)
00267 : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00268
00269 void step(int i, const Scalar& x, const Scalar& y) const
00270 {
00271 Scalar d = x-y;
00272 val_ += d*d;
00273 }
00274
00275 void postProc() const
00276 {
00277 Scalar final = val_;
00278 this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::sumOp());
00279 val_ = final;
00280 }
00281
00282 Scalar result() const
00283 {
00284 return ::sqrt(val_);
00285 }
00286
00287
00288 std::string description() const {return "Norm2Dist()";}
00289
00290 private:
00291 mutable Scalar val_;
00292 };
00293
00294
00295
00296
00297 template <class Scalar>
00298 class Norm1Dist : public ReductionFunctorBase<Scalar>
00299 {
00300 public:
00301 Norm1Dist(const MPIComm& comm)
00302 : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00303
00304 void step(int i, const Scalar& x, const Scalar& y) const
00305 {
00306 Scalar d = x-y;
00307 val_ += ::fabs(d);
00308 }
00309
00310 void postProc() const
00311 {
00312 Scalar final = val_;
00313 this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::sumOp());
00314 val_ = final;
00315 }
00316
00317 Scalar result() const
00318 {
00319 return val_;
00320 }
00321
00322
00323 std::string description() const {return "Norm1Dist()";}
00324
00325 private:
00326 mutable Scalar val_;
00327 };
00328
00329
00330 template <class Scalar>
00331 class NormInfDist : public ReductionFunctorBase<Scalar>
00332 {
00333 public:
00334 NormInfDist(const MPIComm& comm)
00335 : ReductionFunctorBase<Scalar>(comm), val_(0.0) {}
00336
00337 void step(int i, const Scalar& x, const Scalar& y) const
00338 {
00339 Scalar d = ::fabs(x-y);
00340 if (d > val_) val_ = d;
00341 }
00342
00343 void postProc() const
00344 {
00345 Scalar final = val_;
00346 this->comm().allReduce(&val_, &final, 1, MPIDataType::doubleType(), MPIOp::maxOp());
00347 val_ = final;
00348 }
00349
00350 Scalar result() const
00351 {
00352 return val_;
00353 }
00354
00355
00356 std::string description() const {return "NormInfDist()";}
00357
00358 private:
00359 mutable Scalar val_;
00360 };
00361
00362
00363
00364 template <class Scalar>
00365 class VectorFunctorTraits<Scalar, BoundedMinLocFunctor<Scalar> >
00366 {
00367 public:
00368 typedef IndexedValue<Scalar> ReturnType ;
00369 };
00370
00371
00372
00373 template <class Scalar>
00374 class VectorFunctorTraits<Scalar, BoundedMaxLocFunctor<Scalar> >
00375 {
00376 public:
00377 typedef IndexedValue<Scalar> ReturnType ;
00378 };
00379
00380
00381 }
00382
00383 #endif