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 #ifndef THYRA_LINEARCOMBINATION_IMPL_HPP
00030 #define THYRA_LINEARCOMBINATION_IMPL_HPP
00031
00032 #include "Thyra_ConfigDefs.hpp"
00033 #include "Thyra_LinearCombinationDecl.hpp"
00034 #include "Thyra_LinearOperatorImpl.hpp"
00035 #include "Thyra_VectorHandleOpsImpl.hpp"
00036 #include "Teuchos_as.hpp"
00037
00038 namespace Thyra
00039 {
00040
00041
00042 template <class Scalar, class Node> inline
00043 OpTimesLC<Scalar, Node>::OpTimesLC(const Scalar& alpha,
00044 const Node& x)
00045 : alpha_(alpha), op_(), x_(x)
00046 {;}
00047
00048 template <class Scalar, class Node> inline
00049 OpTimesLC<Scalar, Node>
00050 ::OpTimesLC(const Scalar& alpha,
00051 const Thyra::ConstLinearOperator<Scalar>& op,
00052 const Node& x)
00053 : alpha_(alpha), op_(op), x_(x)
00054 {;}
00055
00056
00057 template <class Scalar, class Node> inline
00058 void OpTimesLC<Scalar, Node>::evalInto(Thyra::Vector<Scalar>& result) const
00059 {
00060 if (op_.constPtr().get() != 0)
00061 {
00062 op_.apply(x_.convert(), result, alpha_);
00063 }
00064 else
00065 {
00066 x_.evalInto(result);
00067 if (alpha_ != one()) scale(result, alpha_);
00068 }
00069 }
00070
00071 template <class Scalar, class Node> inline
00072 void OpTimesLC<Scalar, Node>::addInto(Thyra::Vector<Scalar>& result,
00073 LCSign sign) const
00074 {
00075 Scalar s = convertTo<Scalar>(sign);
00076 if (op_.constPtr().get() != 0)
00077 {
00078 Thyra::Vector<Scalar> tmp;
00079 op_.apply(x_.convert(), tmp);
00080 axpy(s*alpha_, tmp, result);
00081 }
00082 else
00083 {
00084 axpy(s*alpha_, x_.convert(), result);
00085 }
00086 }
00087
00088 template <class Scalar, class Node> inline
00089 Thyra::Vector<Scalar> OpTimesLC<Scalar, Node>::formVector() const
00090 {
00091 Thyra::Vector<Scalar> result;
00092 if (op_.constPtr().get() != 0)
00093 {
00094 result = op_.range().createMember();
00095 op_.apply(x_.convert(), result, alpha_);
00096 }
00097 else
00098 {
00099 result = Thyra::formVector(x_);
00100 if (alpha_ != one()) scale(result, alpha_);
00101 }
00102 return result;
00103 }
00104
00105
00106 template <class Scalar, class Node> inline
00107 bool OpTimesLC<Scalar, Node>::containsVector(const Thyra::VectorBase<Scalar>* vec) const
00108 {return x_.containsVector(vec);}
00109
00110
00111
00112
00113
00114
00115
00116
00117 template <class Scalar, class Node1, class Node2> inline
00118 LC2<Scalar, Node1, Node2>::LC2(const Node1& x1, const Node2& x2, LCSign sign)
00119 : x1_(x1), x2_(x2), sign_(sign)
00120 {
00121 ;
00122 }
00123
00124 template <class Scalar, class Node1, class Node2> inline
00125 bool LC2<Scalar, Node1, Node2>::containsVector(const Thyra::VectorBase<Scalar>* vec) const
00126 {return x1_.containsVector(vec) || x2_.containsVector(vec);}
00127
00128 template <class Scalar, class Node1, class Node2> inline
00129 void LC2<Scalar, Node1, Node2>::evalInto(Thyra::Vector<Scalar>& result) const
00130 {
00131 x1_.evalInto(result);
00132 x2_.addInto(result, sign_);
00133 }
00134
00135 template <class Scalar, class Node1, class Node2> inline
00136 void LC2<Scalar, Node1, Node2>::addInto(Thyra::Vector<Scalar>& result,
00137 Thyra::LCSign sign) const
00138 {
00139 x1_.addInto(result, sign);
00140 if (sign_*sign < 0) x2_.addInto(result, LCSubtract);
00141 else x2_.addInto(result, LCAdd);
00142 }
00143
00144 template <class Scalar, class Node1, class Node2> inline
00145 Thyra::Vector<Scalar> LC2<Scalar, Node1, Node2>::formVector() const
00146 {
00147 Thyra::Vector<Scalar> result = Thyra::formVector(x1_);
00148 x2_.addInto(result, sign_);
00149 return result;
00150 }
00151
00152 }
00153
00154 namespace Thyra
00155 {
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00170 template <class Scalar> inline
00171 OpTimesLC<Scalar, Thyra::ConstVector<Scalar> >
00172 operator*(const Scalar& alpha,
00173 const Thyra::ConstVector<Scalar>& x)
00174 {
00175 return OpTimesLC<Scalar, Thyra::ConstVector<Scalar> >(alpha, x);
00176 }
00177
00182 template <class Scalar> inline
00183 OpTimesLC<Scalar, Thyra::ConstVector<Scalar> >
00184 operator*(const Thyra::ConstVector<Scalar>& x,
00185 const Scalar& alpha)
00186 {
00187 return OpTimesLC<Scalar, Thyra::ConstVector<Scalar> >(alpha, x);
00188 }
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198 template <class Scalar, class Node> inline
00199 OpTimesLC<Scalar, Node>
00200 operator*(const Scalar& alpha,
00201 const OpTimesLC<Scalar, Node>& x)
00202 {
00203 return OpTimesLC<Scalar, Node>(alpha * x.alpha(), x.op(), x.node());
00204 }
00205
00206
00207 template <class Scalar, class Node> inline
00208 OpTimesLC<Scalar, Node>
00209 operator*(const OpTimesLC<Scalar, Node>& x, const Scalar& alpha)
00210 {
00211 return alpha * x;
00212 }
00213
00214
00215
00216
00217
00218
00219
00220
00221
00222 template <class Scalar, class Node1, class Node2> inline
00223 OpTimesLC<Scalar, LC2<Scalar, Node1, Node2> >
00224 operator*(const Scalar& alpha,
00225 const LC2<Scalar, Node1, Node2>& x)
00226 {
00227 return OpTimesLC<Scalar, LC2<Scalar, Node1, Node2> >(alpha, x);
00228 }
00229
00230
00231 template <class Scalar, class Node1, class Node2> inline
00232 OpTimesLC<Scalar, LC2<Scalar, Node1, Node2> >
00233 operator*(const LC2<Scalar, Node1, Node2>& x, const Scalar& alpha)
00234 {
00235 return alpha * x;
00236 }
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246
00247 template <class Scalar> inline
00248 OpTimesLC<Scalar, Thyra::ConstVector<Scalar> >
00249 operator*(const ConstLinearOperator<Scalar>& op,
00250 const Thyra::ConstVector<Scalar>& x)
00251 {
00252 return OpTimesLC<Scalar, Thyra::ConstVector<Scalar> >(Teuchos::ScalarTraits<Scalar>::one(), op, x);
00253 }
00254
00255
00256
00257 template <class Scalar, class Node> inline
00258 OpTimesLC<Scalar, Node>
00259 operator*(const ConstLinearOperator<Scalar>& op,
00260 const OpTimesLC<Scalar, Node>& x)
00261 {
00262 TEST_FOR_EXCEPTION(op.constPtr().get()==0, std::runtime_error,
00263 "null operator in LinearOperator * ( OpTimesLC )");
00264 if (x.op().constPtr().get()==0)
00265 {
00266 return OpTimesLC<Scalar, Node>(x.alpha(), op, x.node());
00267 }
00268 else
00269 {
00270 return OpTimesLC<Scalar, Node>(x.alpha(), op * x.op(), x.node());
00271 }
00272 }
00273
00274
00275
00276 template <class Scalar, class Node1, class Node2> inline
00277 OpTimesLC<Scalar, LC2<Scalar, Node1, Node2> >
00278 operator*(const ConstLinearOperator<Scalar>& op,
00279 const LC2<Scalar, Node1, Node2>& x)
00280 {
00281 return OpTimesLC<Scalar, LC2<Scalar, Node1, Node2> >(Teuchos::ScalarTraits<Scalar>::one(), op, x);
00282 }
00283
00284
00285
00286
00287
00288
00289
00290
00291
00292 template <class Scalar> inline
00293 LC2<Scalar, Thyra::ConstVector<Scalar>, Thyra::ConstVector<Scalar> >
00294 operator+(const Thyra::ConstVector<Scalar>& x1,
00295 const Thyra::ConstVector<Scalar>& x2)
00296 {
00297 return LC2<Scalar, Thyra::ConstVector<Scalar>, Thyra::ConstVector<Scalar> >(x1, x2);
00298 }
00299
00300
00301 template <class Scalar> inline
00302 LC2<Scalar, Thyra::ConstVector<Scalar>, Thyra::ConstVector<Scalar> >
00303 operator-(const Thyra::ConstVector<Scalar>& x1,
00304 const Thyra::ConstVector<Scalar>& x2)
00305 {
00306 return LC2<Scalar, Thyra::ConstVector<Scalar>, Thyra::ConstVector<Scalar> >(x1, x2, LCSubtract);
00307 }
00308
00309
00310
00311
00312
00313
00314
00315
00316 template <class Scalar, class Node> inline
00317 LC2<Scalar, Thyra::ConstVector<Scalar>, OpTimesLC<Scalar, Node> >
00318 operator+(const Thyra::ConstVector<Scalar>& x1,
00319 const OpTimesLC<Scalar, Node>& x2)
00320 {
00321 return LC2<Scalar, Thyra::ConstVector<Scalar>, OpTimesLC<Scalar, Node> >(x1, x2);
00322 }
00323
00324
00325 template <class Scalar, class Node> inline
00326 LC2<Scalar, Thyra::ConstVector<Scalar>, OpTimesLC<Scalar, Node> >
00327 operator-(const Thyra::ConstVector<Scalar>& x1,
00328 const OpTimesLC<Scalar, Node>& x2)
00329 {
00330 return LC2<Scalar, Thyra::ConstVector<Scalar>, OpTimesLC<Scalar, Node> >(x1, x2,
00331 LCSubtract);
00332 }
00333
00334
00335 template <class Scalar, class Node> inline
00336 LC2<Scalar, OpTimesLC<Scalar, Node>, Thyra::ConstVector<Scalar> >
00337 operator+(const OpTimesLC<Scalar, Node>& x1,
00338 const Thyra::ConstVector<Scalar>& x2)
00339 {
00340 return LC2<Scalar, OpTimesLC<Scalar, Node>, Thyra::ConstVector<Scalar> >(x1, x2);
00341 }
00342
00343
00344 template <class Scalar, class Node> inline
00345 LC2<Scalar, OpTimesLC<Scalar, Node>, Thyra::ConstVector<Scalar> >
00346 operator-(const OpTimesLC<Scalar, Node>& x1,
00347 const Thyra::ConstVector<Scalar>& x2)
00348 {
00349 return LC2<Scalar, OpTimesLC<Scalar, Node>, Thyra::ConstVector<Scalar> >(x1, x2,
00350 LCSubtract);
00351 }
00352
00353
00354
00355
00356
00357
00358
00359
00360
00361 template <class Scalar, class Node1, class Node2> inline
00362 LC2<Scalar, OpTimesLC<Scalar, Node1>, OpTimesLC<Scalar, Node2> >
00363 operator+(const OpTimesLC<Scalar, Node1>& x1,
00364 const OpTimesLC<Scalar, Node2>& x2)
00365 {
00366 return LC2<Scalar, OpTimesLC<Scalar, Node1>,
00367 OpTimesLC<Scalar, Node2> >(x1, x2);
00368 }
00369
00370
00371 template <class Scalar, class Node1, class Node2> inline
00372 LC2<Scalar, OpTimesLC<Scalar, Node1>, OpTimesLC<Scalar, Node2> >
00373 operator-(const OpTimesLC<Scalar, Node1>& x1,
00374 const OpTimesLC<Scalar, Node2>& x2)
00375 {
00376 return LC2<Scalar, OpTimesLC<Scalar, Node1>,
00377 OpTimesLC<Scalar, Node2> >(x1, x2, LCSubtract);
00378 }
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 template <class Scalar, class Node1, class Node2> inline
00391 LC2<Scalar, Thyra::ConstVector<Scalar>, LC2<Scalar, Node1, Node2> >
00392 operator+(const Thyra::ConstVector<Scalar>& x1,
00393 const LC2<Scalar, Node1, Node2>& x2)
00394 {
00395 return LC2<Scalar, Thyra::ConstVector<Scalar>, LC2<Scalar, Node1, Node2> >(x1, x2);
00396 }
00397
00398
00399 template <class Scalar, class Node1, class Node2> inline
00400 LC2<Scalar, Thyra::ConstVector<Scalar>, LC2<Scalar, Node1, Node2> >
00401 operator-(const Thyra::ConstVector<Scalar>& x1,
00402 const LC2<Scalar, Node1, Node2>& x2)
00403 {
00404 return LC2<Scalar, Thyra::ConstVector<Scalar>, LC2<Scalar, Node1, Node2> >(x1, x2,
00405 LCSubtract);
00406 }
00407
00408
00409
00410 template <class Scalar, class Node1, class Node2> inline
00411 LC2<Scalar, LC2<Scalar, Node1, Node2>, Thyra::ConstVector<Scalar> >
00412 operator+(const LC2<Scalar, Node1, Node2>& x1,
00413 const Thyra::ConstVector<Scalar>& x2)
00414 {
00415 return LC2<Scalar, LC2<Scalar, Node1, Node2>, Thyra::ConstVector<Scalar> >(x1, x2);
00416 }
00417
00418
00419 template <class Scalar, class Node1, class Node2> inline
00420 LC2<Scalar, LC2<Scalar, Node1, Node2>, Thyra::ConstVector<Scalar> >
00421 operator-(const LC2<Scalar, Node1, Node2>& x1,
00422 const Thyra::ConstVector<Scalar>& x2)
00423 {
00424 return LC2<Scalar, LC2<Scalar, Node1, Node2>, Thyra::ConstVector<Scalar> >(x1, x2,
00425 LCSubtract);
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437 template <class Scalar, class Node0, class Node1, class Node2> inline
00438 LC2<Scalar, OpTimesLC<Scalar, Node0>, LC2<Scalar, Node1, Node2> >
00439 operator+(const OpTimesLC<Scalar, Node0>& x1,
00440 const LC2<Scalar, Node1, Node2>& x2)
00441 {
00442 return LC2<Scalar, OpTimesLC<Scalar, Node0>,
00443 LC2<Scalar, Node1, Node2> >(x1, x2);
00444 }
00445
00446
00447 template <class Scalar, class Node0, class Node1, class Node2> inline
00448 LC2<Scalar, OpTimesLC<Scalar, Node0>, LC2<Scalar, Node1, Node2> >
00449 operator-(const OpTimesLC<Scalar, Node0>& x1,
00450 const LC2<Scalar, Node1, Node2>& x2)
00451 {
00452 return LC2<Scalar, OpTimesLC<Scalar, Node0>,
00453 LC2<Scalar, Node1, Node2> >(x1, x2, LCSubtract);
00454 }
00455
00456
00457
00458 template <class Scalar, class Node1, class Node2, class Node3> inline
00459 LC2<Scalar, LC2<Scalar, Node1, Node2>, OpTimesLC<Scalar, Node3> >
00460 operator+(const LC2<Scalar, Node1, Node2>& x1,
00461 const OpTimesLC<Scalar, Node3>& x2)
00462 {
00463 return LC2<Scalar, LC2<Scalar, Node1, Node2>,
00464 OpTimesLC<Scalar, Node3> >(x1, x2);
00465 }
00466
00467
00468 template <class Scalar, class Node1, class Node2, class Node3> inline
00469 LC2<Scalar, LC2<Scalar, Node1, Node2>, OpTimesLC<Scalar, Node3> >
00470 operator-(const LC2<Scalar, Node1, Node2>& x1,
00471 const OpTimesLC<Scalar, Node3>& x2)
00472 {
00473 return LC2<Scalar, LC2<Scalar, Node1, Node2>,
00474 OpTimesLC<Scalar, Node3> >(x1, x2, LCSubtract);
00475 }
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 template <class Scalar, class Node1, class Node2,
00486 class Node3, class Node4> inline
00487 LC2<Scalar, LC2<Scalar, Node1, Node2>, LC2<Scalar, Node3, Node4> >
00488 operator+(const LC2<Scalar, Node1, Node2>& x1,
00489 const LC2<Scalar, Node3, Node4>& x2)
00490 {
00491 return LC2<Scalar, LC2<Scalar, Node1, Node2>,
00492 LC2<Scalar, Node3, Node4> >(x1, x2);
00493 }
00494
00495
00496 template <class Scalar, class Node1, class Node2,
00497 class Node3, class Node4> inline
00498 LC2<Scalar, LC2<Scalar, Node1, Node2>, LC2<Scalar, Node3, Node4> >
00499 operator-(const LC2<Scalar, Node1, Node2>& x1,
00500 const LC2<Scalar, Node3, Node4>& x2)
00501 {
00502 return LC2<Scalar, LC2<Scalar, Node1, Node2>,
00503 LC2<Scalar, Node3, Node4> >(x1, x2, LCSubtract);
00504 }
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515 template <class Scalar>
00516 template <class Node> inline
00517 Thyra::Vector<Scalar>& Thyra::Vector<Scalar>::operator=(const Thyra::OpTimesLC<Scalar, Node>& x)
00518 {
00519 if (this->ptr().get()==0)
00520 {
00521 *this = x.formVector();
00522 }
00523 else if (x.containsVector(this->ptr().get()))
00524 {
00525 Thyra::Vector<Scalar> rtn = x.formVector();
00526 acceptCopyOf(rtn);
00527 }
00528 else
00529 {
00530 x.evalInto(*this);
00531 }
00532 return *this;
00533 }
00534
00535
00536 template <class Scalar>
00537 template <class Node> inline
00538 Thyra::Vector<Scalar>& Thyra::Vector<Scalar>::operator+=(const Thyra::OpTimesLC<Scalar, Node>& x)
00539 {
00540 *this = *this + x;
00541 return *this;
00542 }
00543
00544
00545 template <class Scalar>
00546 template <class Node1, class Node2> inline
00547 Thyra::Vector<Scalar>& Thyra::Vector<Scalar>::operator=(const Thyra::LC2<Scalar, Node1, Node2>& x)
00548 {
00549 if (this->ptr().get()==0)
00550 {
00551 *this = x.formVector();
00552 }
00553 else if (x.containsVector(this->ptr().get()))
00554 {
00555 Thyra::Vector<Scalar> rtn = x.formVector();
00556 acceptCopyOf(rtn);
00557 }
00558 else
00559 {
00560 x.evalInto(*this);
00561 }
00562 return *this;
00563 }
00564
00565
00566 template <class Scalar>
00567 template <class Node1, class Node2> inline
00568 Thyra::Vector<Scalar>& Thyra::Vector<Scalar>::operator+=(const Thyra::LC2<Scalar, Node1, Node2>& x)
00569 {
00570 *this = *this + x;
00571 return *this;
00572 }
00573
00574
00575
00576
00577
00578
00579
00580
00581 template <class Scalar>
00582 Thyra::ConstVector<Scalar>::ConstVector(const Thyra::ConvertibleToVector<Scalar>& x)
00583 : Teuchos::ConstHandle<Thyra::VectorBase<Scalar> >(x.formVector().constPtr())
00584 {;}
00585
00586
00587
00588
00589
00590
00591
00592
00593 template <class Scalar>
00594 template <class Node1, class Node2> inline
00595 Thyra::Vector<Scalar>::Vector(const Thyra::LC2<Scalar, Node1, Node2>& x)
00596 : Teuchos::Handle<VectorBase<Scalar> >(),
00597 Thyra::ConstVector<Scalar>()
00598 {
00599 setRcp(x.formVector().ptr());
00600 }
00601
00602 template <class Scalar>
00603 template <class Node> inline
00604 Thyra::Vector<Scalar>::Vector(const Thyra::OpTimesLC<Scalar, Node>& x)
00605 : Teuchos::Handle<VectorBase<Scalar> >(),
00606 Thyra::ConstVector<Scalar>()
00607
00608 {
00609 Vector<Scalar> y = x.formVector();
00610 setRcp(y.ptr());
00611 }
00612
00613
00614 #ifdef EXTENDED_OPS_ARE_READY
00615
00616
00617
00618
00619
00620
00621
00622 template <class Scalar> inline
00623 LinearOperator<Scalar> operator*(const Scalar& a, const LinearOperator<Scalar>& A)
00624 {
00625 return new ScaledOperator<Scalar>(A, a);
00626 }
00627
00628
00629
00630
00631
00632
00633
00634
00635 template <class Scalar> inline
00636 LinearOperator<Scalar> operator*(const LinearOperator<Scalar>& A,
00637 const LinearOperator<Scalar>& B)
00638 {
00639 return new ComposedOperator<Scalar>(A, B);
00640 }
00641
00642 #endif // EXTENDED_OPS_ARE_READY
00643
00644 }
00645
00646 #endif // THYRA_LINEARCOMBINATION_IMPL_HPP