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 #include "Teuchos_as.hpp"
00037 
00038 namespace Thyra
00039 {
00040   /* -------- methods of OpTimesLC ------ */
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   /* ------------------------ methods of LC2 --------------------------- */
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   /* ------------------------ global methods ----------------------- */
00158 
00159 
00160   /*======================================================================
00161    *
00162    *    scalar times std::vector
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    *    scalar times OpTimesLC
00194    *
00195    *======================================================================*/
00196 
00197   /* scalar * OpTimesLC */
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   /* OpTimesLC * scalar */
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    *    scalar times LC2
00218    *
00219    *======================================================================*/
00220 
00221   /* scalar * LC2 */
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   /* LC2 * scalar */
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    *    operator times [vectors, OpTimesLC, LC2]
00243    *
00244    *======================================================================*/
00245 
00246   /* op * vec */
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   /* op * OpTimesLC */
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   /* op * LC2 */
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    *    add/subtract std::vector, std::vector
00288    *
00289    *======================================================================*/
00290   
00291   /* vec + vec */
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   /* vec - vec */
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    *    add/subtract std::vector, OpTimesLC
00312    *
00313    *======================================================================*/
00314 
00315   /* vec + OpTimesLC */
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   /* vec - OpTimesLC */
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   /* OpTimesLC + vec */
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   /* OpTimesLC - vec */
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    *    add/subtract OpTimesLC, OpTimesLC
00357    *
00358    *======================================================================*/
00359   
00360   /* OpTimesLC + OpTimesLC */
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   /* OpTimesLC - OpTimesLC */
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    *    add/subtract Vector, LC2
00385    *
00386    *======================================================================*/
00387 
00388   
00389   /* vec + LC2 */
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   /* vec - LC2 */
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   /* LC2 + vec */
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   /* LC2 - vec */
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    *    add/subtract OpTimesLC, LC2
00432    *
00433    *======================================================================*/
00434 
00435 
00436   /* OpTimesLC + LC2 */
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   /* OpTimesLC - LC2 */
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   /* LC2 + OpTimesLC */
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   /* LC2 - OpTimesLC */
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    *    add/subtract LC2, LC2
00481    *
00482    *======================================================================*/
00483   
00484   /* LC2 + LC2 */
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   /* LC2 - LC2 */
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    *    assignment of [OpTimesLC, LC2] to std::vector
00510    *
00511    *======================================================================*/
00512   
00513   
00514   /* definition of assignment from 1-term linear combination to a std::vector */
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   /* definition of add and assign from 1-term linear combination to a std::vector */
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; // ToDo: Make this more efficient to avoid a copy!
00541     return *this;
00542   }
00543 
00544   /* definition of assignment from N-term linear combination to a std::vector */
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   /* definition of add and assign from N-term linear combination to a std::vector */
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; // ToDo: Make this more efficient to avoid a temp copy!
00571     return *this;
00572   }
00573 
00574   /*======================================================================
00575    *
00576    *    construction of vectors from [OpTimesLC, LC2]
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   template <class Scalar> 
00587   template <class Node> inline
00588   Thyra::ConstVector<Scalar>::ConstVector(const Thyra::OpTimesLC<Scalar, Node>& x)
00589     : Teuchos::ConstHandle<Thyra::VectorBase<Scalar> >(x.formVector().constPtr())
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    *    formation of scaled operator 
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    *    composition of operators
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

Generated on Wed May 12 21:26:54 2010 for Thyra Operator/Vector Support by  doxygen 1.4.7