PlayaLinearCombinationImpl.hpp
Go to the documentation of this file.
00001 /* @HEADER@ */
00002 // ************************************************************************
00003 // 
00004 //                 Playa: Programmable Linear Algebra
00005 //                 Copyright 2012 Sandia Corporation
00006 // 
00007 // Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
00008 // the U.S. Government retains certain rights in this software.
00009 //
00010 // Redistribution and use in source and binary forms, with or without
00011 // modification, are permitted provided that the following conditions are
00012 // met:
00013 //
00014 // 1. Redistributions of source code must retain the above copyright
00015 // notice, this list of conditions and the following disclaimer.
00016 //
00017 // 2. Redistributions in binary form must reproduce the above copyright
00018 // notice, this list of conditions and the following disclaimer in the
00019 // documentation and/or other materials provided with the distribution.
00020 //
00021 // 3. Neither the name of the Corporation nor the names of the
00022 // contributors may be used to endorse or promote products derived from
00023 // this software without specific prior written permission.
00024 //
00025 // THIS SOFTWARE IS PROVIDED BY SANDIA CORPORATION "AS IS" AND ANY
00026 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
00027 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00028 // PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL SANDIA CORPORATION OR THE
00029 // CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
00030 // EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00031 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00032 // PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
00033 // LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
00034 // NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
00035 // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00036 //
00037 // Questions? Contact Kevin Long (kevin.long@ttu.edu)
00038 // 
00039 
00040 /* @HEADER@ */
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  * Copy constructors
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  * Assignment operators
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     /* If LHS and RHS vectors are identical, simply multiply LHS
00096      * by the scalar constant */
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     /* If the vectors are distinct but from the same space, use the
00103      * update operation to compute (*this) = zero*(*this) + alpha*other */ 
00104     this->ptr()->update(alpha, other.ptr().get(), zero);
00105   }
00106   else
00107   {
00108     /* If the vectors are from different spaces, or if the LHS is null,
00109      * copy the RHS vector into the LHS and scale */
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     /* If the LHS exists and is from the same space as the RHS vectors, use the
00137      * update operation to compute 
00138      *      (*this) = zero*(*this) + alpha*x + beta*y 
00139      */ 
00140     this->update(alpha, x, beta, y, zero);
00141   }
00142   else
00143   {
00144     /* If the vectors are from different spaces, or if the LHS is null,
00145      * form the RHS vector and overwrite the LHS's ptr with it. */
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     /* If the LHS exists and is from the same space as the RHS vectors, use the
00177      * update operation to compute 
00178      *      (*this) = zero*(*this) + alpha*x + beta*y + c*z
00179      */ 
00180     this->update(alpha, x, beta, y, gamma, z, zero);
00181   }
00182   else
00183   {
00184     /* If the vectors are from different spaces, or if the LHS is null,
00185      * form the RHS vector and overwrite the LHS's ptr with it. */
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  * Reflexive addition operators
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  * Reflexive subtraction operators
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  *    operator times vector or LC
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  *    scalar times vector
00354  *
00355  *======================================================================*/
00356 
00357 /* \relates LCN scalar * vec */
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 /* \relates LCN vec * scalar */
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 /* \relates LCN vec / scalar */
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  *    scalar times LC
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  *  vector plus/minus vector
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  *  LC plus LC
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  *  LC minus LC
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  *  Operations on LC
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

Site Contact