ViennaCL - The Vienna Computing Library  1.5.0
viennacl/scalar.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_SCALAR_HPP_
00002 #define VIENNACL_SCALAR_HPP_
00003 
00004 /* =========================================================================
00005    Copyright (c) 2010-2013, Institute for Microelectronics,
00006                             Institute for Analysis and Scientific Computing,
00007                             TU Wien.
00008    Portions of this software are copyright by UChicago Argonne, LLC.
00009 
00010                             -----------------
00011                   ViennaCL - The Vienna Computing Library
00012                             -----------------
00013 
00014    Project Head:    Karl Rupp                   rupp@iue.tuwien.ac.at
00015 
00016    (A list of authors and contributors can be found in the PDF manual)
00017 
00018    License:         MIT (X11), see file LICENSE in the base directory
00019 ============================================================================= */
00020 
00025 #include <iostream>
00026 
00027 #include "viennacl/forwards.h"
00028 #include "viennacl/backend/memory.hpp"
00029 #include "viennacl/meta/result_of.hpp"
00030 #include "viennacl/linalg/scalar_operations.hpp"
00031 #include "viennacl/traits/handle.hpp"
00032 
00033 #ifdef VIENNACL_WITH_OPENCL
00034 #include "viennacl/ocl/backend.hpp"
00035 #endif
00036 
00037 namespace viennacl
00038 {
00046     template <typename LHS, typename RHS, typename OP>
00047     class scalar_expression
00048     {
00049         typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00050       public:
00051         typedef typename viennacl::result_of::cpu_value_type<DummyType>::type    ScalarType;
00052 
00053         scalar_expression(LHS & lhs, RHS & rhs) : lhs_(lhs), rhs_(rhs) {}
00054 
00056         LHS & lhs() const { return lhs_; }
00058         RHS & rhs() const { return rhs_; }
00059 
00061         operator ScalarType () const
00062         {
00063           viennacl::scalar<ScalarType> temp;
00064           temp = *this;
00065           return temp;
00066         }
00067 
00068       private:
00069         LHS & lhs_;
00070         RHS & rhs_;
00071     };
00072 
00073 
00081     template <typename LHS, typename RHS>
00082     class scalar_expression<LHS, RHS, op_inner_prod>
00083     {
00084         //typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00085       public:
00086         typedef typename viennacl::result_of::cpu_value_type<LHS>::type    ScalarType;
00087 
00088         scalar_expression(LHS & lhs, RHS & rhs) : lhs_(lhs), rhs_(rhs) {}
00089 
00091         LHS & lhs() const { return lhs_; }
00093         RHS & rhs() const { return rhs_; }
00094 
00096         operator ScalarType () const
00097         {
00098           ScalarType result;
00099           viennacl::linalg::inner_prod_cpu(lhs_, rhs_, result);
00100           return result;
00101         }
00102 
00103       private:
00104         LHS & lhs_;
00105         RHS & rhs_;
00106     };
00107 
00108 
00114     template <typename LHS, typename RHS>
00115     class scalar_expression<LHS, RHS, op_norm_1>
00116     {
00117         //typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00118       public:
00119         typedef typename viennacl::result_of::cpu_value_type<LHS>::type    ScalarType;
00120 
00121         scalar_expression(LHS & lhs, RHS & rhs) : lhs_(lhs), rhs_(rhs) {}
00122 
00124         LHS & lhs() const { return lhs_; }
00126         RHS & rhs() const { return rhs_; }
00127 
00129         operator ScalarType () const
00130         {
00131           ScalarType result;
00132           viennacl::linalg::norm_1_cpu(lhs_, result);
00133           return result;
00134         }
00135 
00136       private:
00137         LHS & lhs_;
00138         RHS & rhs_;
00139     };
00140 
00146     template <typename LHS, typename RHS>
00147     class scalar_expression<LHS, RHS, op_norm_2>
00148     {
00149         //typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00150       public:
00151         typedef typename viennacl::result_of::cpu_value_type<LHS>::type    ScalarType;
00152 
00153         scalar_expression(LHS & lhs, RHS & rhs) : lhs_(lhs), rhs_(rhs) {}
00154 
00156         LHS & lhs() const { return lhs_; }
00158         RHS & rhs() const { return rhs_; }
00159 
00161         operator ScalarType () const
00162         {
00163           ScalarType result;
00164           viennacl::linalg::norm_2_cpu(lhs_, result);
00165           return result;
00166         }
00167 
00168       private:
00169         LHS & lhs_;
00170         RHS & rhs_;
00171     };
00172 
00173 
00179     template <typename LHS, typename RHS>
00180     class scalar_expression<LHS, RHS, op_norm_inf>
00181     {
00182         //typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00183       public:
00184         typedef typename viennacl::result_of::cpu_value_type<LHS>::type    ScalarType;
00185 
00186         scalar_expression(LHS & lhs, RHS & rhs) : lhs_(lhs), rhs_(rhs) {}
00187 
00189         LHS & lhs() const { return lhs_; }
00191         RHS & rhs() const { return rhs_; }
00192 
00194         operator ScalarType () const
00195         {
00196           ScalarType result;
00197           viennacl::linalg::norm_inf_cpu(lhs_, result);
00198           return result;
00199         }
00200 
00201       private:
00202         LHS & lhs_;
00203         RHS & rhs_;
00204     };
00205 
00211     template <typename LHS, typename RHS>
00212     class scalar_expression<LHS, RHS, op_norm_frobenius>
00213     {
00214         //typedef typename LHS::value_type          DummyType; //Visual C++ 2005 does not allow to write LHS::value_type::value_type
00215       public:
00216         typedef typename viennacl::result_of::cpu_value_type<LHS>::type    ScalarType;
00217 
00218         scalar_expression(LHS & lhs, RHS & rhs) : lhs_(lhs), rhs_(rhs) {}
00219 
00221         LHS & lhs() const { return lhs_; }
00223         RHS & rhs() const { return rhs_; }
00224 
00226         operator ScalarType () const
00227         {
00228           ScalarType result;
00229           viennacl::linalg::norm_frobenius_cpu(lhs_, result);
00230           return result;
00231         }
00232 
00233       private:
00234         LHS & lhs_;
00235         RHS & rhs_;
00236     };
00237 
00238 
00239 
00240 
00248     template<class SCALARTYPE>
00249     class scalar
00250     {
00251       typedef scalar<SCALARTYPE>         self_type;
00252     public:
00253       typedef viennacl::backend::mem_handle                     handle_type;
00254       typedef vcl_size_t                                        size_type;
00255 
00257       typedef SCALARTYPE   value_type;
00258 
00260       scalar() {}
00261 
00263       scalar(SCALARTYPE val, viennacl::context ctx = viennacl::context())
00264       {
00265         viennacl::backend::memory_create(val_, sizeof(SCALARTYPE), ctx, &val);
00266       }
00267 
00268 #ifdef VIENNACL_WITH_OPENCL
00269 
00274       explicit scalar(cl_mem mem, size_type /*size*/)
00275       {
00276         val_.switch_active_handle_id(viennacl::OPENCL_MEMORY);
00277         val_.opencl_handle() = mem;
00278         val_.opencl_handle().inc();  //prevents that the user-provided memory is deleted once the vector object is destroyed.
00279       }
00280 #endif
00281 
00283       template <typename T1, typename T2, typename OP>
00284       scalar(scalar_expression<T1, T2, OP> const & proxy)
00285       {
00286         val_.switch_active_handle_id(viennacl::traits::handle(proxy.lhs()).get_active_handle_id());
00287         viennacl::backend::memory_create(val_, sizeof(SCALARTYPE), viennacl::traits::context(proxy));
00288         *this = proxy;
00289       }
00290 
00291       //copy constructor
00293       scalar(const scalar & other)
00294       {
00295         if (other.handle().get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED)
00296         {
00297           //copy value:
00298           val_.switch_active_handle_id(other.handle().get_active_handle_id());
00299           viennacl::backend::memory_create(val_, sizeof(SCALARTYPE), viennacl::traits::context(other));
00300           viennacl::backend::memory_copy(other.handle(), val_, 0, 0, sizeof(SCALARTYPE));
00301         }
00302       }
00303 
00305       operator SCALARTYPE() const
00306       {
00307         // make sure the scalar contains reasonable data:
00308         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized, cannot read!"));
00309 
00310         SCALARTYPE tmp;
00311         viennacl::backend::memory_read(val_, 0, sizeof(SCALARTYPE), &tmp);
00312         return tmp;
00313       }
00314 
00316       self_type & operator= (entry_proxy<SCALARTYPE> const & other)
00317       {
00318         init_if_necessary(viennacl::traits::context(other));
00319         viennacl::backend::memory_copy(other.handle(), val_, other.index() * sizeof(SCALARTYPE), 0, sizeof(SCALARTYPE));
00320         return *this;
00321       }
00322 
00324       self_type & operator= (scalar<SCALARTYPE> const & other)
00325       {
00326         init_if_necessary(viennacl::traits::context(other));
00327         viennacl::backend::memory_copy(other.handle(), val_, 0, 0, sizeof(SCALARTYPE));
00328         return *this;
00329       }
00330 
00331       self_type & operator= (float cpu_other)
00332       {
00333         init_if_necessary(viennacl::context());
00334 
00335         //copy value:
00336         SCALARTYPE value = static_cast<SCALARTYPE>(cpu_other);
00337         viennacl::backend::memory_write(val_, 0, sizeof(SCALARTYPE), &value);
00338         return *this;
00339       }
00340 
00341       self_type & operator= (double cpu_other)
00342       {
00343         init_if_necessary(viennacl::context());
00344 
00345         SCALARTYPE value = static_cast<SCALARTYPE>(cpu_other);
00346         viennacl::backend::memory_write(val_, 0, sizeof(SCALARTYPE), &value);
00347         return *this;
00348       }
00349 
00350       self_type & operator= (long cpu_other)
00351       {
00352         init_if_necessary(viennacl::context());
00353 
00354         SCALARTYPE value = static_cast<SCALARTYPE>(cpu_other);
00355         viennacl::backend::memory_write(val_, 0, sizeof(SCALARTYPE), &value);
00356         return *this;
00357       }
00358 
00359       self_type & operator= (unsigned long cpu_other)
00360       {
00361         init_if_necessary(viennacl::context());
00362 
00363         SCALARTYPE value = static_cast<SCALARTYPE>(cpu_other);
00364         viennacl::backend::memory_write(val_, 0, sizeof(SCALARTYPE), &value);
00365         return *this;
00366       }
00367 
00368       self_type & operator= (int cpu_other)
00369       {
00370         init_if_necessary(viennacl::context());
00371 
00372         SCALARTYPE value = static_cast<SCALARTYPE>(cpu_other);
00373         viennacl::backend::memory_write(val_, 0, sizeof(SCALARTYPE), &value);
00374         return *this;
00375       }
00376 
00377       self_type & operator= (unsigned int cpu_other)
00378       {
00379         init_if_necessary(viennacl::context());
00380 
00381         SCALARTYPE value = static_cast<SCALARTYPE>(cpu_other);
00382         viennacl::backend::memory_write(val_, 0, sizeof(SCALARTYPE), &value);
00383         return *this;
00384       }
00385 
00387       template <typename T1, typename T2>
00388       self_type & operator= (scalar_expression<T1, T2, op_inner_prod> const & proxy)
00389       {
00390         init_if_necessary(viennacl::traits::context(proxy));
00391 
00392         viennacl::linalg::inner_prod_impl(proxy.lhs(), proxy.rhs(), *this);
00393         return *this;
00394       }
00395 
00397       template <typename T1, typename T2>
00398       self_type & operator= (scalar_expression<T1, T2, op_norm_1> const & proxy)
00399       {
00400         init_if_necessary(viennacl::traits::context(proxy));
00401 
00402         viennacl::linalg::norm_1_impl(proxy.lhs(), *this);
00403         return *this;
00404       }
00405 
00407       template <typename T1, typename T2>
00408       self_type & operator= (scalar_expression<T1, T2, op_norm_2> const & proxy)
00409       {
00410         init_if_necessary(viennacl::traits::context(proxy));
00411 
00412         viennacl::linalg::norm_2_impl(proxy.lhs(), *this);
00413         return *this;
00414       }
00415 
00417       template <typename T1, typename T2>
00418       self_type & operator= (scalar_expression<T1, T2, op_norm_inf> const & proxy)
00419       {
00420         init_if_necessary(viennacl::traits::context(proxy));
00421 
00422         viennacl::linalg::norm_inf_impl(proxy.lhs(), *this);
00423         return *this;
00424       }
00425 
00427       template <typename T1, typename T2>
00428       self_type & operator= (scalar_expression<T1, T2, op_norm_frobenius> const & proxy)
00429       {
00430         init_if_necessary(viennacl::traits::context(proxy));
00431 
00432         viennacl::linalg::norm_frobenius_impl(proxy.lhs(), *this);
00433         return *this;
00434       }
00435 
00437       template <typename T1, typename T2>
00438       self_type & operator= (scalar_expression<T1, T2, op_flip_sign> const & proxy)
00439       {
00440         init_if_necessary(viennacl::traits::context(proxy));
00441 
00442         viennacl::linalg::as(*this, proxy.lhs(), SCALARTYPE(-1.0), 1, false, true);
00443         return *this;
00444       }
00445 
00446 
00448       self_type & operator += (scalar<SCALARTYPE> const & other)
00449       {
00450         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00451 
00452         viennacl::linalg::asbs(*this,                                       // s1 =
00453                                *this, SCALARTYPE(1.0), 1, false, false,     //       s1 * 1.0
00454                                other, SCALARTYPE(1.0), 1, false, false);    //     + s2 * 1.0
00455         return *this;
00456       }
00458       self_type & operator += (SCALARTYPE other)
00459       {
00460         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00461 
00462         viennacl::linalg::asbs(*this,                                       // s1 =
00463                                *this, SCALARTYPE(1.0), 1, false, false,     //       s1 * 1.0
00464                                other, SCALARTYPE(1.0), 1, false, false);    //     + s2 * 1.0
00465         return *this;
00466       }
00467 
00468 
00470       self_type & operator -= (scalar<SCALARTYPE> const & other)
00471       {
00472         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00473 
00474         viennacl::linalg::asbs(*this,                                       // s1 =
00475                                *this, SCALARTYPE(1.0), 1, false, false,     //       s1 * 1.0
00476                                other, SCALARTYPE(-1.0), 1, false, false);   //     + s2 * (-1.0)
00477         return *this;
00478       }
00480       self_type & operator -= (SCALARTYPE other)
00481       {
00482         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00483 
00484         viennacl::linalg::asbs(*this,                                       // s1 =
00485                                *this, SCALARTYPE(1.0), 1, false, false,     //       s1 * 1.0
00486                                other, SCALARTYPE(-1.0), 1, false, false);   //     + s2 * (-1.0)
00487         return *this;
00488       }
00489 
00490 
00492       self_type & operator *= (scalar<SCALARTYPE> const & other)
00493       {
00494         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00495 
00496         viennacl::linalg::as(*this,                                       // s1 =
00497                              *this, other, 1, false, false);              //      s1 * s2
00498         return *this;
00499       }
00501       self_type & operator *= (SCALARTYPE other)
00502       {
00503         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00504 
00505         viennacl::linalg::as(*this,                                       // s1 =
00506                              *this, other, 1, false, false);              //      s1 * s2
00507         return *this;
00508       }
00509 
00510 
00512 
00513       self_type & operator /= (scalar<SCALARTYPE> const & other)
00514       {
00515         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00516 
00517         viennacl::linalg::as(*this,                                       // s1 =
00518                              *this, other, 1, true, false);              //      s1 / s2
00519         return *this;
00520       }
00522       self_type & operator /= (SCALARTYPE other)
00523       {
00524         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00525 
00526         viennacl::linalg::as(*this,                                       // s1 =
00527                              *this, other, 1, true, false);              //      s1 / s2
00528         return *this;
00529       }
00530 
00531 
00533 
00534       self_type operator + (scalar<SCALARTYPE> const & other)
00535       {
00536         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00537 
00538         self_type result = 0;
00539 
00540         viennacl::linalg::asbs(result,                                       // result =
00541                                *this, SCALARTYPE(1.0), 1, false, false,      //            *this * 1.0
00542                                other, SCALARTYPE(1.0), 1, false, false);     //          + other * 1.0
00543 
00544         return result;
00545       }
00547       template <typename T1, typename T2, typename OP>
00548       self_type operator + (scalar_expression<T1, T2, OP> const & proxy) const
00549       {
00550         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00551 
00552         self_type result = proxy;
00553 
00554         viennacl::linalg::asbs(result,                                       // result =
00555                                *this, SCALARTYPE(1.0), 1, false, false,      //            *this * 1.0
00556                                result, SCALARTYPE(1.0), 1, false, false);     //        + result * 1.0
00557 
00558         return result;
00559       }
00561       self_type operator + (SCALARTYPE other)
00562       {
00563         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00564 
00565         self_type result = 0;
00566 
00567         viennacl::linalg::asbs(result,                                       // result =
00568                                *this, SCALARTYPE(1.0), 1, false, false,      //            *this * 1.0
00569                                other, SCALARTYPE(1.0), 1, false, false);     //          + other * 1.0
00570 
00571         return result;
00572       }
00573 
00574 
00576 
00578       scalar_expression<const self_type, const self_type, op_flip_sign> operator-() const
00579       {
00580         return scalar_expression<const self_type, const self_type, op_flip_sign>(*this, *this);
00581       }
00582 
00583 
00585       self_type operator - (scalar<SCALARTYPE> const & other) const
00586       {
00587         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00588 
00589         self_type result = 0;
00590 
00591         viennacl::linalg::asbs(result,                                       // result =
00592                                *this, SCALARTYPE(1.0), 1, false, false,      //            *this * 1.0
00593                                other, SCALARTYPE(-1.0), 1, false, false);    //          + other * (-1.0)
00594 
00595         return result;
00596       }
00598       template <typename T1, typename T2, typename OP>
00599       self_type operator - (scalar_expression<T1, T2, OP> const & proxy) const
00600       {
00601         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00602 
00603         self_type result = proxy;
00604 
00605         viennacl::linalg::asbs(result,                                       // result =
00606                                 *this, SCALARTYPE(1.0), 1 , false, false,    //            *this * 1.0
00607                                result, SCALARTYPE(-1.0), 1, false, false);  //          + result * (-1.0)
00608 
00609         return result;
00610       }
00612       scalar<SCALARTYPE> operator - (SCALARTYPE other) const
00613       {
00614         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00615 
00616         self_type result = 0;
00617 
00618         viennacl::linalg::asbs(result,                                       // result =
00619                                *this, SCALARTYPE(1.0), 1, false, false,      //            *this * 1.0
00620                                other, SCALARTYPE(-1.0), 1, false, false);    //          + other * (-1.0)
00621 
00622         return result;
00623       }
00624 
00626 
00627       self_type operator * (scalar<SCALARTYPE> const & other) const
00628       {
00629         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00630 
00631         scalar<SCALARTYPE> result = 0;
00632 
00633         viennacl::linalg::as(result,                                     // result =
00634                              *this, other, 1, false, false);              //          *this * other
00635 
00636         return result;
00637       }
00639       template <typename T1, typename T2, typename OP>
00640       self_type operator * (scalar_expression<T1, T2, OP> const & proxy) const
00641       {
00642         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00643 
00644         self_type result = proxy;
00645 
00646         viennacl::linalg::as(result,                                       // result =
00647                              *this, result, 1, false, false);              //            *this * proxy
00648 
00649         return result;
00650       }
00652       self_type operator * (SCALARTYPE other) const
00653       {
00654         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00655 
00656         scalar<SCALARTYPE> result = 0;
00657 
00658         viennacl::linalg::as(result,                                     // result =
00659                              *this, other, 1, false, false);              //          *this * other
00660 
00661         return result;
00662       }
00663 
00665 
00666       self_type operator / (scalar<SCALARTYPE> const & other) const
00667       {
00668         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00669 
00670         self_type result = 0;
00671 
00672         viennacl::linalg::as(result,                                     // result =
00673                              *this, other, 1, true, false);              //           *this / other
00674 
00675         return result;
00676       }
00678       template <typename T1, typename T2, typename OP>
00679       self_type operator / (scalar_expression<T1, T2, OP> const & proxy) const
00680       {
00681         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00682 
00683         self_type result = proxy;
00684 
00685         viennacl::linalg::as(result,                                     // result =
00686                              *this, result, 1, true, false);              //          *this / proxy
00687 
00688         return result;
00689       }
00691       self_type operator / (SCALARTYPE other) const
00692       {
00693         assert( val_.get_active_handle_id() != viennacl::MEMORY_NOT_INITIALIZED && bool("Scalar not initialized!"));
00694 
00695         self_type result = 0;
00696 
00697         viennacl::linalg::as(result,                                     // result =
00698                              *this, other, 1, true, false);              //            *this / other
00699 
00700         return result;
00701       }
00702 
00704       handle_type & handle() { return val_; }
00705 
00707       const handle_type & handle() const { return val_; }
00708 
00709     private:
00710 
00711       void init_if_necessary(viennacl::context ctx)
00712       {
00713         if (val_.get_active_handle_id() == viennacl::MEMORY_NOT_INITIALIZED)
00714         {
00715           viennacl::backend::memory_create(val_, sizeof(SCALARTYPE), ctx);
00716         }
00717       }
00718 
00719       handle_type val_;
00720     };
00721 
00722 
00723     //stream operators:
00725     template<class SCALARTYPE>
00726     std::ostream & operator<<(std::ostream & s, const scalar<SCALARTYPE> & val)
00727     {
00728       SCALARTYPE temp = val;
00729       s << temp;
00730       return s;
00731     }
00732 
00734     template<class SCALARTYPE>
00735     std::istream & operator>>(std::istream & s, const scalar<SCALARTYPE> & val)
00736     {
00737       SCALARTYPE temp;
00738       s >> temp;
00739       val = temp;
00740       return s;
00741     }
00742 
00743 } //namespace viennacl
00744 
00745 #endif