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_VECTORIMPL_HPP
00043 #define PLAYA_VECTORIMPL_HPP
00044
00045
00046 #include "PlayaVectorDecl.hpp"
00047 #include "PlayaBlockVectorBaseDecl.hpp"
00048 #include "PlayaVectorFunctorsImpl.hpp"
00049 #include "PlayaSingleChunkVector.hpp"
00050 #include "PlayaLoadableVector.hpp"
00051 #include "PlayaPrintable.hpp"
00052 #include "PlayaExceptions.hpp"
00053 #include "PlayaGeneralizedIndex.hpp"
00054 #include "PlayaOut.hpp"
00055 #include "Teuchos_StrUtils.hpp"
00056 #include "PlayaTabs.hpp"
00057 #include "PlayaDebug.hpp"
00058
00059 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00060 #include "PlayaVectorSpaceImpl.hpp"
00061 #include "PlayaBlockIteratorImpl.hpp"
00062 #endif
00063
00064
00065
00066 extern "C"
00067 {
00068 void daxpy_(int*, double*, double*, int*, double*, int*);
00069 }
00070
00071
00072 namespace Playa
00073 {
00074 using Playa::Out;
00075 using Playa::Tabs;
00076 using Playa::Printable;
00077
00078
00079
00080
00081
00082 template <class Scalar>
00083 Vector<Scalar>& Vector<Scalar>::operator+=(const Vector<Scalar>& other)
00084 {
00085 return update(1.0, other, 1.0);
00086 }
00087
00088
00089
00090
00091 template <class Scalar>
00092 Vector<Scalar>& Vector<Scalar>::operator-=(const Vector<Scalar>& other)
00093 {
00094 return update(-1.0, other, 1.0);
00095 }
00096
00097
00098
00099 template <class Scalar>
00100 Vector<Scalar>& Vector<Scalar>::operator*=(const Scalar& a)
00101 {
00102 return scale(a);
00103 }
00104
00105
00106 template <class Scalar>
00107 Vector<Scalar>& Vector<Scalar>::operator/=(const Scalar& a)
00108 {
00109 return scale(1.0/a);
00110 }
00111
00112
00113
00114 template <class Scalar>
00115 int Vector<Scalar>::numBlocks() const
00116 {
00117 return this->ptr()->numBlocks();
00118 }
00119
00120
00121
00122 template <class Scalar>
00123 void Vector<Scalar>::setBlock(int i, const Vector<Scalar>& v)
00124 {
00125 BlockVectorBase<Scalar>* bv =
00126 dynamic_cast<BlockVectorBase<Scalar>* >(this->ptr().get());
00127 TEUCHOS_TEST_FOR_EXCEPTION(bv == 0, std::runtime_error,
00128 "setBlock() called on a vector is not a block vector");
00129 bv->setBlock(i, v);
00130 }
00131
00132
00133
00134 template <class Scalar>
00135 const Vector<Scalar>& Vector<Scalar>::getBlock(int i) const
00136 {
00137 const BlockVectorBase<Scalar>* bv =
00138 dynamic_cast<const BlockVectorBase<Scalar>* >(this->ptr().get());
00139 if (bv==0 && numBlocks()==1) return *this;
00140
00141 TEUCHOS_TEST_FOR_EXCEPTION(bv == 0, std::runtime_error,
00142 "getBlock() called on a vector is not a block vector");
00143 return bv->getBlock(i);
00144 }
00145
00146
00147 template <class Scalar>
00148 Vector<Scalar> Vector<Scalar>::getNonConstBlock(int i)
00149 {
00150 BlockVectorBase<Scalar>* bv =
00151 dynamic_cast<BlockVectorBase<Scalar>* >(this->ptr().get());
00152 if (bv==0 && numBlocks()==1) return *this;
00153
00154 TEUCHOS_TEST_FOR_EXCEPTION(bv == 0, std::runtime_error,
00155 "getBlock() called on a vector is not a block vector");
00156 return bv->getNonConstBlock(i);
00157 }
00158
00159
00160
00161 template <class Scalar> inline
00162 const Vector<Scalar>& Vector<Scalar>
00163 ::getBlock(const BlockIterator<Scalar>& b) const
00164 {
00165
00166 TEUCHOS_TEST_FOR_EXCEPTION(b.atEnd(), RuntimeError,
00167 "Attempt to use a block iterator that's run off end");
00168
00169 return this->getBlock(b.blockIndex());
00170 }
00171
00172
00173
00174
00175 template <class Scalar> inline
00176 Vector<Scalar> Vector<Scalar>
00177 ::getNonConstBlock(const BlockIterator<Scalar>& b)
00178 {
00179
00180 TEUCHOS_TEST_FOR_EXCEPTION(b.atEnd(), RuntimeError,
00181 "Attempt to use a block iterator that's run off end");
00182
00183 return this->getNonConstBlock(b.blockIndex());
00184 }
00185
00186
00187
00188 template <class Scalar> inline
00189 const Vector<Scalar>& Vector<Scalar>
00190 ::getBlock(const std::deque<int>& b) const
00191 {
00192
00193 TEUCHOS_TEST_FOR_EXCEPTION(b.size()==0, RuntimeError,
00194 "Attempt to use an empty block iterator");
00195
00196 if (b.size()==1)
00197 {
00198 return this->getBlock(b.front());
00199 }
00200
00201 int b0 = b.front();
00202 std::deque<int> tmp = b;
00203 tmp.pop_front();
00204 return this->getBlock(b0).getBlock(tmp);
00205 }
00206
00207
00208 template <class Scalar> inline
00209 Vector<Scalar> Vector<Scalar>
00210 ::getNonConstBlock(const std::deque<int>& b)
00211 {
00212
00213 TEUCHOS_TEST_FOR_EXCEPTION(b.size()==0, RuntimeError,
00214 "Attempt to use an empty block iterator");
00215
00216 if (b.size()==1)
00217 {
00218 return this->getNonConstBlock(b.front());
00219 }
00220
00221 int b0 = b.front();
00222 std::deque<int> tmp = b;
00223 tmp.pop_front();
00224 return this->getNonConstBlock(b0).getNonConstBlock(tmp);
00225 }
00226
00227
00228 template <class Scalar>
00229 ConstDataChunk<Scalar> Vector<Scalar>::nextConstChunk() const
00230 {
00231 return this->ptr()->nextConstChunk();
00232 }
00233
00234
00235 template <class Scalar>
00236 NonConstDataChunk<Scalar> Vector<Scalar>::nextChunk()
00237 {
00238 return this->ptr()->nextChunk();
00239 }
00240
00241
00242
00243 template <class Scalar>
00244 bool Vector<Scalar>::hasMoreChunks() const
00245 {
00246 return this->ptr()->hasMoreChunks();
00247 }
00248
00249
00250 template <class Scalar>
00251 void Vector<Scalar>::rewind() const
00252 {
00253 return this->ptr()->rewind();
00254 }
00255
00256
00257
00258
00259
00260 template <class Scalar>
00261 void Vector<Scalar>::print(std::ostream& os) const
00262 {
00263 const Printable* p =
00264 dynamic_cast<const Printable* >(this->ptr().get());
00265 if (false && p != 0)
00266 {
00267 p->print(os);
00268 return;
00269 }
00270 else
00271 {
00272 Tabs tab(0);
00273 int np = this->comm().getNProc();
00274 int rank = this->comm().getRank();
00275 if (rank==0)
00276 {
00277 os << tab << this->description() << std::endl;
00278 }
00279 this->comm().synchronize();
00280
00281 os << tab << "rank= " << std::setw(10) << rank << " base GNI="
00282 << std::setw(10) << this->space().baseGlobalNaturalIndex()
00283 << " local size=" << std::setw(10)
00284 << this->space().numLocalElements() << std::endl;
00285 for (BlockIterator<Scalar> b=this->space().beginBlock();
00286 b!=this->space().endBlock(); b++)
00287 {
00288 Tabs tab1;
00289 this->comm().synchronize();
00290 if (rank==0 && this->numBlocks()>1)
00291 os << tab1 << "Block=" << b << std::endl;
00292 for (int r=0; r<np; r++)
00293 {
00294 Tabs tab2;
00295 this->comm().synchronize();
00296 if (rank != r) continue;
00297 if (np > 1) os << tab2 << "Processor=" << r << std::endl;
00298
00299 const Vector<Scalar>& xBlock = this->getBlock(b);
00300 os << tab2 << "rank= " << rank << " base GNI="
00301 << xBlock.space().baseGlobalNaturalIndex() << std::endl;
00302
00303 int low = xBlock.space().baseGlobalNaturalIndex();
00304 while(xBlock.hasMoreChunks())
00305 {
00306 Tabs tab3;
00307 ConstDataChunk<Scalar> myChunk = xBlock.nextConstChunk();
00308 const Scalar* me = myChunk.values();
00309 for (int i=0; i<myChunk.size(); i++)
00310 {
00311 os << tab3 << std::setw(10) << low+i << " " << std::setw(20)
00312 << me[i] << std::endl;
00313 }
00314 }
00315 for(int i=0; i<6; i++)
00316 {
00317 this->comm().synchronize();
00318 }
00319 }
00320 }
00321
00322 this->rewind();
00323 }
00324 }
00325
00326 template <class Scalar>
00327 std::string Vector<Scalar>::description() const
00328 {
00329 const Describable* d =
00330 dynamic_cast<const Describable* >(this->ptr().get());
00331 if (d != 0)
00332 {
00333 return d->description();
00334 }
00335 return "Vector[type=unknown, dim=" + Teuchos::toString(dim()) + "]";
00336 }
00337
00338
00339
00340
00341
00342 template <class Scalar>
00343 template <class UF> inline
00344 Vector<Scalar>& Vector<Scalar>::applyUnaryFunctor(const UF& func)
00345 {
00346 TimeMonitor t(*opTimer());
00347
00348 if (this->numBlocks() > 1)
00349 {
00350 for (int b=0; b<numBlocks(); b++)
00351 {
00352 Vector<Scalar> xBlock = this->getNonConstBlock(b);
00353 xBlock.applyUnaryFunctor(func);
00354 }
00355 }
00356 else
00357 {
00358 while(this->hasMoreChunks())
00359 {
00360 NonConstDataChunk<Scalar> myChunk = this->nextChunk();
00361 Scalar* me = myChunk.values();
00362 for (int i=0; i<myChunk.size(); i++)
00363 {
00364 me[i] = func(me[i]);
00365 }
00366 }
00367 }
00368
00369 this->rewind();
00370
00371 return *this;
00372 }
00373
00374
00375
00376 template <class Scalar>
00377 template <class UF> inline
00378 Vector<Scalar>& Vector<Scalar>::acceptUnaryFunctor(const UF& func,
00379 const Vector<Scalar>& other)
00380 {
00381 TimeMonitor t(*opTimer());
00382
00383 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(other.space()),
00384 std::runtime_error,
00385 "Spaces this=" << this->space() << " and other="
00386 << other.space() << " are not compatible in unary accept-operation "
00387 << func.description());
00388
00389 if (this->numBlocks() > 1)
00390 {
00391 for (int b=0; b<this->numBlocks(); b++)
00392 {
00393 Vector<Scalar> myBlock = this->getNonConstBlock(b);
00394 Vector<Scalar> yourBlock = other.getBlock(b);
00395 myBlock.acceptUnaryFunctor(func, yourBlock);
00396 }
00397 }
00398 else
00399 {
00400 while(this->hasMoreChunks())
00401 {
00402 NonConstDataChunk<Scalar> myChunk = this->nextChunk();
00403 ConstDataChunk<Scalar> yourChunk = other.nextConstChunk();
00404 Scalar* me = myChunk.values();
00405 const Scalar* you = yourChunk.values();
00406 for (int i=0; i<myChunk.size(); i++)
00407 {
00408 me[i] = func(you[i]);
00409 }
00410 }
00411 other.rewind();
00412 this->rewind();
00413 }
00414
00415 return *this;
00416 }
00417
00418
00419
00420 template <class Scalar>
00421 template <class VF> inline
00422 Vector<Scalar>& Vector<Scalar>::applyBinaryFunctor(const VF& func,
00423 const Vector<Scalar>& other)
00424 {
00425 TimeMonitor t(*opTimer());
00426
00427 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(other.space()),
00428 std::runtime_error,
00429 "Spaces this=" << this->space() << " and other="
00430 << other.space() << " are not compatible in binary operation "
00431 << func.description());
00432
00433 if (this->numBlocks() > 1)
00434 {
00435 for (int b=0; b<this->numBlocks(); b++)
00436 {
00437 Vector<Scalar> myBlock = this->getNonConstBlock(b);
00438 Vector<Scalar> yourBlock = other.getBlock(b);
00439 myBlock.applyBinaryFunctor(func, yourBlock);
00440 }
00441 }
00442 else
00443 {
00444 while(this->hasMoreChunks())
00445 {
00446 NonConstDataChunk<Scalar> myChunk = this->nextChunk();
00447 ConstDataChunk<Scalar> yourChunk = other.nextConstChunk();
00448 Scalar* me = myChunk.values();
00449 const Scalar* you = yourChunk.values();
00450 for (int i=0; i<myChunk.size(); i++)
00451 {
00452 me[i] = func(me[i], you[i]);
00453 }
00454 }
00455 other.rewind();
00456 this->rewind();
00457 }
00458
00459 return *this;
00460 }
00461
00462
00463 template <class Scalar>
00464 template <class VF> inline
00465 Vector<Scalar>& Vector<Scalar>::applyTernaryFunctor(
00466 const VF& func,
00467 const Vector<Scalar>& y,
00468 const Vector<Scalar>& z)
00469 {
00470 TimeMonitor t(*opTimer());
00471
00472 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(y.space())
00473 || !this->space().isCompatible(z.space()),
00474 std::runtime_error,
00475 "Spaces this=" << this->space() << ", Y="
00476 << y.space() << " and Z=" << z.space()
00477 << " are not compatible in ternary operation "
00478 << func.description());
00479
00480 if (this->numBlocks() > 1)
00481 {
00482 for (int b=0; b<this->numBlocks(); b++)
00483 {
00484 Vector<Scalar> xBlock = this->getNonConstBlock(b);
00485 Vector<Scalar> yBlock = y.getBlock(b);
00486 Vector<Scalar> zBlock = z.getBlock(b);
00487 xBlock.applyTernaryFunctor(func, yBlock, zBlock);
00488 }
00489 }
00490 else
00491 {
00492 while(this->hasMoreChunks())
00493 {
00494 NonConstDataChunk<Scalar> xChunk = this->nextChunk();
00495 ConstDataChunk<Scalar> yChunk = y.nextConstChunk();
00496 ConstDataChunk<Scalar> zChunk = z.nextConstChunk();
00497 Scalar* xv = xChunk.values();
00498 const Scalar* yv = yChunk.values();
00499 const Scalar* zv = zChunk.values();
00500 for (int i=0; i<xChunk.size(); i++)
00501 {
00502 xv[i] = func(xv[i], yv[i], zv[i]);
00503 }
00504 }
00505 this->rewind();
00506 y.rewind();
00507 z.rewind();
00508 }
00509 return *this;
00510 }
00511
00512
00513
00514
00515
00516 template <class Scalar>
00517 template <class RF> inline
00518 typename PlayaFunctors::VectorFunctorTraits<Scalar, RF>::ReturnType
00519 Vector<Scalar>::applyUnaryReductionFunctor(const RF& func) const
00520 {
00521 TimeMonitor t(*opTimer());
00522
00523 for (BlockIterator<Scalar> b=this->space().beginBlock(); b!=this->space().endBlock(); b++)
00524 {
00525 Vector<Scalar> xBlock = this->getBlock(b);
00526 while(xBlock.hasMoreChunks())
00527 {
00528 ConstDataChunk<Scalar> myChunk = xBlock.nextConstChunk();
00529 const Scalar* me = myChunk.values();
00530 for (int i=0; i<myChunk.size(); i++)
00531 {
00532 func.step(i, me[i]);
00533 }
00534 }
00535 }
00536
00537 func.postProc();
00538 this->rewind();
00539
00540 return func.result();
00541 }
00542
00543
00544
00545
00546 template <class Scalar>
00547 template <class RF> inline
00548 typename PlayaFunctors::VectorFunctorTraits<Scalar, RF>::ReturnType
00549 Vector<Scalar>::applyBinaryReductionFunctor(const RF& func, const Vector<Scalar>& y) const
00550 {
00551 TimeMonitor t(*opTimer());
00552
00553 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(y.space()),
00554 std::runtime_error,
00555 "Spaces this=" << this->space() << " and other="
00556 << y.space() << " are not compatible in binary reduction operation "
00557 << func.description());
00558
00559 for (BlockIterator<Scalar> b=this->space().beginBlock(); b!=this->space().endBlock(); b++)
00560 {
00561 Vector<Scalar> xBlock = this->getBlock(b);
00562 Vector<Scalar> yBlock = y.getBlock(b);
00563 while(xBlock.hasMoreChunks())
00564 {
00565 ConstDataChunk<Scalar> xChunk = xBlock.nextConstChunk();
00566 ConstDataChunk<Scalar> yChunk = yBlock.nextConstChunk();
00567 const Scalar* me = xChunk.values();
00568 const Scalar* you = yChunk.values();
00569 for (int i=0; i<xChunk.size(); i++)
00570 {
00571 func.step(i, me[i], you[i]);
00572 }
00573 }
00574 }
00575
00576 func.postProc();
00577 this->rewind();
00578 y.rewind();
00579
00580 return func.result();
00581 }
00582
00583
00584
00585 template <class Scalar> inline
00586 Vector<Scalar>& Vector<Scalar>::scale(const Scalar& alpha)
00587 {
00588 return applyUnaryFunctor(PlayaFunctors::ScalarMult<Scalar>(alpha));
00589 }
00590
00591
00592 template <class Scalar> inline
00593 Vector<Scalar>& Vector<Scalar>::selfReciprocal()
00594 {
00595 return applyUnaryFunctor(PlayaFunctors::Reciprocal<Scalar>());
00596 }
00597
00598
00599
00600 template <class Scalar> inline
00601 Vector<Scalar>& Vector<Scalar>::selfAbs()
00602 {
00603 return applyUnaryFunctor(PlayaFunctors::Abs<Scalar>());
00604 }
00605
00606
00607
00608 template <class Scalar> inline
00609 Vector<Scalar>& Vector<Scalar>::randomize()
00610 {
00611 return applyUnaryFunctor(PlayaFunctors::Random<Scalar>());
00612 }
00613
00614
00615
00616 template <class Scalar> inline
00617 Vector<Scalar>& Vector<Scalar>::update(const Scalar& alpha,
00618 const Vector<Scalar>& other, const Scalar& gamma)
00619 {
00620 this->ptr()->update(alpha, other.ptr().get(), gamma);
00621 return *this;
00622 }
00623
00624
00625
00626 template <class Scalar> inline
00627 Vector<Scalar>& Vector<Scalar>::acceptCopyOf(const Vector<Scalar>& x)
00628 {
00629 if (this->ptr().get()==0 || !this->space().isCompatible(x.space()) )
00630 {
00631 this->ptr() = x.space().createMember().ptr();
00632 }
00633 return acceptUnaryFunctor(PlayaFunctors::Identity<Scalar>(), x);
00634 }
00635
00636 template <class Scalar> inline
00637 Vector<Scalar> Vector<Scalar>::copy() const
00638 {
00639 Vector<Scalar> rtn = space().createMember();
00640 rtn.acceptCopyOf(*this);
00641 return rtn;
00642 }
00643
00644
00645
00646
00647 template <class Scalar> inline
00648 Vector<Scalar>& Vector<Scalar>::selfDotStar(const Vector<Scalar>& other)
00649 {
00650 return applyBinaryFunctor(PlayaFunctors::DotStar<Scalar>(), other);
00651 }
00652
00653
00654 template <class Scalar> inline
00655 Vector<Scalar>& Vector<Scalar>::selfDotSlash(const Vector<Scalar>& other)
00656 {
00657 return applyBinaryFunctor(PlayaFunctors::DotSlash<Scalar>(), other);
00658 }
00659
00660
00661
00662 template <class Scalar> inline
00663 Vector<Scalar> Vector<Scalar>::dotStar(const Vector<Scalar>& other) const
00664 {
00665 Vector<Scalar> rtn = space().createMember();
00666 rtn.acceptCopyOf(*this);
00667 rtn.selfDotStar(other);
00668 return rtn;
00669 }
00670
00671
00672 template <class Scalar> inline
00673 Vector<Scalar> Vector<Scalar>::dotSlash(const Vector<Scalar>& other) const
00674 {
00675 Vector<Scalar> rtn = space().createMember();
00676 rtn.acceptCopyOf(*this);
00677 rtn.selfDotSlash(other);
00678 return rtn;
00679 }
00680
00681
00682
00683 template <class Scalar> inline
00684 Vector<Scalar> Vector<Scalar>::abs() const
00685 {
00686 Vector<Scalar> rtn = space().createMember();
00687 rtn.acceptCopyOf(*this);
00688 rtn.selfAbs();
00689 return rtn;
00690 }
00691
00692
00693
00694
00695
00696
00697 template <class Scalar> inline
00698 Vector<Scalar> Vector<Scalar>::reciprocal() const
00699 {
00700 Vector<Scalar> rtn = space().createMember();
00701 rtn.acceptCopyOf(*this);
00702 rtn.selfReciprocal();
00703 return rtn;
00704 }
00705
00706
00707
00708
00709 template <class Scalar> inline
00710 Vector<Scalar>& Vector<Scalar>::update(const Scalar& alpha,
00711 const Vector<Scalar>& x,
00712 const Scalar& beta,
00713 const Vector<Scalar>& y,
00714 const Scalar& gamma)
00715 {
00716 this->ptr()->update(alpha, x.ptr().get(), beta, y.ptr().get(), gamma);
00717 return *this;
00718 }
00719
00720
00721
00722 template <class Scalar> inline
00723 Vector<Scalar>& Vector<Scalar>::update(const Scalar& alpha,
00724 const Vector<Scalar>& x,
00725 const Scalar& beta,
00726 const Vector<Scalar>& y,
00727 const Scalar& gamma,
00728 const Vector<Scalar>& z,
00729 const Scalar& delta)
00730 {
00731 this->ptr()->update(alpha, x.ptr().get(), beta, y.ptr().get(),
00732 gamma, z.ptr().get(), delta);
00733 return *this;
00734 }
00735
00736
00737
00738
00739 template <class Scalar> inline
00740 Scalar Vector<Scalar>::dot(const Vector<Scalar>& other) const
00741 {
00742 PLAYA_CHECK_SPACES(this->space(), other.space());
00743 return this->ptr()->dot(other.ptr().get());
00744 }
00745
00746
00747
00748 template <class Scalar> inline
00749 Scalar Vector<Scalar>::operator*(const Vector<Scalar>& other) const
00750 {
00751 PLAYA_CHECK_SPACES(this->space(), other.space());
00752 return this->ptr()->dot(other.ptr().get());
00753 }
00754
00755
00756
00757
00758
00759 template <class Scalar> inline
00760 Scalar Vector<Scalar>::norm1() const
00761 {
00762 return applyUnaryReductionFunctor(PlayaFunctors::Norm1<Scalar>(this->comm()));
00763 }
00764
00765
00766
00767
00768
00769 template <class Scalar> inline
00770 Scalar Vector<Scalar>::norm2() const
00771 {
00772 return this->ptr()->norm2();
00773 }
00774
00775
00776
00777
00778
00779 template <class Scalar> inline
00780 Scalar Vector<Scalar>::norm2(const Vector<Scalar>& weights) const
00781 {
00782 return applyBinaryReductionFunctor(PlayaFunctors::WeightedNorm2<Scalar>(this->comm()), weights);
00783 }
00784
00785
00786
00787
00788
00789
00790 template <class Scalar> inline
00791 Scalar Vector<Scalar>::normInf() const
00792 {
00793 return applyUnaryReductionFunctor(PlayaFunctors::NormInf<Scalar>(this->comm()));
00794 }
00795
00796
00797
00798
00799
00800 template <class Scalar> inline
00801 void Vector<Scalar>::zero()
00802 {
00803 setToConstant(0.0);
00804 }
00805
00806
00807
00808
00809
00810 template <class Scalar> inline
00811 void Vector<Scalar>::setToConstant(const Scalar& alpha)
00812 {
00813 applyUnaryFunctor(PlayaFunctors::SetConstant<Scalar>(alpha));
00814 }
00815
00816
00817
00818 template <class Scalar> inline
00819 Scalar Vector<Scalar>::max()const
00820 {
00821 return applyUnaryReductionFunctor(PlayaFunctors::Max<Scalar>(this->comm()));
00822 }
00823
00824
00825
00826 template <class Scalar> inline
00827 Scalar Vector<Scalar>::min()const
00828 {
00829 return applyUnaryReductionFunctor(PlayaFunctors::Min<Scalar>(this->comm()));
00830 }
00831
00832
00833
00834
00835 template <class Scalar> inline
00836 const Scalar& Vector<Scalar>::operator[](int localIndex) const
00837 {
00838 const SingleChunkVector<Scalar>* scv
00839 = dynamic_cast<const SingleChunkVector<Scalar>* >(this->ptr().get());
00840
00841 if (scv)
00842 {
00843 if (Debug::on)
00844 {
00845 PLAYA_BOUNDSCHECK(localIndex, 0, scv->chunkSize(),
00846 "const Vector::operator[]()");
00847 }
00848 return scv->dataPtr()[localIndex];
00849 }
00850
00851 int chunkBase = 0;
00852 while(this->ptr()->hasMoreChunks())
00853 {
00854 ConstDataChunk<Scalar> chunk = this->nextConstChunk();
00855 int chunkSize = chunk.size();
00856 if (localIndex >= chunkBase && localIndex < chunkBase+chunkSize)
00857 {
00858 this->ptr()->rewind();
00859 return chunk.values()[localIndex-chunkBase];
00860 }
00861 chunkBase += chunkSize;
00862 }
00863
00864 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00865 "Vector operator[] local index "
00866 << localIndex << " out of range [0, " << chunkBase << ")");
00867
00868 return scv->dataPtr()[0];
00869 }
00870
00871
00872
00873 template <class Scalar> inline
00874 Scalar& Vector<Scalar>::operator[](int localIndex)
00875 {
00876 SingleChunkVector<Scalar>* scv
00877 = dynamic_cast<SingleChunkVector<Scalar>* >(this->ptr().get());
00878
00879 if (scv)
00880 {
00881 if (Debug::on)
00882 {
00883 PLAYA_BOUNDSCHECK(localIndex, 0, scv->chunkSize(),
00884 "non-const Vector::operator[]()");
00885 }
00886 return scv->dataPtr()[localIndex];
00887 }
00888
00889 int chunkBase = 0;
00890 while(this->ptr()->hasMoreChunks())
00891 {
00892 NonConstDataChunk<Scalar> chunk = this->nextChunk();
00893 int chunkSize = chunk.size();
00894 if (localIndex >= chunkBase && localIndex < chunkBase+chunkSize)
00895 {
00896 this->ptr()->rewind();
00897 return chunk.values()[localIndex-chunkBase];
00898 }
00899 chunkBase += chunkSize;
00900 }
00901
00902 TEUCHOS_TEST_FOR_EXCEPTION(true, std::runtime_error,
00903 "Vector operator[] local index "
00904 << localIndex << " out of range [0, " << chunkBase << ")");
00905
00906 return scv->dataPtr()[0];
00907 }
00908
00909
00910
00911 template <class Scalar> inline
00912 const Scalar& Vector<Scalar>::operator()(const BlockIterator<Scalar>& b,
00913 int localIndexWithinBlock) const
00914 {
00915 return this->getBlock(b)[localIndexWithinBlock];
00916 }
00917
00918
00919
00920
00921 template <class Scalar> inline
00922 Scalar& Vector<Scalar>::operator()(const BlockIterator<Scalar>& b,
00923 int localIndexWithinBlock)
00924 {
00925 return this->getNonConstBlock(b)[localIndexWithinBlock];
00926 }
00927
00928
00929
00930
00931 template <class Scalar> inline
00932 Scalar* dataPtr(Vector<Scalar> vec)
00933 {
00934 SingleChunkVector<Scalar>* v
00935 = dynamic_cast<SingleChunkVector<Scalar>* >(vec.ptr().get());
00936 TEUCHOS_TEST_FOR_EXCEPT(v==0);
00937 return v->dataPtr();
00938 }
00939
00940
00941
00942
00943 template <class Scalar> inline
00944 const Scalar* dataPtr(const Vector<Scalar>& vec)
00945 {
00946 const SingleChunkVector<Scalar>* v
00947 = dynamic_cast<const SingleChunkVector<Scalar>* >(vec.ptr().get());
00948 TEUCHOS_TEST_FOR_EXCEPT(v==0);
00949 return v->dataPtr();
00950 }
00951
00952
00953
00954 template <class Scalar> inline
00955 LoadableVector<Scalar>* loadable(Vector<Scalar> vec)
00956 {
00957 LoadableVector<Scalar>* lv
00958 = dynamic_cast<LoadableVector<Scalar>* >(vec.ptr().get());
00959 TEUCHOS_TEST_FOR_EXCEPT(lv==0);
00960 return lv;
00961 }
00962
00963 }
00964
00965
00966
00967
00968 #endif