• Main Page
  • Namespaces
  • Data Structures
  • Files
  • File List
  • Globals

/data/development/ViennaCL/ViennaCL-1.1.2/viennacl/vector.hpp

Go to the documentation of this file.
00001 /* =======================================================================
00002    Copyright (c) 2010, Institute for Microelectronics, TU Vienna.
00003    http://www.iue.tuwien.ac.at
00004                              -----------------
00005                      ViennaCL - The Vienna Computing Library
00006                              -----------------
00007                             
00008    authors:    Karl Rupp                          rupp@iue.tuwien.ac.at
00009                Florian Rudolf                     flo.rudy+viennacl@gmail.com
00010                Josef Weinbub                      weinbub@iue.tuwien.ac.at
00011 
00012    license:    MIT (X11), see file LICENSE in the ViennaCL base directory
00013 ======================================================================= */
00014 
00020 #ifndef _VIENNACL_VECTOR_HPP_
00021 #define _VIENNACL_VECTOR_HPP_
00022 
00023 #include "viennacl/forwards.h"
00024 #include "viennacl/ocl/backend.hpp"
00025 #include "viennacl/scalar.hpp"
00026 #include "viennacl/tools/tools.hpp"
00027 #include "viennacl/tools/entry_proxy.hpp"
00028 #include "viennacl/linalg/vector_operations.hpp"
00029 
00030 namespace viennacl
00031 {
00032     
00045     template <typename LHS, typename RHS, typename OP>
00046     class vector_expression
00047     {
00048       public:
00051         typedef typename viennacl::tools::VECTOR_EXTRACTOR<LHS, RHS>::ResultType    VectorType;
00052       
00053         vector_expression(LHS & lhs, RHS & rhs) : _lhs(lhs), _rhs(rhs) {}
00054         
00057         LHS & lhs() const { return _lhs; }
00060         RHS & rhs() const { return _rhs; }
00061         
00063         unsigned int size() const { return viennacl::tools::VECTOR_SIZE_DEDUCER<LHS, RHS, OP>::size(_lhs, _rhs); }
00064         
00065       private:
00067         LHS & _lhs;
00069         RHS & _rhs;
00070     };
00071     
00090     template<class SCALARTYPE, unsigned int ALIGNMENT>
00091     class const_vector_iterator
00092     {
00093         typedef const_vector_iterator<SCALARTYPE, ALIGNMENT>    self_type;
00094       public:
00095         typedef scalar<SCALARTYPE>            value_type;
00096         typedef long                          difference_type;
00097         
00098         const_vector_iterator() {};
00103         const_vector_iterator(vector<SCALARTYPE, ALIGNMENT> const & vec,      cl_uint index)  : elements_(vec.handle()), index_(index) {};
00104         const_vector_iterator(viennacl::ocl::handle<cl_mem> const & elements, cl_uint index)  : elements_(elements), index_(index) {};
00105 
00106         
00107         value_type operator*(void) const 
00108         { 
00109            value_type result;
00110            result = entry_proxy<SCALARTYPE>(index_, elements_);
00111            return result;
00112         }
00113         self_type operator++(void) { ++index_; return *this; }
00114         self_type operator++(int) { self_type tmp = *this; ++(*this); return tmp; }
00115         
00116         bool operator==(self_type const & other) const { return index_ == other.index_; }
00117         bool operator!=(self_type const & other) const { return index_ != other.index_; }
00118         
00119 //        self_type & operator=(self_type const & other)
00120 //        {
00121 //           _index = other._index;
00122 //           elements_ = other._elements;
00123 //           return *this;
00124 //        }   
00125 
00126         difference_type operator-(self_type const & other) const { difference_type result = index_; return result - other.index_; }
00127         self_type operator+(difference_type diff) const { return self_type(elements_, index_ + diff); }
00128         
00129         unsigned int index() const { return index_; }
00130         viennacl::ocl::handle<cl_mem> const & handle() const { return elements_; }
00131 
00132       protected:
00134         viennacl::ocl::handle<cl_mem> elements_;
00135         unsigned int index_;
00136     };
00137     
00138 
00158     template<class SCALARTYPE, unsigned int ALIGNMENT>
00159     class vector_iterator : public const_vector_iterator<SCALARTYPE, ALIGNMENT>
00160     {
00161         typedef const_vector_iterator<SCALARTYPE, ALIGNMENT>  base_type;
00162         typedef vector_iterator<SCALARTYPE, ALIGNMENT>        self_type;
00163       public:
00164         vector_iterator() : base_type(){};
00165         vector_iterator(viennacl::ocl::handle<cl_mem> const & elements, unsigned int index)  : base_type(elements, index) {};
00170         vector_iterator(vector<SCALARTYPE, ALIGNMENT> & vec, cl_uint index) : base_type(vec, index) {};
00171         vector_iterator(base_type const & b) : base_type(b) {};
00172 
00173         typename base_type::value_type operator*(void)  
00174         { 
00175            typename base_type::value_type result;
00176            result = entry_proxy<SCALARTYPE>(base_type::index_, base_type::elements_); 
00177            return result;
00178         }
00179         
00180         viennacl::ocl::handle<cl_mem> handle() { return base_type::elements_; }
00181         
00182         operator base_type() const
00183         {
00184           return base_type(base_type::elements_, base_type::index_);
00185         }
00186     };
00187 
00188     // forward definition in VCLForwards.h!
00197     template<class SCALARTYPE, unsigned int ALIGNMENT>
00198     class vector
00199     {
00200       
00201     public:
00202       typedef scalar<typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT<SCALARTYPE>::ResultType>   value_type;
00203       typedef vcl_size_t                                        size_type;
00204       typedef vcl_ptrdiff_t                                     difference_type;
00205       typedef const_vector_iterator<SCALARTYPE, ALIGNMENT>      const_iterator;
00206       typedef vector_iterator<SCALARTYPE, ALIGNMENT>            iterator;
00207 
00210       vector() : size_(0) { viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::init();  }
00211 
00216       explicit vector(size_type vec_size) : size_(vec_size)
00217       {
00218         viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::init(); 
00219         
00220         if (size_ > 0)
00221           elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*internal_size());
00222         
00223         //force entries above size_ to zero:
00224         if (size_ < internal_size())
00225         {
00226           std::vector<SCALARTYPE> temp(internal_size() - size_);
00227           cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), elements_, CL_TRUE, sizeof(SCALARTYPE)*size_, sizeof(SCALARTYPE)*(internal_size() - size_), &(temp[0]), 0, NULL, NULL);
00228           //assert(err == CL_SUCCESS);
00229           VIENNACL_ERR_CHECK(err);
00230         }
00231       }
00232 
00241       explicit vector(cl_mem existing_mem, size_type vec_size) : size_(vec_size),  elements_(existing_mem)
00242       {
00243         elements_.inc();  //prevents that the user-provided memory is deleted once the vector object is destroyed.
00244       }
00245       
00246       template <typename LHS, typename RHS, typename OP>
00247       vector(vector_expression<LHS, RHS, OP> const & other) : size_(other.size())
00248       {
00249         elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*other.size());
00250         *this = other;
00251       }
00252       
00257       vector(const vector<SCALARTYPE, ALIGNMENT> & vec) :
00258         size_(vec.size())
00259       {
00260         viennacl::linalg::kernels::vector<SCALARTYPE, 1>::init(); 
00261         
00262         if (size() != 0)
00263         {
00264           elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*internal_size());
00265           cl_int err;
00266           err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), vec.handle(), elements_, 0, 0, sizeof(SCALARTYPE)*internal_size(), 0, NULL, NULL);
00267           //assert(err == CL_SUCCESS);
00268           VIENNACL_ERR_CHECK(err);
00269         }
00270       }
00271 
00274       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector<SCALARTYPE, ALIGNMENT> & vec)
00275       {
00276         resize(vec.size());
00277         if (size() != 0)
00278         {
00279           cl_int err;
00280           err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), vec.handle(), elements_, 0, 0, sizeof(SCALARTYPE)*internal_size(), 0, NULL, NULL);
00281           VIENNACL_ERR_CHECK(err);
00282         }
00283         return *this;
00284       }
00285 
00286 
00291       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00292       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00293                                                                            const scalar<SCALARTYPE>,
00294                                                                            op_prod> & proxy)
00295       {
00296         resize(proxy.lhs().size());
00297         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00298         viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this);
00299         return *this;
00300       }
00301 
00306       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00307       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00308                                                                            const SCALARTYPE,
00309                                                                            op_prod> & proxy)
00310       {
00311         resize(proxy.lhs().size());
00312         viennacl::linalg::mult(proxy.lhs(), proxy.rhs(), *this);
00313         return *this;
00314       }
00315 
00320       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00321       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00322                                                                            const scalar<SCALARTYPE>,
00323                                                                            op_div> & proxy)
00324       {
00325         resize(proxy.lhs().size());
00326         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00327         viennacl::linalg::divide(proxy.lhs(), proxy.rhs(), *this);
00328         return *this;
00329       }
00330 
00335       template <typename VectorType>   //use template to cover const/non-const of VectorType:
00336       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< VectorType,
00337                                                                            const SCALARTYPE,
00338                                                                            op_div> & proxy)
00339       {
00340         resize(proxy.lhs().size());
00341         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00342         viennacl::linalg::mult(proxy.lhs(), static_cast<SCALARTYPE>(1.0) / proxy.rhs(), *this);
00343         return *this;
00344       }
00345 
00346       //v1 = v2 + v3; 
00351       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00352                                                                            vector<SCALARTYPE, ALIGNMENT>,
00353                                                                            op_add> & proxy)
00354       {
00355         resize(proxy.lhs().size());
00356         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00357         viennacl::linalg::add(proxy.lhs(), proxy.rhs(), *this);
00358         return *this;
00359       }
00360       
00361       //v1 = v2 - v3; 
00366       vector<SCALARTYPE, ALIGNMENT> & operator = (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00367                                                                            vector<SCALARTYPE, ALIGNMENT>,
00368                                                                            op_sub> & proxy)
00369       {
00370         resize(proxy.lhs().size());
00371         //std::cout << "vector::operator=(vec_times_scalar_proxy)" << std::endl; 
00372         viennacl::linalg::sub(proxy.lhs(), proxy.rhs(), *this);
00373         return *this;
00374       }
00375       
00377 
00378       //Note: The following operator overloads are defined in matrix_operations.hpp, compressed_matrix_operations.hpp and coordinate_matrix_operations.hpp
00379       //This is certainly not the nicest approach and will most likely by changed in the future, but it works :-)
00380       
00381       //matrix<>
00386       template <typename F, unsigned int MAT_ALIGNMENT>
00387       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00388                                                 const vector<SCALARTYPE, ALIGNMENT>,
00389                                                 op_prod> & proxy);
00390 
00395       template <typename F, unsigned int MAT_ALIGNMENT>
00396       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00397                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00398                                                                           op_prod> & proxy);
00399                                                 
00404       template <typename F, unsigned int MAT_ALIGNMENT>
00405       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00406                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00407                                                                           op_prod> & proxy);
00408 
00413       template <typename F, unsigned int MAT_ALIGNMENT>
00414       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00415                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00416                                                                        op_prod> & proxy);
00417 
00422       template <typename F, unsigned int MAT_ALIGNMENT>
00423       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00424                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00425                                                                        op_prod> & proxy);
00426 
00427       //transposed_matrix_proxy:
00432       template <typename F, unsigned int MAT_ALIGNMENT>
00433       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00434                                                                                                   const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00435                                                                                                   op_trans >,
00436                                                                          const vector<SCALARTYPE, ALIGNMENT>,
00437                                                                          op_prod> & proxy);
00438 
00443       template <typename F, unsigned int MAT_ALIGNMENT>
00444       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00445                                                                                                    const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00446                                                                                                    op_trans >,
00447                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00448                                                                           op_prod> & proxy);
00449                                                 
00454       template <typename F, unsigned int MAT_ALIGNMENT>
00455       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00456                                                                                                    const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00457                                                                                                    op_trans >,
00458                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00459                                                                           op_prod> & proxy);
00460 
00465       template <typename F, unsigned int MAT_ALIGNMENT>
00466       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00467                                                                                                 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00468                                                                                                 op_trans >,
00469                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00470                                                                        op_prod> & proxy);
00471 
00476       template <typename F, unsigned int MAT_ALIGNMENT>
00477       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const matrix_expression< const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00478                                                                                                 const matrix<SCALARTYPE, F, MAT_ALIGNMENT>,
00479                                                                                                 op_trans >,
00480                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00481                                                                        op_prod> & proxy);
00482                                                                        
00483                                                                        
00484                                                                        
00486 
00490       template <unsigned int MAT_ALIGNMENT>
00491       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00492                                                 const vector<SCALARTYPE, ALIGNMENT>,
00493                                                 op_prod> & proxy);
00494 
00499       template <unsigned int MAT_ALIGNMENT>
00500       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00501                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00502                                                                           op_prod> & proxy);
00503                                                 
00508       template <unsigned int MAT_ALIGNMENT>
00509       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00510                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00511                                                                           op_prod> & proxy);
00512 
00517       template <unsigned int MAT_ALIGNMENT>
00518       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00519                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00520                                                                        op_prod> & proxy);
00521 
00526       template <unsigned int MAT_ALIGNMENT>
00527       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const compressed_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00528                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00529                                                                        op_prod> & proxy);
00530 
00531 
00532       //coordinate_matrix<>
00537       template <unsigned int MAT_ALIGNMENT>
00538       vector<SCALARTYPE, ALIGNMENT> & operator=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00539                                                 const vector<SCALARTYPE, ALIGNMENT>,
00540                                                 op_prod> & proxy);
00541 
00546       template <unsigned int MAT_ALIGNMENT>
00547       vector<SCALARTYPE, ALIGNMENT> & operator+=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00548                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00549                                                                           op_prod> & proxy);
00550                                                 
00555       template <unsigned int MAT_ALIGNMENT>
00556       vector<SCALARTYPE, ALIGNMENT> & operator-=(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00557                                                                           const vector<SCALARTYPE, ALIGNMENT>,
00558                                                                           op_prod> & proxy);
00559 
00564       template <unsigned int MAT_ALIGNMENT>
00565       vector<SCALARTYPE, ALIGNMENT> operator+(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00566                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00567                                                                        op_prod> & proxy);
00568 
00573       template <unsigned int MAT_ALIGNMENT>
00574       vector<SCALARTYPE, ALIGNMENT> operator-(const vector_expression< const coordinate_matrix<SCALARTYPE, MAT_ALIGNMENT>,
00575                                                                        const vector<SCALARTYPE, ALIGNMENT>,
00576                                                                        op_prod> & proxy);
00577 
00579 
00580       //enlarge or reduce allocated memory and set unused memory to zero
00586       void resize(size_type new_size, bool preserve = true)
00587       {
00588         assert(new_size > 0);
00589         
00590         if (new_size != size_)
00591         {
00592           unsigned int new_internal_size = viennacl::tools::roundUpToNextMultiple<unsigned int>(new_size, ALIGNMENT);
00593         
00594           std::vector<SCALARTYPE> temp(size_);
00595           if (preserve && size_ > 0)
00596             fast_copy(*this, temp);
00597           temp.resize(new_size);  //drop all entries above new_size
00598           temp.resize(new_internal_size); //enlarge to fit new internal size
00599           
00600           if (new_internal_size != internal_size())
00601           {
00602             elements_ = viennacl::ocl::current_context().create_memory(CL_MEM_READ_WRITE, sizeof(SCALARTYPE)*new_internal_size);
00603           }
00604           
00605           fast_copy(temp, *this);
00606           size_ = new_size;
00607         }
00608         
00609       }
00610       
00611 
00612       //read-write access to an element of the vector
00615       entry_proxy<SCALARTYPE> operator()(size_type index)
00616       {
00617         return entry_proxy<SCALARTYPE>(index, elements_);
00618       }
00619 
00622       entry_proxy<SCALARTYPE> operator[](size_type index)
00623       {
00624         return entry_proxy<SCALARTYPE>(index, elements_);
00625       }
00626 
00627 
00630       scalar<SCALARTYPE> operator()(size_type index) const
00631       {
00632         scalar<SCALARTYPE> tmp;
00633         cl_int err;
00634         err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(), elements_, tmp.handle(), sizeof(SCALARTYPE)*index, 0, sizeof(SCALARTYPE), 0, NULL, NULL);
00635         //assert(err == CL_SUCCESS);
00636         VIENNACL_ERR_CHECK(err);
00637         return tmp;
00638       }
00639       
00642       scalar<SCALARTYPE> operator[](size_type index) const
00643       {
00644         return operator()(index);
00645       }
00646       
00649       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector<SCALARTYPE, ALIGNMENT> & vec)
00650       {
00651         viennacl::linalg::inplace_add(*this, vec);
00652         return *this;
00653       }
00654 
00657       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00658                                                                            const scalar<SCALARTYPE>,
00659                                                                            op_prod> & proxy)
00660       {
00661         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00662         return *this;
00663       }
00664 
00667       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00668                                                                            const scalar<SCALARTYPE>,
00669                                                                            op_prod> & proxy)
00670       {
00671         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00672         return *this;
00673       }
00674 
00677       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00678                                                                            const SCALARTYPE,
00679                                                                            op_prod> & proxy)
00680       {
00681         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00682         return *this;
00683       }
00684 
00687       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00688                                                                            const SCALARTYPE,
00689                                                                            op_prod> & proxy)
00690       {
00691         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), proxy.rhs());
00692         return *this;
00693       }
00694 
00697       vector<SCALARTYPE, ALIGNMENT> & operator += (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00698                                                                            const scalar<SCALARTYPE>,
00699                                                                            op_div> & proxy)
00700       {
00701         viennacl::linalg::inplace_div_add(*this, proxy.lhs(), proxy.rhs());
00702         return *this;
00703       }
00704 
00705 
00706 
00709       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector<SCALARTYPE, ALIGNMENT> & vec)
00710       {
00711         viennacl::linalg::inplace_sub(*this, vec);
00712         return *this;
00713       }
00714 
00717       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00718                                                                            const scalar<SCALARTYPE>,
00719                                                                            op_prod> & proxy)
00720       {
00721         viennacl::linalg::inplace_mul_sub(*this, proxy.lhs(), proxy.rhs());
00722         return *this;
00723       }
00724 
00727       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00728                                                                            const scalar<SCALARTYPE>,
00729                                                                            op_prod> & proxy)
00730       {
00731         viennacl::linalg::inplace_mul_sub(*this, proxy.lhs(), proxy.rhs());
00732         return *this;
00733       }
00734 
00737       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00738                                                                             const SCALARTYPE,
00739                                                                             op_prod> & proxy)
00740       {
00741         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), -proxy.rhs());
00742         return *this;
00743       }
00744 
00747       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00748                                                                             const SCALARTYPE,
00749                                                                             op_prod> & proxy)
00750       {
00751         viennacl::linalg::inplace_mul_add(*this, proxy.lhs(), -proxy.rhs());
00752         return *this;
00753       }
00754       
00757       vector<SCALARTYPE, ALIGNMENT> & operator -= (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00758                                                                             const scalar<SCALARTYPE>,
00759                                                                             op_div> & proxy)
00760       {
00761         viennacl::linalg::inplace_div_sub(*this, proxy.lhs(), proxy.rhs());
00762         return *this;
00763       }
00764       
00765       
00766       
00767 
00770       vector<SCALARTYPE, ALIGNMENT> & operator *= (SCALARTYPE val)
00771       {
00772         viennacl::linalg::inplace_mult(*this, val);
00773         return *this;
00774       }
00775 
00778       vector<SCALARTYPE, ALIGNMENT> & operator *= (scalar<SCALARTYPE> const & gpu_val)
00779       {
00780         viennacl::linalg::inplace_mult(*this, gpu_val);
00781         return *this;
00782       }
00783 
00786       vector<SCALARTYPE, ALIGNMENT> & operator /= (SCALARTYPE val)
00787       {
00788         viennacl::linalg::inplace_mult(*this, static_cast<SCALARTYPE>(1) / val);
00789         return *this;
00790       }
00791       
00794       vector<SCALARTYPE, ALIGNMENT> & operator /= (scalar<SCALARTYPE> const & gpu_val)
00795       {
00796         viennacl::linalg::inplace_divide(*this, gpu_val);
00797         return *this;
00798       }
00799       
00800       
00801       
00802       // free addition
00803       
00806       vector<SCALARTYPE, ALIGNMENT> operator + (const vector<SCALARTYPE, ALIGNMENT> & vec) const
00807       {
00808         vector<SCALARTYPE, ALIGNMENT> result(internal_size());
00809         viennacl::linalg::add(*this, vec, result);
00810         return result;
00811       }
00812       
00815       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00816                                                                          const scalar<SCALARTYPE>,
00817                                                                            op_prod> & proxy) const
00818       {
00819         vector<SCALARTYPE, ALIGNMENT> result(size_);
00820         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
00821         return result;
00822       }
00823 
00826       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00827                                                                          const scalar<SCALARTYPE>,
00828                                                                            op_prod> & proxy) const
00829       {
00830         vector<SCALARTYPE, ALIGNMENT> result(size_);
00831         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
00832         return result;
00833       }
00834 
00837       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00838                                                                          const SCALARTYPE,
00839                                                                          op_prod> & proxy) const
00840       {
00841         vector<SCALARTYPE, ALIGNMENT> result(size_);
00842         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
00843         return result;
00844       }
00845 
00848       vector<SCALARTYPE, ALIGNMENT> operator + (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00849                                                                          const SCALARTYPE,
00850                                                                          op_prod> & proxy) const
00851       {
00852         vector<SCALARTYPE, ALIGNMENT> result(size_);
00853         viennacl::linalg::mul_add(proxy.lhs(), proxy.rhs(), *this, result);
00854         return result;
00855       }
00856 
00857 
00858       //free subtraction:
00861       vector<SCALARTYPE, ALIGNMENT> operator - (const vector<SCALARTYPE, ALIGNMENT> & vec) const
00862       {
00863         vector<SCALARTYPE, ALIGNMENT> result(size_);
00864         viennacl::linalg::sub(*this, vec, result);
00865         return result;
00866       }
00867 
00870       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00871                                                                          const scalar<SCALARTYPE>,
00872                                                                            op_prod> & proxy) const
00873       {
00874         vector<SCALARTYPE, ALIGNMENT> result(size_);
00875         result = *this;
00876         viennacl::linalg::inplace_mul_sub(result, proxy.lhs(), proxy.rhs());
00877         return result;
00878       }
00879 
00882       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00883                                                                          const scalar<SCALARTYPE>,
00884                                                                            op_prod> & proxy) const
00885       {
00886         vector<SCALARTYPE, ALIGNMENT> result(size_);
00887         result = *this;
00888         viennacl::linalg::inplace_mul_sub(result, proxy.lhs(), proxy.rhs());
00889         return result;
00890       }
00891 
00894       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< vector<SCALARTYPE, ALIGNMENT>,
00895                                                                          const SCALARTYPE,
00896                                                                          op_prod> & proxy) const
00897       {
00898         vector<SCALARTYPE, ALIGNMENT> result(size_);
00899         result = *this;
00900         viennacl::linalg::inplace_mul_add(result, proxy.lhs(), -proxy.rhs());
00901         return result;
00902       }
00903 
00906       vector<SCALARTYPE, ALIGNMENT> operator - (const vector_expression< const vector<SCALARTYPE, ALIGNMENT>,
00907                                                                          const SCALARTYPE,
00908                                                                          op_prod> & proxy) const
00909       {
00910         vector<SCALARTYPE, ALIGNMENT> result(size_);
00911         result = *this;
00912         viennacl::linalg::inplace_mul_add(result, proxy.lhs(), -proxy.rhs());
00913         return result;
00914       }
00915 
00916       
00917       //free multiplication
00920       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_prod> 
00921       operator * (SCALARTYPE value) const
00922       {
00923         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_prod>(*this, value);
00924       }
00925 
00928       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_prod> 
00929       operator * (scalar<SCALARTYPE> const & value) const
00930       {
00931         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_prod>(*this, value);
00932       }
00933 
00934       //free division
00937       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_div> 
00938       operator / (SCALARTYPE value) const
00939       {
00940         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const SCALARTYPE, op_div>(*this, value);
00941       }
00942 
00945       vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_div> 
00946       operator / (scalar<SCALARTYPE> const & value) const
00947       {
00948         return vector_expression< const vector<SCALARTYPE, ALIGNMENT>, const scalar<SCALARTYPE>, op_div>(*this, value);
00949       }
00950       
00951       
00953 
00954       iterator begin()
00955       {
00956         return iterator(*this, 0);
00957       }
00958 
00960       iterator end()
00961       {
00962         return iterator(*this, size());
00963       }
00964 
00966       const_iterator begin() const
00967       {
00968         return const_iterator(*this, 0);
00969       }
00970 
00972       const_iterator end() const
00973       {
00974         return const_iterator(*this, size());
00975       }
00976 
00979       vector<SCALARTYPE, ALIGNMENT> & swap(vector<SCALARTYPE, ALIGNMENT> & other)
00980       {
00981         swap(*this, other);
00982         return *this;
00983       };
00984       
00987       vector<SCALARTYPE, ALIGNMENT> & fast_swap(vector<SCALARTYPE, ALIGNMENT> & other) 
00988       { 
00989         assert(this->size_ == other.size_); 
00990         this->elements_.swap(other.elements_); 
00991         return *this; 
00992       };       
00993       
00996       size_type size() const { return size_; }
00997       
01000       size_type max_size() const
01001       {
01002         return (128*1024*1024) / sizeof(SCALARTYPE);  //128 MB is maximum size of memory chunks in OpenCL!
01003       }
01006       size_type internal_size() const { return viennacl::tools::roundUpToNextMultiple<size_type>(size_, ALIGNMENT); }
01007       
01009       bool empty() { return size_ == 0; }
01010       
01012       const viennacl::ocl::handle<cl_mem> & handle() const { return elements_; }
01013 
01016       void clear()
01017       {
01018         viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::program_name(), "clear");
01019         
01020         viennacl::ocl::enqueue(k(elements_, static_cast<cl_uint>(internal_size())));
01021       }
01022       //void swap(vector & other){}
01023       
01024 
01025       //TODO: Think about implementing the following public member functions
01026       //void insert_element(unsigned int i, SCALARTYPE val){}
01027       //void erase_element(unsigned int i){}
01028       
01029     private:
01030       cl_uint size_;
01031       viennacl::ocl::handle<cl_mem> elements_;
01032     }; //vector
01033     
01034 
01035     //
01037     //
01038     
01045     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01046     void copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
01047               const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
01048               CPU_ITERATOR cpu_begin )
01049     {
01050       assert(gpu_end - gpu_begin >= 0);
01051       if (gpu_end - gpu_begin != 0)
01052       {
01053         std::vector<SCALARTYPE> temp_buffer(gpu_end - gpu_begin);
01054         cl_int err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(),
01055                                          gpu_begin.handle(), CL_TRUE, 0, 
01056                                          sizeof(SCALARTYPE)*(gpu_end - gpu_begin),
01057                                          &(temp_buffer[0]), 0, NULL, NULL);
01058         VIENNACL_ERR_CHECK(err);
01059         viennacl::ocl::get_queue().finish();
01060         
01061         //now copy entries to cpu_vec:
01062         std::copy(temp_buffer.begin(), temp_buffer.end(), cpu_begin);
01063       }
01064     }
01065 
01072     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01073     void copy(const vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
01074               const vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
01075               CPU_ITERATOR cpu_begin )
01076 
01077     {
01078       copy(const_vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_begin),
01079            const_vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_end),
01080            cpu_begin);
01081     }
01082     
01088     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01089     void copy(vector<SCALARTYPE, ALIGNMENT> const & gpu_vec,
01090               CPUVECTOR & cpu_vec )
01091     {
01092       viennacl::copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
01093     }
01094 
01095     //from gpu to cpu. Type assumption: cpu_vec lies in a linear memory chunk
01107     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01108     void fast_copy(const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_begin,
01109                    const const_vector_iterator<SCALARTYPE, ALIGNMENT> & gpu_end,
01110                    CPU_ITERATOR cpu_begin )
01111     {
01112       if (gpu_begin != gpu_end)
01113       {
01114         cl_int err = clEnqueueReadBuffer(viennacl::ocl::get_queue().handle(),
01115                                          gpu_begin.handle(), CL_TRUE, 0,
01116                                          sizeof(SCALARTYPE)*(gpu_end - gpu_begin),
01117                                          &(*cpu_begin), 0, NULL, NULL);
01118         VIENNACL_ERR_CHECK(err);
01119         viennacl::ocl::get_queue().finish();
01120       }
01121     }
01122 
01128     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01129     void fast_copy(vector<SCALARTYPE, ALIGNMENT> const & gpu_vec,
01130                    CPUVECTOR & cpu_vec )
01131     {
01132       viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), cpu_vec.begin());
01133     }
01134 
01135 
01136 
01137     #ifdef VIENNACL_HAVE_EIGEN
01138     template <unsigned int ALIGNMENT>
01139     void copy(vector<float, ALIGNMENT> const & gpu_vec,
01140               Eigen::VectorXf & eigen_vec)
01141     {
01142       viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
01143     }
01144     
01145     template <unsigned int ALIGNMENT>
01146     void copy(vector<double, ALIGNMENT> & gpu_vec,
01147               Eigen::VectorXd & eigen_vec)
01148     {
01149       viennacl::fast_copy(gpu_vec.begin(), gpu_vec.end(), &(eigen_vec[0]));
01150     }
01151     #endif
01152 
01153 
01154     //
01156     //
01157 
01158     //from cpu to gpu. Safe assumption: cpu_vector does not necessarily occupy a linear memory segment, but is not larger than the allocated memory on the GPU
01165     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01166     void copy(CPU_ITERATOR const & cpu_begin,
01167               CPU_ITERATOR const & cpu_end,
01168               vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin)
01169     {
01170       if (cpu_begin != cpu_end)
01171       {
01172         //we require that the size of the gpu_vector is larger or equal to the cpu-size
01173         std::vector<SCALARTYPE> temp_buffer(cpu_end - cpu_begin);
01174         std::copy(cpu_begin, cpu_end, temp_buffer.begin());
01175         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(),
01176                                           gpu_begin.handle(), CL_TRUE, sizeof(SCALARTYPE)*gpu_begin.index(),
01177                                           sizeof(SCALARTYPE)*(cpu_end - cpu_begin),
01178                                           &(temp_buffer[0]), 0, NULL, NULL);
01179         VIENNACL_ERR_CHECK(err);
01180       }
01181     }
01182 
01183     // for things like copy(std_vec.begin(), std_vec.end(), vcl_vec.begin() + 1);
01184     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01185     void copy(CPU_ITERATOR const & cpu_begin,
01186               CPU_ITERATOR const & cpu_end,
01187               const_vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin)
01188     {
01189       copy(cpu_begin, cpu_end, vector_iterator<SCALARTYPE, ALIGNMENT>(gpu_begin));
01190     }
01191 
01197     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01198     void copy(const CPUVECTOR & cpu_vec, vector<SCALARTYPE, ALIGNMENT> & gpu_vec)
01199     {
01200       viennacl::copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
01201     }
01202 
01214     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPU_ITERATOR>
01215     void fast_copy(CPU_ITERATOR const & cpu_begin,
01216                    CPU_ITERATOR const & cpu_end,
01217                    vector_iterator<SCALARTYPE, ALIGNMENT> gpu_begin)
01218     {
01219       if (cpu_begin != cpu_end)
01220       {
01221         //we require that the size of the gpu_vector is larger or equal to the cpu-size
01222         cl_int err = clEnqueueWriteBuffer(viennacl::ocl::get_queue().handle(), 
01223                                           gpu_begin.handle(), CL_TRUE, 0, 
01224                                           sizeof(SCALARTYPE)*(cpu_end - cpu_begin), &(*cpu_begin), 0, NULL, NULL);
01225         VIENNACL_ERR_CHECK(err);
01226       }
01227     }
01228 
01229 
01235     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename CPUVECTOR>
01236     void fast_copy(const CPUVECTOR & cpu_vec, vector<SCALARTYPE, ALIGNMENT> & gpu_vec)
01237     {
01238       viennacl::fast_copy(cpu_vec.begin(), cpu_vec.end(), gpu_vec.begin());
01239     }
01240 
01241     #ifdef VIENNACL_HAVE_EIGEN
01242     template <unsigned int ALIGNMENT>
01243     void copy(Eigen::VectorXf const & eigen_vec,
01244               vector<float, ALIGNMENT> & gpu_vec)
01245     {
01246       std::vector<float> entries(eigen_vec.size());
01247       for (size_t i = 0; i<entries.size(); ++i)
01248         entries[i] = eigen_vec(i);
01249       viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
01250     }
01251     
01252     template <unsigned int ALIGNMENT>
01253     void copy(Eigen::VectorXd const & eigen_vec,
01254               vector<double, ALIGNMENT> & gpu_vec)
01255     {
01256       std::vector<double> entries(eigen_vec.size());
01257       for (size_t i = 0; i<entries.size(); ++i)
01258         entries[i] = eigen_vec(i);
01259       viennacl::fast_copy(entries.begin(), entries.end(), gpu_vec.begin());
01260     }
01261     #endif
01262     
01263 
01264 
01265     //
01267     //
01274     template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
01275     void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin,
01276               const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
01277               vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin)
01278     {
01279       assert(gpu_src_end - gpu_src_begin >= 0);
01280       if (gpu_src_begin != gpu_src_end)
01281       {
01282         cl_int err = clEnqueueCopyBuffer(viennacl::ocl::get_queue().handle(),
01283                                           gpu_src_begin.handle(),  //src handle
01284                                           gpu_dest_begin.handle(), //dest handle
01285                                           sizeof(SCALARTYPE) * gpu_src_begin.index(), //src offset
01286                                           sizeof(SCALARTYPE) * gpu_dest_begin.index(), //dest offset
01287                                           sizeof(SCALARTYPE) * (gpu_src_end.index() - gpu_src_begin.index()), //data length
01288                                           0, //don't know -> check!! (something related to increment?)
01289                                           NULL, NULL);
01290         VIENNACL_ERR_CHECK(err);
01291       }
01292     }
01293 
01300     template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
01301     void copy(const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_begin,
01302               const_vector_iterator<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_end,
01303               const_vector_iterator<SCALARTYPE, ALIGNMENT_DEST> gpu_dest_begin)
01304     {
01305       copy(gpu_src_begin, gpu_src_end, vector_iterator<SCALARTYPE, ALIGNMENT_DEST>(gpu_dest_begin));
01306     }
01307 
01313     template <typename SCALARTYPE, unsigned int ALIGNMENT_SRC, unsigned int ALIGNMENT_DEST>
01314     void copy(vector<SCALARTYPE, ALIGNMENT_SRC> const & gpu_src_vec,
01315               vector<SCALARTYPE, ALIGNMENT_DEST> & gpu_dest_vec )
01316     {
01317       viennacl::copy(gpu_src_vec.begin(), gpu_src_vec.end(), gpu_dest_vec.begin());
01318     } 
01319 
01320 
01321     
01322     
01323     
01324 
01325     //global functions for handling vectors:
01330     template<class SCALARTYPE, unsigned int ALIGNMENT>
01331     std::ostream & operator<<(std::ostream & s, vector<SCALARTYPE,ALIGNMENT> const & val)
01332     {
01333       viennacl::ocl::get_queue().finish();
01334       std::vector<SCALARTYPE> tmp(val.size());
01335       copy(val.begin(), val.end(), tmp.begin());
01336       std::cout << "[" << val.size() << "](";
01337       for (typename std::vector<SCALARTYPE>::size_type i=0; i<val.size(); ++i)
01338       {
01339         if (i > 0)
01340           s << ",";
01341         s << tmp[i];
01342       }
01343       std::cout << ")";
01344       return s;
01345     }
01346 
01353     template<class SCALARTYPE, unsigned int ALIGNMENT>
01354     void swap(viennacl::vector<SCALARTYPE, ALIGNMENT> & vec1,
01355               viennacl::vector<SCALARTYPE, ALIGNMENT> & vec2)
01356     {
01357       assert(vec1.size() == vec2.size());
01358 
01359       viennacl::ocl::kernel & k = viennacl::ocl::get_kernel(viennacl::linalg::kernels::vector<SCALARTYPE, ALIGNMENT>::program_name(), "swap");
01360 
01361       viennacl::ocl::enqueue(k(vec1, vec2, static_cast<cl_uint>(vec1.size())));
01362     }
01363     
01369     template <typename SCALARTYPE, unsigned int ALIGNMENT>
01370     vector<SCALARTYPE, ALIGNMENT> & fast_swap(vector<SCALARTYPE, ALIGNMENT> & v1,
01371                                               vector<SCALARTYPE, ALIGNMENT> & v2) 
01372     { 
01373       return v1.fast_swap(v2);
01374     }       
01375     
01376     
01377     
01379 
01384     template <typename SCALARTYPE, unsigned int A>
01385     vector_expression< const vector<SCALARTYPE, A>, const SCALARTYPE, op_prod> operator * (SCALARTYPE const & value, vector<SCALARTYPE, A> const & vec)
01386     {
01387       return vector_expression< const vector<SCALARTYPE, A>, const SCALARTYPE, op_prod>(vec, value);
01388     }
01389 
01395     template <typename SCALARTYPE, unsigned int A>
01396     vector_expression< const vector<SCALARTYPE, A>, const scalar<SCALARTYPE>, op_prod> operator * (scalar<SCALARTYPE> const & value, vector<SCALARTYPE, A> const & vec)
01397     {
01398         return vector_expression< const vector<SCALARTYPE, A>, const scalar<SCALARTYPE>, op_prod>(vec, value);
01399     }
01400 
01401 
01402     //addition and subtraction of two vector_expressions:
01408     template <typename LHS1, typename RHS1, typename OP1,
01409               typename LHS2, typename RHS2, typename OP2>
01410     typename vector_expression< LHS1, RHS1, OP1>::VectorType
01411     operator + (vector_expression< LHS1, RHS1, OP1> const & proxy1,
01412                 vector_expression< LHS2, RHS2, OP2> const & proxy2)
01413     {
01414       assert(proxy1.size() == proxy2.size());
01415       typename vector_expression< LHS1, RHS1, OP1>::VectorType result(proxy1.size());
01416       result = proxy1;
01417       result += proxy2;
01418       return result;
01419     }
01420 
01426     template <typename LHS1, typename RHS1, typename OP1,
01427               typename LHS2, typename RHS2, typename OP2>
01428     typename vector_expression< LHS1, RHS1, OP1>::VectorType
01429     operator - (vector_expression< LHS1, RHS1, OP1> const & proxy1,
01430                 vector_expression< LHS2, RHS2, OP2> const & proxy2)
01431     {
01432       assert(proxy1.size() == proxy2.size());
01433       typename vector_expression< LHS1, RHS1, OP1>::VectorType result(proxy1.size());
01434       result = proxy1;
01435       result -= proxy2;
01436       return result;
01437     }
01438     
01440     
01446     template <typename SCALARTYPE, unsigned int A, typename LHS, typename RHS, typename OP>
01447     vector<SCALARTYPE, A> operator + (vector_expression< LHS, RHS, OP> const & proxy,
01448                                       vector<SCALARTYPE, A> const & vec)
01449     {
01450       assert(proxy.size() == vec.size());
01451       vector<SCALARTYPE, A> result(vec.size());
01452       result = proxy;
01453       result += vec;
01454       return result;
01455     }
01456 
01462     template <typename SCALARTYPE, unsigned int A, typename LHS, typename RHS, typename OP>
01463     vector<SCALARTYPE, A> operator - (vector_expression< LHS, RHS, OP> const & proxy,
01464                                       vector<SCALARTYPE, A> const & vec)
01465     {
01466       assert(proxy.size() == vec.size());
01467       vector<SCALARTYPE, A> result(vec.size());
01468       result = proxy;
01469       result -= vec;
01470       return result;
01471     }
01472 
01473 
01479     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01480     vector<SCALARTYPE> operator * (vector_expression< LHS, RHS, OP> const & proxy,
01481                                    scalar<SCALARTYPE> const & val)
01482     {
01483       vector<SCALARTYPE> result(proxy.size());
01484       result = proxy;
01485       result *= val;
01486       return result;
01487     }
01488 
01494     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01495     vector<SCALARTYPE> operator / (vector_expression< LHS, RHS, OP> const & proxy,
01496                                       scalar<SCALARTYPE> const & val)
01497     {
01498       vector<SCALARTYPE> result(proxy.size());
01499       result = proxy;
01500       result /= val;
01501       return result;
01502     }
01503 
01504 
01506     
01512     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01513     vector<SCALARTYPE> operator * (scalar<SCALARTYPE> const & val,
01514                                    vector_expression< LHS, RHS, OP> const & proxy)
01515     {
01516       vector<SCALARTYPE> result(proxy.size());
01517       result = proxy;
01518       result *= val;
01519       return result;
01520     }
01521     
01527     template <typename SCALARTYPE, typename LHS, typename RHS, typename OP>
01528     viennacl::vector<SCALARTYPE> operator * (SCALARTYPE val,
01529                                    viennacl::vector_expression< LHS, RHS, OP> const & proxy)
01530     {
01531       viennacl::vector<SCALARTYPE> result(proxy.size());
01532       result = proxy;
01533       result *= val;
01534       return result;
01535     }
01536 
01537 }
01538 
01539 #endif

Generated on Sat May 21 2011 20:36:51 for ViennaCL - The Vienna Computing Library by  doxygen 1.7.1