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