Thyra_LinearCombinationImpl.hpp

00001 // @HEADER
00002 // ***********************************************************************
00003 // 
00004 //    Thyra: Interfaces and Support for Abstract Numerical Algorithms
00005 //                 Copyright (2004) Sandia Corporation
00006 // 
00007 // Under terms of Contract DE-AC04-94AL85000, there is a non-exclusive
00008 // license for use of this work by or on behalf of the U.S. Government.
00009 // 
00010 // This library is free software; you can redistribute it and/or modify
00011 // it under the terms of the GNU Lesser General Public License as
00012 // published by the Free Software Foundation; either version 2.1 of the
00013 // License, or (at your option) any later version.
00014 //  
00015 // This library is distributed in the hope that it will be useful, but
00016 // WITHOUT ANY WARRANTY; without even the implied warranty of
00017 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00018 // Lesser General Public License for more details.
00019 //  
00020 // You should have received a copy of the GNU Lesser General Public
00021 // License along with this library; if not, write to the Free Software
00022 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
00023 // USA
00024 // Questions? Contact Michael A. Heroux (maherou@sandia.gov) 
00025 // 
00026 // ***********************************************************************
00027 // @HEADER
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   /* -------- methods of OpTimesLC ------ */
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   /* ------------------------ methods of LC2 --------------------------- */
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   /* ------------------------ global methods ----------------------- */
00157 
00158 
00159   /*======================================================================
00160    *
00161    *    scalar times vector
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    *    scalar times OpTimesLC
00193    *
00194    *======================================================================*/
00195 
00196   /* scalar * OpTimesLC */
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   /* OpTimesLC * scalar */
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    *    scalar times LC2
00217    *
00218    *======================================================================*/
00219 
00220   /* scalar * LC2 */
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   /* LC2 * scalar */
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    *    operator times [vectors, OpTimesLC, LC2]
00242    *
00243    *======================================================================*/
00244 
00245   /* op * vec */
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   /* op * OpTimesLC */
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   /* op * LC2 */
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    *    add/subtract vector, vector
00287    *
00288    *======================================================================*/
00289   
00290   /* vec + vec */
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   /* vec - vec */
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    *    add/subtract vector, OpTimesLC
00311    *
00312    *======================================================================*/
00313 
00314   /* vec + OpTimesLC */
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   /* vec - OpTimesLC */
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   /* OpTimesLC + vec */
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   /* OpTimesLC - vec */
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    *    add/subtract OpTimesLC, OpTimesLC
00356    *
00357    *======================================================================*/
00358   
00359   /* OpTimesLC + OpTimesLC */
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   /* OpTimesLC - OpTimesLC */
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    *    add/subtract Vector, LC2
00384    *
00385    *======================================================================*/
00386 
00387   
00388   /* vec + LC2 */
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   /* vec - LC2 */
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   /* LC2 + vec */
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   /* LC2 - vec */
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    *    add/subtract OpTimesLC, LC2
00431    *
00432    *======================================================================*/
00433 
00434 
00435   /* OpTimesLC + LC2 */
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   /* OpTimesLC - LC2 */
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   /* LC2 + OpTimesLC */
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   /* LC2 - OpTimesLC */
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    *    add/subtract LC2, LC2
00480    *
00481    *======================================================================*/
00482   
00483   /* LC2 + LC2 */
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   /* LC2 - LC2 */
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    *    assignment of [OpTimesLC, LC2] to vector
00509    *
00510    *======================================================================*/
00511   
00512   
00513   /* definition of assignment from 1-term linear combination to a vector */
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   /* definition of add and assign from 1-term linear combination to a vector */
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; // ToDo: Make this more efficient to avoid a copy!
00540     return *this;
00541   }
00542 
00543   /* definition of assignment from N-term linear combination to a vector */
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   /* definition of add and assign from N-term linear combination to a vector */
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; // ToDo: Make this more efficient to avoid a temp copy!
00570     return *this;
00571   }
00572 
00573   /*======================================================================
00574    *
00575    *    construction of vectors from [OpTimesLC, LC2]
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   template <class Scalar> 
00586   template <class Node> inline
00587   Thyra::ConstVector<Scalar>::ConstVector(const Thyra::OpTimesLC<Scalar, Node>& x)
00588     : Teuchos::ConstHandle<Thyra::VectorBase<Scalar> >(x.formVector().constPtr())
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    *    formation of scaled operator 
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    *    composition of operators
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

Generated on Thu Sep 18 12:32:31 2008 for Thyra Operator/Vector Support by doxygen 1.3.9.1