ViennaCL - The Vienna Computing Library  1.5.0
viennacl/vandermonde_matrix.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_VANDERMONDE_MATRIX_HPP
00002 #define VIENNACL_VANDERMONDE_MATRIX_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 
00021 #include <cmath>
00022 
00027 #include "viennacl/forwards.h"
00028 #include "viennacl/vector.hpp"
00029 #include "viennacl/ocl/backend.hpp"
00030 
00031 #include "viennacl/fft.hpp"
00032 
00033 #include "viennacl/linalg/vandermonde_matrix_operations.hpp"
00034 
00035 namespace viennacl {
00041     template<class SCALARTYPE, unsigned int ALIGNMENT>
00042     class vandermonde_matrix
00043     {
00044       public:
00045         typedef viennacl::backend::mem_handle                                                              handle_type;
00046         typedef scalar<typename viennacl::tools::CHECK_SCALAR_TEMPLATE_ARGUMENT<SCALARTYPE>::ResultType>   value_type;
00047 
00052         explicit vandermonde_matrix() {}
00053 
00060         explicit vandermonde_matrix(vcl_size_t rows, vcl_size_t cols) : elements_(rows)
00061         {
00062           assert(rows == cols && bool("Vandermonde matrix must be square in this release!"));
00063           (void)cols;  // avoid 'unused parameter' warning in optimized builds
00064         }
00065 
00072         void resize(vcl_size_t sz, bool preserve = true) {
00073             elements_.resize(sz, preserve);
00074         }
00075 
00080         handle_type const & handle() const { return elements_.handle(); }
00081 
00086         viennacl::vector<SCALARTYPE, ALIGNMENT> & elements() { return elements_; }
00087         viennacl::vector<SCALARTYPE, ALIGNMENT> const & elements() const { return elements_; }
00088 
00092         vcl_size_t size1() const { return elements_.size(); }
00093 
00097         vcl_size_t size2() const { return elements_.size(); }
00098 
00104         vcl_size_t internal_size() const { return elements_.internal_size(); }
00105 
00112         entry_proxy<SCALARTYPE> operator()(vcl_size_t row_index)
00113         {
00114             return elements_[row_index];
00115         }
00116 
00124         SCALARTYPE operator()(vcl_size_t row_index, vcl_size_t col_index) const
00125         {
00126             assert(row_index < size1() && col_index < size2() && bool("Invalid access"));
00127 
00128             return pow(elements_[row_index], static_cast<int>(col_index));
00129         }
00130 
00131     private:
00132         vandermonde_matrix(vandermonde_matrix const &) {}
00133         vandermonde_matrix & operator=(vandermonde_matrix const & t);
00134 
00135         viennacl::vector<SCALARTYPE, ALIGNMENT> elements_;
00136     };
00137 
00144     template <typename SCALARTYPE, unsigned int ALIGNMENT>
00145     void copy(std::vector<SCALARTYPE>& cpu_vec, vandermonde_matrix<SCALARTYPE, ALIGNMENT>& gpu_mat)
00146     {
00147         assert(cpu_vec.size() == gpu_mat.size1()  && bool("Size mismatch"));
00148         copy(cpu_vec, gpu_mat.elements());
00149     }
00150 
00157     template <typename SCALARTYPE, unsigned int ALIGNMENT>
00158     void copy(vandermonde_matrix<SCALARTYPE, ALIGNMENT>& gpu_mat, std::vector<SCALARTYPE>& cpu_vec)
00159     {
00160         assert(cpu_vec.size() == gpu_mat.size1() && bool("Size mismatch"));
00161         copy(gpu_mat.elements(), cpu_vec);
00162     }
00163 
00170     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00171     void copy(vandermonde_matrix<SCALARTYPE, ALIGNMENT>& vander_src, MATRIXTYPE& com_dst)
00172     {
00173         assert(vander_src.size1() == viennacl::traits::size1(com_dst) && bool("Size mismatch"));
00174         assert(vander_src.size2() == viennacl::traits::size2(com_dst) && bool("Size mismatch"));
00175 
00176         vcl_size_t size = vander_src.size1();
00177         std::vector<SCALARTYPE> tmp(size);
00178         copy(vander_src, tmp);
00179 
00180         for(vcl_size_t i = 0; i < size; i++) {
00181             for(vcl_size_t j = 0; j < size; j++) {
00182                 com_dst(i, j) = std::pow(tmp[i], static_cast<int>(j));
00183             }
00184         }
00185     }
00186 
00193     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00194     void copy(MATRIXTYPE& com_src, vandermonde_matrix<SCALARTYPE, ALIGNMENT>& vander_dst)
00195     {
00196         assert( (vander_dst.size1() == 0 || vander_dst.size1() == viennacl::traits::size1(com_src)) && bool("Size mismatch"));
00197         assert( (vander_dst.size2() == 0 || vander_dst.size2() == viennacl::traits::size2(com_src)) && bool("Size mismatch"));
00198 
00199         vcl_size_t size = vander_dst.size1();
00200         std::vector<SCALARTYPE> tmp(size);
00201 
00202         for(vcl_size_t i = 0; i < size; i++)
00203             tmp[i] = com_src(i, 1);
00204 
00205         copy(tmp, vander_dst);
00206     }
00207 
00208     /*template <typename SCALARTYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00209     void prod_impl(vandermonde_matrix<SCALARTYPE, ALIGNMENT>& mat,
00210                    vector<SCALARTYPE, VECTOR_ALIGNMENT>& vec,
00211                    vector<SCALARTYPE, VECTOR_ALIGNMENT>& result) {
00212         assert(mat.size1() == vec.size());
00213 
00214         fft::vandermonde_prod<SCALARTYPE>(mat.handle(), vec.handle(), result.handle(), mat.size1());
00215     } */
00216 
00222     template<class SCALARTYPE, unsigned int ALIGNMENT>
00223     std::ostream & operator<<(std::ostream& s, vandermonde_matrix<SCALARTYPE, ALIGNMENT>& gpu_matrix)
00224     {
00225         vcl_size_t size = gpu_matrix.size1();
00226         std::vector<SCALARTYPE> tmp(size);
00227         copy(gpu_matrix, tmp);
00228         s << "[" << size << "," << size << "](\n";
00229 
00230         for(vcl_size_t i = 0; i < size; i++) {
00231             s << "(";
00232             for(vcl_size_t j = 0; j < size; j++) {
00233                 s << pow(tmp[i], static_cast<SCALARTYPE>(j));
00234                 if(j < (size - 1)) s << ",";
00235             }
00236             s << ")";
00237         }
00238         s << ")";
00239         return s;
00240     }
00241 
00242 
00243     //
00244     // Specify available operations:
00245     //
00246 
00249     namespace linalg
00250     {
00251       namespace detail
00252       {
00253         // x = A * y
00254         template <typename T, unsigned int A>
00255         struct op_executor<vector_base<T>, op_assign, vector_expression<const vandermonde_matrix<T, A>, const vector_base<T>, op_prod> >
00256         {
00257             static void apply(vector_base<T> & lhs, vector_expression<const vandermonde_matrix<T, A>, const vector_base<T>, op_prod> const & rhs)
00258             {
00259               // check for the special case x = A * x
00260               if (viennacl::traits::handle(lhs) == viennacl::traits::handle(rhs.rhs()))
00261               {
00262                 viennacl::vector<T> temp(lhs);
00263                 viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), temp);
00264                 lhs = temp;
00265               }
00266               else
00267                 viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), lhs);
00268             }
00269         };
00270 
00271         template <typename T, unsigned int A>
00272         struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vandermonde_matrix<T, A>, const vector_base<T>, op_prod> >
00273         {
00274             static void apply(vector_base<T> & lhs, vector_expression<const vandermonde_matrix<T, A>, const vector_base<T>, op_prod> const & rhs)
00275             {
00276               viennacl::vector<T> temp(lhs);
00277               viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), temp);
00278               lhs += temp;
00279             }
00280         };
00281 
00282         template <typename T, unsigned int A>
00283         struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vandermonde_matrix<T, A>, const vector_base<T>, op_prod> >
00284         {
00285             static void apply(vector_base<T> & lhs, vector_expression<const vandermonde_matrix<T, A>, const vector_base<T>, op_prod> const & rhs)
00286             {
00287               viennacl::vector<T> temp(lhs);
00288               viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), temp);
00289               lhs -= temp;
00290             }
00291         };
00292 
00293 
00294         // x = A * vec_op
00295         template <typename T, unsigned int A, typename LHS, typename RHS, typename OP>
00296         struct op_executor<vector_base<T>, op_assign, vector_expression<const vandermonde_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> >
00297         {
00298             static void apply(vector_base<T> & lhs, vector_expression<const vandermonde_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> const & rhs)
00299             {
00300               viennacl::vector<T> temp(rhs.rhs());
00301               viennacl::linalg::prod_impl(rhs.lhs(), temp, lhs);
00302             }
00303         };
00304 
00305         // x = A * vec_op
00306         template <typename T, unsigned int A, typename LHS, typename RHS, typename OP>
00307         struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const vandermonde_matrix<T, A>, vector_expression<const LHS, const RHS, OP>, op_prod> >
00308         {
00309             static void apply(vector_base<T> & lhs, vector_expression<const vandermonde_matrix<T, A>, vector_expression<const LHS, const RHS, OP>, op_prod> const & rhs)
00310             {
00311               viennacl::vector<T> temp(rhs.rhs());
00312               viennacl::vector<T> temp_result(lhs);
00313               viennacl::linalg::prod_impl(rhs.lhs(), temp, temp_result);
00314               lhs += temp_result;
00315             }
00316         };
00317 
00318         // x = A * vec_op
00319         template <typename T, unsigned int A, typename LHS, typename RHS, typename OP>
00320         struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const vandermonde_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> >
00321         {
00322             static void apply(vector_base<T> & lhs, vector_expression<const vandermonde_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> const & rhs)
00323             {
00324               viennacl::vector<T> temp(rhs.rhs());
00325               viennacl::vector<T> temp_result(lhs);
00326               viennacl::linalg::prod_impl(rhs.lhs(), temp, temp_result);
00327               lhs -= temp_result;
00328             }
00329         };
00330 
00331       } // namespace detail
00332     } // namespace linalg
00333 
00335 }
00336 
00337 #endif // VIENNACL_VANDERMONDE_MATRIX_HPP