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_LINEARCOMBINATIONIMPL_HPP
00043 #define PLAYA_LINEARCOMBINATIONIMPL_HPP
00044
00045 #include "PlayaDefs.hpp"
00046 #include "PlayaOut.hpp"
00047 #include "PlayaTabs.hpp"
00048 #include "PlayaLinearCombinationDecl.hpp"
00049 #include "PlayaLinearOperatorDecl.hpp"
00050 #include "Teuchos_ScalarTraits.hpp"
00051
00052
00053 #ifndef HAVE_TEUCHOS_EXPLICIT_INSTANTIATION
00054 #include "PlayaVectorImpl.hpp"
00055 #include "PlayaLinearOperatorImpl.hpp"
00056 #include "PlayaSimpleTransposedOpImpl.hpp"
00057 #endif
00058
00059
00060 namespace Playa
00061 {
00062
00063 using Playa::Out;
00064 using Playa::Tabs;
00065 using std::endl;
00066
00067
00068
00069
00070
00071
00072 template <class Scalar>
00073 template <int N>
00074 inline
00075 Vector<Scalar>::Vector(const LCN<Scalar, N>& x)
00076 : Playa::Handle<VectorBase<Scalar> >()
00077 {
00078 this->ptr() = x.eval().ptr();
00079 }
00080
00081
00082
00083
00084
00085 template <class Scalar> inline
00086 Vector<Scalar>& Vector<Scalar>::operator=(const LCN<Scalar, 1>& lc)
00087 {
00088 const Vector<Scalar>& other = lc.vec(0);
00089 const Scalar& alpha = lc.coeff(0);
00090 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
00091 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00092
00093 if (this->ptr().get() == other.ptr().get())
00094 {
00095
00096
00097 if (alpha == zero) this->zero();
00098 else if (alpha != one) this->scale(alpha);
00099 }
00100 else if (this->ptr().get() != 0 && this->space() == other.space())
00101 {
00102
00103
00104 this->ptr()->update(alpha, other.ptr().get(), zero);
00105 }
00106 else
00107 {
00108
00109
00110 Vector<Scalar> cp = other.copy();
00111 this->ptr() = cp.ptr();
00112 this->scale(alpha);
00113
00114 }
00115 return *this;
00116 }
00117
00118
00119 template <class Scalar> inline
00120 Vector<Scalar>& Vector<Scalar>::operator=(const LCN<Scalar, 2>& lc)
00121 {
00122 const Vector<Scalar>& x = lc.vec(0);
00123 const Scalar& alpha = lc.coeff(0);
00124 const Vector<Scalar>& y = lc.vec(1);
00125 const Scalar& beta = lc.coeff(1);
00126 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
00127
00128
00129 TEUCHOS_TEST_FOR_EXCEPTION(!y.space().isCompatible(x.space()),
00130 std::runtime_error,
00131 "Spaces x=" << x.space() << " and y="
00132 << y.space() << " are not compatible in operator=(a*x + b*y)");
00133
00134 if (this->ptr().get() != 0 && this->space() == x.space())
00135 {
00136
00137
00138
00139
00140 this->update(alpha, x, beta, y, zero);
00141 }
00142 else
00143 {
00144
00145
00146 Vector<Scalar> e = lc.eval();
00147 this->ptr() = e.ptr();
00148 }
00149
00150 return *this;
00151 }
00152
00153 template <class Scalar> inline
00154 Vector<Scalar>& Vector<Scalar>::operator=(const LCN<Scalar, 3>& lc)
00155 {
00156 const Vector<Scalar>& x = lc.vec(0);
00157 const Scalar& alpha = lc.coeff(0);
00158 const Vector<Scalar>& y = lc.vec(1);
00159 const Scalar& beta = lc.coeff(1);
00160 const Vector<Scalar>& z = lc.vec(2);
00161 const Scalar& gamma = lc.coeff(2);
00162 const Scalar zero = Teuchos::ScalarTraits<Scalar>::zero();
00163
00164 TEUCHOS_TEST_FOR_EXCEPTION(!y.space().isCompatible(x.space()),
00165 std::runtime_error,
00166 "Spaces x=" << x.space() << " and y="
00167 << y.space() << " are not compatible in operator=(a*x + b*y + c*z)");
00168
00169 TEUCHOS_TEST_FOR_EXCEPTION(!z.space().isCompatible(x.space()),
00170 std::runtime_error,
00171 "Spaces x=" << x.space() << " and z="
00172 << z.space() << " are not compatible in operator=(a*x + b*y + c*z)");
00173
00174 if (this->ptr().get() != 0 && this->space() == x.space())
00175 {
00176
00177
00178
00179
00180 this->update(alpha, x, beta, y, gamma, z, zero);
00181 }
00182 else
00183 {
00184
00185
00186 Vector e = lc.eval();
00187 this->ptr() = e.ptr();
00188 }
00189
00190 return *this;
00191 }
00192
00193 template <class Scalar>
00194 template <int N> inline
00195 Vector<Scalar>& Vector<Scalar>::operator=(const LCN<Scalar, N>& lc)
00196 {
00197 Vector e = lc.eval();
00198 this->ptr() = e.ptr();
00199
00200 return *this;
00201 }
00202
00203
00204
00205
00206
00207
00208
00209
00210 template <class Scalar> inline
00211 Vector<Scalar>& Vector<Scalar>::operator+=(const LCN<Scalar, 1>& lc)
00212 {
00213 const Vector<Scalar>& other = lc.vec(0);
00214 const Scalar& alpha = lc.coeff(0);
00215 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00216
00217 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(other.space()),
00218 std::runtime_error,
00219 "Spaces this=" << this->space() << " and other="
00220 << other.space() << " are not compatible in operator+=()");
00221
00222 this->ptr()->update(alpha, other.ptr().get(), one);
00223
00224 return *this;
00225 }
00226
00227
00228 template <class Scalar> inline
00229 Vector<Scalar>& Vector<Scalar>::operator+=(const LCN<Scalar, 2>& lc)
00230 {
00231 const Vector<Scalar>& x = lc.vec(0);
00232 const Scalar& alpha = lc.coeff(0);
00233 const Vector<Scalar>& y = lc.vec(1);
00234 const Scalar& beta = lc.coeff(1);
00235 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00236
00237 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(x.space()),
00238 std::runtime_error,
00239 "Spaces this=" << this->space() << " and other="
00240 << x.space() << " are not compatible in operator+=()");
00241
00242 this->update(alpha, x, beta, y, one);
00243
00244 return *this;
00245 }
00246
00247
00248 template <class Scalar>
00249 template <int N> inline
00250 Vector<Scalar>& Vector<Scalar>::operator+=(const LCN<Scalar, N>& lc)
00251 {
00252 Vector<Scalar> e = lc.eval();
00253 *this += e;
00254 return *this;
00255 }
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265 template <class Scalar> inline
00266 Vector<Scalar>& Vector<Scalar>::operator-=(const LCN<Scalar, 1>& lc)
00267 {
00268 const Vector<Scalar>& other = lc.vec(0);
00269 const Scalar& alpha = -lc.coeff(0);
00270 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00271
00272 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(other.space()),
00273 std::runtime_error,
00274 "Spaces this=" << this->space() << " and other="
00275 << other.space() << " are not compatible in operator+=()");
00276
00277 this->ptr()->update(alpha, other.ptr().get(), one);
00278
00279 return *this;
00280 }
00281
00282
00283 template <class Scalar> inline
00284 Vector<Scalar>& Vector<Scalar>::operator-=(const LCN<Scalar, 2>& lc)
00285 {
00286
00287 const Vector<Scalar>& x = lc.vec(0);
00288 const Scalar& alpha = -lc.coeff(0);
00289 const Vector<Scalar>& y = lc.vec(1);
00290 const Scalar& beta = -lc.coeff(1);
00291 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00292
00293 TEUCHOS_TEST_FOR_EXCEPTION(!this->space().isCompatible(x.space()),
00294 std::runtime_error,
00295 "Spaces this=" << this->space() << " and other="
00296 << x.space() << " are not compatible in operator+=()");
00297
00298 this->update(alpha, x, beta, y, one);
00299
00300 return *this;
00301 }
00302
00303
00304 template <class Scalar>
00305 template <int N> inline
00306 Vector<Scalar>& Vector<Scalar>::operator-=(const LCN<Scalar, N>& lc)
00307 {
00308 Vector<Scalar> e = lc.eval();
00309 *this -= e;
00310
00311 return *this;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320
00321 template <class Scalar>
00322 Vector<Scalar> operator*(const LinearOperator<Scalar>& A,
00323 const Vector<Scalar>& x)
00324 {
00325 Vector<Scalar> rtn;
00326 A.apply(x, rtn);
00327 return rtn;
00328 }
00329
00330
00331
00332 template <class Scalar, int N>
00333 Vector<Scalar> operator*(const LinearOperator<Scalar>& A,
00334 const LCN<Scalar, N>& x)
00335 {
00336 return A*x.eval();
00337 }
00338
00339
00340 template <class Scalar>
00341 Vector<Scalar> operator*(const LinearOperator<Scalar>& A,
00342 const LCN<Scalar, 1>& x)
00343 {
00344 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00345 Vector<Scalar> rtn = A*x.vec(0);
00346 if (x.coeff(0)!=one) rtn.scale(x.coeff(0));
00347 return rtn;
00348 }
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 template <class Scalar> inline
00359 LCN<Scalar, 1> operator*(const Scalar& alpha,
00360 const Vector<Scalar>& x)
00361 {
00362 return LCN<Scalar, 1>(alpha, x);
00363 }
00364
00365
00366 template <class Scalar> inline
00367 LCN<Scalar, 1> operator*(const Vector<Scalar>& x,
00368 const Scalar& alpha)
00369 {
00370 return LCN<Scalar, 1>(alpha, x);
00371 }
00372
00373
00374
00375 template <class Scalar> inline
00376 LCN<Scalar, 1> operator/(const Vector<Scalar>& x,
00377 const Scalar& alpha)
00378 {
00379 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00380 return LCN<Scalar, 1>(one/alpha, x);
00381 }
00382
00383
00384
00385
00386
00387
00388
00389
00390
00391
00392 template <class Scalar, int N> inline
00393 LCN<Scalar, N> operator*(const LCN<Scalar, N>& lc, const Scalar& beta)
00394 {
00395 LCN<Scalar, N> rtn(lc);
00396 rtn.multiply(beta);
00397 return rtn;
00398 }
00399
00400
00401 template <class Scalar, int N> inline
00402 LCN<Scalar, N> operator*(const Scalar& beta, const LCN<Scalar, N>& lc)
00403 {
00404 LCN<Scalar, N> rtn(lc);
00405 rtn.multiply(beta);
00406 return rtn;
00407 }
00408
00409
00410 template <class Scalar, int N> inline
00411 LCN<Scalar, N> operator/(const LCN<Scalar, N>& lc, const Scalar& beta)
00412 {
00413 LCN<Scalar, N> rtn(lc);
00414 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00415 rtn.multiply(one/beta);
00416 return rtn;
00417 }
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427
00428
00429 template <class Scalar> inline
00430 LCN<Scalar, 2> operator+(const Vector<Scalar>& x,
00431 const Vector<Scalar>& y)
00432 {
00433 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00434 return LCN<Scalar, 2>(one, x, one, y);
00435 }
00436
00437
00438 template <class Scalar> inline
00439 LCN<Scalar, 2> operator-(const Vector<Scalar>& x,
00440 const Vector<Scalar>& y)
00441 {
00442 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00443 return LCN<Scalar, 2>(one, x, -one, y);
00444 }
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455 template <class Scalar, int N, int M> inline
00456 LCN<Scalar, N+M> operator+(const LCN<Scalar, N>& f, const LCN<Scalar, M>& g)
00457 {
00458 LCN<Scalar, N+M> rtn;
00459 for (int i=0; i<N; i++) rtn.set(i, f.coeff(i), f.vec(i));
00460 for (int i=0; i<M; i++) rtn.set(i+N, g.coeff(i), g.vec(i));
00461 return rtn;
00462 }
00463
00464
00465 template <class Scalar, int N> inline
00466 LCN<Scalar, N+1> operator+(const LCN<Scalar, N>& f, const Vector<Scalar>& g)
00467 {
00468 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00469 LCN<Scalar, N+1> rtn;
00470 for (int i=0; i<N; i++) rtn.set(i, f.coeff(i), f.vec(i));
00471 rtn.set(N, one, g);
00472 return rtn;
00473 }
00474
00475
00476 template <class Scalar, int N> inline
00477 LCN<Scalar, N+1> operator+(const Vector<Scalar>& f, const LCN<Scalar, N>& g)
00478 {
00479 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00480 LCN<Scalar, N+1> rtn;
00481 rtn.set(0, one, f);
00482 for (int i=0; i<N; i++) rtn.set(i+1, g.coeff(i), g.vec(i));
00483
00484 return rtn;
00485 }
00486
00487
00488
00489 template <class Scalar> inline
00490 LCN<Scalar, 2> operator+(const LCN<Scalar, 1>& lc, const Vector<Scalar>& x)
00491 {
00492 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00493 return LCN<Scalar, 2>(lc, one, x);
00494 }
00495
00496
00497
00498
00499 template <class Scalar> inline
00500 LCN<Scalar, 2> operator+(const Vector<Scalar>& x, const LCN<Scalar, 1>& lc)
00501 {
00502 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00503 return LCN<Scalar, 2>(one, x, lc);
00504 }
00505
00506
00507
00508 template <class Scalar> inline
00509 LCN<Scalar, 2> operator+(const LCN<Scalar, 1>& ax, const LCN<Scalar, 1>& by)
00510 {
00511 return LCN<Scalar, 2>(ax, by);
00512 }
00513
00514
00515
00516
00517 template <class Scalar> inline
00518 LCN<Scalar, 3> operator+(const LCN<Scalar, 1>& ax, const LCN<Scalar, 2>& bycz)
00519 {
00520 return LCN<Scalar, 3>(ax, bycz);
00521 }
00522
00523
00524
00525 template <class Scalar> inline
00526 LCN<Scalar, 3> operator+(const Vector<Scalar>& x, const LCN<Scalar, 2>& bycz)
00527 {
00528 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00529 return LCN<Scalar, 3>(LCN<Scalar, 1>(one, x), bycz);
00530 }
00531
00532
00533
00534
00535 template <class Scalar> inline
00536 LCN<Scalar, 3> operator+(const LCN<Scalar, 2>& axby, const LCN<Scalar, 1>& cz)
00537 {
00538 return LCN<Scalar, 3>(axby, cz);
00539 }
00540
00541
00542
00543
00544 template <class Scalar> inline
00545 LCN<Scalar, 3> operator+(const LCN<Scalar, 2>& axby, const Vector<Scalar>& z)
00546 {
00547 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00548 return LCN<Scalar, 3>(axby, LCN<Scalar,1>(one,z));
00549 }
00550
00551
00552
00553
00554
00555
00556
00557
00558
00559
00560
00561 template <class Scalar, int N, int M> inline
00562 LCN<Scalar, N+M> operator-(const LCN<Scalar, N>& f, const LCN<Scalar, M>& g)
00563 {
00564 LCN<Scalar, N+M> rtn;
00565 for (int i=0; i<N; i++) rtn.set(i, f.coeff(i), f.vec(i));
00566 for (int i=0; i<M; i++) rtn.set(i+N, -g.coeff(i), g.vec(i));
00567 return rtn;
00568 }
00569
00570
00571 template <class Scalar, int N> inline
00572 LCN<Scalar, N+1> operator-(const LCN<Scalar, N>& f, const Vector<Scalar>& g)
00573 {
00574 LCN<Scalar, N+1> rtn;
00575 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00576 for (int i=0; i<N; i++) rtn.set(i, f.coeff(i), f.vec(i));
00577 rtn.set(N, -one, g);
00578 return rtn;
00579 }
00580
00581
00582 template <class Scalar, int N> inline
00583 LCN<Scalar, N+1> operator-(const Vector<Scalar>& f, const LCN<Scalar, N>& g)
00584 {
00585 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00586 LCN<Scalar, N+1> rtn;
00587 rtn.set(0, one, f);
00588 for (int i=0; i<N; i++) rtn.set(i+1, -g.coeff(i), g.vec(i));
00589
00590 return rtn;
00591 }
00592
00593
00594
00595 template <class Scalar> inline
00596 LCN<Scalar, 2> operator-(const LCN<Scalar, 1>& lc, const Vector<Scalar>& x)
00597 {
00598 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00599 return LCN<Scalar, 2>(lc, -one, x);
00600 }
00601
00602
00603
00604
00605 template <class Scalar> inline
00606 LCN<Scalar, 2> operator-(const Vector<Scalar>& x, const LCN<Scalar, 1>& lc)
00607 {
00608 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00609 return LCN<Scalar, 2>(one, x, -lc.coeff(0), lc.vec(0));
00610 }
00611
00612
00613
00614 template <class Scalar> inline
00615 LCN<Scalar, 2> operator-(const LCN<Scalar, 1>& ax, const LCN<Scalar, 1>& by)
00616 {
00617 return LCN<Scalar, 2>(ax, -by);
00618 }
00619
00620
00621
00622
00623 template <class Scalar> inline
00624 LCN<Scalar, 3> operator-(const LCN<Scalar, 1>& ax, const LCN<Scalar, 2>& bycz)
00625 {
00626 return LCN<Scalar, 3>(ax, -bycz);
00627 }
00628
00629
00630
00631 template <class Scalar> inline
00632 LCN<Scalar, 3> operator-(const Vector<Scalar>& x, const LCN<Scalar, 2>& bycz)
00633 {
00634 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00635 return LCN<Scalar, 3>(LCN<Scalar, 1>(one, x), -bycz);
00636 }
00637
00638
00639
00640
00641 template <class Scalar> inline
00642 LCN<Scalar, 3> operator-(const LCN<Scalar, 2>& axby, const LCN<Scalar, 1>& cz)
00643 {
00644 return LCN<Scalar, 3>(axby, -cz);
00645 }
00646
00647
00648
00649
00650 template <class Scalar> inline
00651 LCN<Scalar, 3> operator-(const LCN<Scalar, 2>& axby, const Vector<Scalar>& z)
00652 {
00653 const Scalar one = Teuchos::ScalarTraits<Scalar>::one();
00654 return LCN<Scalar, 3>(axby, LCN<Scalar,1>(-one,z));
00655 }
00656
00657
00658
00659
00660
00661
00662
00663
00664
00665
00666
00667 template <class Scalar, int N> inline
00668 Scalar norm1(const LCN<Scalar, N>& lc)
00669 {
00670 return lc.norm1();
00671 }
00672
00673
00674 template <class Scalar, int N> inline
00675 Scalar norm2(const LCN<Scalar, N>& lc)
00676 {
00677 return lc.norm2();
00678 }
00679
00680
00681 template <class Scalar, int N> inline
00682 Scalar normInf(const LCN<Scalar, N>& lc)
00683 {
00684 return lc.normInf();
00685 }
00686
00687
00688 template <class Scalar, int N> inline
00689 Vector<Scalar> abs(const LCN<Scalar, N>& lc)
00690 {
00691 return lc.abs();
00692 }
00693
00694
00695 template <class Scalar, int N> inline
00696 Scalar min(const LCN<Scalar, N>& lc)
00697 {
00698 return lc.min();
00699 }
00700
00701
00702 template <class Scalar, int N> inline
00703 Scalar max(const LCN<Scalar, N>& lc)
00704 {
00705 return lc.max();
00706 }
00707
00708
00709 template <class Scalar, int N> inline
00710 Vector<Scalar> reciprocal(const LCN<Scalar, N>& lc)
00711 {
00712 return lc.reciprocal();
00713 }
00714
00715
00716
00717 }
00718
00719
00720
00721 #endif