ViennaCL - The Vienna Computing Library  1.5.0
viennacl/hankel_matrix.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_HANKEL_MATRIX_HPP
00002 #define VIENNACL_HANKEL_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 
00026 #include "viennacl/forwards.h"
00027 #include "viennacl/vector.hpp"
00028 #include "viennacl/ocl/backend.hpp"
00029 
00030 #include "viennacl/toeplitz_matrix.hpp"
00031 #include "viennacl/fft.hpp"
00032 
00033 #include "viennacl/linalg/hankel_matrix_operations.hpp"
00034 
00035 namespace viennacl {
00041     template<class SCALARTYPE, unsigned int ALIGNMENT>
00042     class hankel_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 hankel_matrix() {}
00053 
00060         explicit hankel_matrix(vcl_size_t rows, vcl_size_t cols) : elements_(rows, cols)
00061         {
00062           assert(rows == cols && bool("Hankel matrix must be square!"));
00063           (void)cols;  // avoid 'unused parameter' warning in optimized builds
00064         }
00065 
00072         void resize(vcl_size_t sz, bool preserve = true)
00073         {
00074             elements_.resize(sz, preserve);
00075         }
00076 
00081         handle_type const & handle() const { return elements_.handle(); }
00082 
00087         toeplitz_matrix<SCALARTYPE, ALIGNMENT> & elements() { return elements_; }
00088         toeplitz_matrix<SCALARTYPE, ALIGNMENT> const & elements() const { return elements_; }
00089 
00093         vcl_size_t size1() const { return elements_.size1(); }
00094 
00098         vcl_size_t size2() const { return elements_.size2(); }
00099 
00105         vcl_size_t internal_size() const { return elements_.internal_size(); }
00106 
00114         entry_proxy<SCALARTYPE> operator()(unsigned int row_index, unsigned int col_index)
00115         {
00116             assert(row_index < size1() && col_index < size2() && bool("Invalid access"));
00117 
00118             return elements_(size1() - row_index - 1, col_index);
00119         }
00120 
00127         hankel_matrix<SCALARTYPE, ALIGNMENT>& operator +=(hankel_matrix<SCALARTYPE, ALIGNMENT>& that)
00128         {
00129             elements_ += that.elements();
00130             return *this;
00131         }
00132 
00133     private:
00134         hankel_matrix(hankel_matrix const &) {}
00135         hankel_matrix & operator=(hankel_matrix const & t);
00136 
00137         toeplitz_matrix<SCALARTYPE, ALIGNMENT> elements_;
00138     };
00139 
00146     template <typename SCALARTYPE, unsigned int ALIGNMENT>
00147     void copy(std::vector<SCALARTYPE> const & cpu_vec, hankel_matrix<SCALARTYPE, ALIGNMENT> & gpu_mat)
00148     {
00149         assert((gpu_mat.size1() * 2 - 1)  == cpu_vec.size() && bool("Size mismatch"));
00150 
00151         copy(cpu_vec, gpu_mat.elements());
00152     }
00153 
00160     template <typename SCALARTYPE, unsigned int ALIGNMENT>
00161     void copy(hankel_matrix<SCALARTYPE, ALIGNMENT> const & gpu_mat, std::vector<SCALARTYPE> & cpu_vec)
00162     {
00163         assert((gpu_mat.size1() * 2 - 1)  == cpu_vec.size() && bool("Size mismatch"));
00164 
00165         copy(gpu_mat.elements(), cpu_vec);
00166     }
00167 
00174     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00175     void copy(hankel_matrix<SCALARTYPE, ALIGNMENT> const & han_src, MATRIXTYPE& com_dst)
00176     {
00177         assert( (viennacl::traits::size1(com_dst) == han_src.size1()) && bool("Size mismatch") );
00178         assert( (viennacl::traits::size2(com_dst) == han_src.size2()) && bool("Size mismatch") );
00179 
00180         vcl_size_t size = han_src.size1();
00181         std::vector<SCALARTYPE> tmp(size * 2 - 1);
00182         copy(han_src, tmp);
00183 
00184         for (vcl_size_t i = 0; i < size; i++)
00185             for (vcl_size_t j = 0; j < size; j++)
00186                 com_dst(i, j) = tmp[i + j];
00187     }
00188 
00195     template <typename SCALARTYPE, unsigned int ALIGNMENT, typename MATRIXTYPE>
00196     void copy(MATRIXTYPE const & com_src, hankel_matrix<SCALARTYPE, ALIGNMENT>& han_dst)
00197     {
00198         assert( (han_dst.size1() == 0 || viennacl::traits::size1(com_src) == han_dst.size1()) && bool("Size mismatch") );
00199         assert( (han_dst.size2() == 0 || viennacl::traits::size2(com_src) == han_dst.size2()) && bool("Size mismatch") );
00200         assert( viennacl::traits::size2(com_src) == viennacl::traits::size1(com_src) && bool("Logic error: non-square Hankel matrix!") );
00201 
00202         vcl_size_t size = viennacl::traits::size1(com_src);
00203 
00204         std::vector<SCALARTYPE> tmp(2*size - 1);
00205 
00206         for (vcl_size_t i = 0; i < size; i++)
00207             tmp[i] = com_src(0, i);
00208 
00209         for (vcl_size_t i = 1; i < size; i++)
00210             tmp[size + i - 1] = com_src(size - 1, i);
00211 
00212         viennacl::copy(tmp, han_dst);
00213     }
00214 
00215     /*template <typename SCALARTYPE, unsigned int ALIGNMENT, unsigned int VECTOR_ALIGNMENT>
00216     void prod_impl(hankel_matrix<SCALARTYPE, ALIGNMENT>& mat,
00217                    vector<SCALARTYPE, VECTOR_ALIGNMENT>& vec,
00218                    vector<SCALARTYPE, VECTOR_ALIGNMENT>& result)
00219     {
00220         prod_impl(mat.elements(), vec, result);
00221         fft::reverse(result);
00222     }*/
00223 
00224     template<class SCALARTYPE, unsigned int ALIGNMENT>
00225     std::ostream & operator<<(std::ostream & s, hankel_matrix<SCALARTYPE, ALIGNMENT>& gpu_matrix)
00226     {
00227         vcl_size_t size = gpu_matrix.size1();
00228         std::vector<SCALARTYPE> tmp(2*size - 1);
00229         copy(gpu_matrix, tmp);
00230         s << "[" << size << "," << size << "](";
00231 
00232         for(vcl_size_t i = 0; i < size; i++) {
00233             s << "(";
00234             for(vcl_size_t j = 0; j < size; j++) {
00235                 s << tmp[i + j];
00236                 //s << (int)i - (int)j;
00237                 if(j < (size - 1)) s << ",";
00238             }
00239             s << ")";
00240         }
00241         s << ")";
00242         return s;
00243     }
00244 
00245     //
00246     // Specify available operations:
00247     //
00248 
00251     namespace linalg
00252     {
00253       namespace detail
00254       {
00255         // x = A * y
00256         template <typename T, unsigned int A>
00257         struct op_executor<vector_base<T>, op_assign, vector_expression<const hankel_matrix<T, A>, const vector_base<T>, op_prod> >
00258         {
00259             static void apply(vector_base<T> & lhs, vector_expression<const hankel_matrix<T, A>, const vector_base<T>, op_prod> const & rhs)
00260             {
00261               // check for the special case x = A * x
00262               if (viennacl::traits::handle(lhs) == viennacl::traits::handle(rhs.rhs()))
00263               {
00264                 viennacl::vector<T> temp(lhs);
00265                 viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), temp);
00266                 lhs = temp;
00267               }
00268               else
00269                 viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), lhs);
00270             }
00271         };
00272 
00273         template <typename T, unsigned int A>
00274         struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const hankel_matrix<T, A>, const vector_base<T>, op_prod> >
00275         {
00276             static void apply(vector_base<T> & lhs, vector_expression<const hankel_matrix<T, A>, const vector_base<T>, op_prod> const & rhs)
00277             {
00278               viennacl::vector<T> temp(lhs);
00279               viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), temp);
00280               lhs += temp;
00281             }
00282         };
00283 
00284         template <typename T, unsigned int A>
00285         struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const hankel_matrix<T, A>, const vector_base<T>, op_prod> >
00286         {
00287             static void apply(vector_base<T> & lhs, vector_expression<const hankel_matrix<T, A>, const vector_base<T>, op_prod> const & rhs)
00288             {
00289               viennacl::vector<T> temp(lhs);
00290               viennacl::linalg::prod_impl(rhs.lhs(), rhs.rhs(), temp);
00291               lhs -= temp;
00292             }
00293         };
00294 
00295 
00296         // x = A * vec_op
00297         template <typename T, unsigned int A, typename LHS, typename RHS, typename OP>
00298         struct op_executor<vector_base<T>, op_assign, vector_expression<const hankel_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> >
00299         {
00300             static void apply(vector_base<T> & lhs, vector_expression<const hankel_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> const & rhs)
00301             {
00302               viennacl::vector<T> temp(rhs.rhs());
00303               viennacl::linalg::prod_impl(rhs.lhs(), temp, lhs);
00304             }
00305         };
00306 
00307         // x = A * vec_op
00308         template <typename T, unsigned int A, typename LHS, typename RHS, typename OP>
00309         struct op_executor<vector_base<T>, op_inplace_add, vector_expression<const hankel_matrix<T, A>, vector_expression<const LHS, const RHS, OP>, op_prod> >
00310         {
00311             static void apply(vector_base<T> & lhs, vector_expression<const hankel_matrix<T, A>, vector_expression<const LHS, const RHS, OP>, op_prod> const & rhs)
00312             {
00313               viennacl::vector<T> temp(rhs.rhs());
00314               viennacl::vector<T> temp_result(lhs);
00315               viennacl::linalg::prod_impl(rhs.lhs(), temp, temp_result);
00316               lhs += temp_result;
00317             }
00318         };
00319 
00320         // x = A * vec_op
00321         template <typename T, unsigned int A, typename LHS, typename RHS, typename OP>
00322         struct op_executor<vector_base<T>, op_inplace_sub, vector_expression<const hankel_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> >
00323         {
00324             static void apply(vector_base<T> & lhs, vector_expression<const hankel_matrix<T, A>, const vector_expression<const LHS, const RHS, OP>, op_prod> const & rhs)
00325             {
00326               viennacl::vector<T> temp(rhs.rhs());
00327               viennacl::vector<T> temp_result(lhs);
00328               viennacl::linalg::prod_impl(rhs.lhs(), temp, temp_result);
00329               lhs -= temp_result;
00330             }
00331         };
00332 
00333 
00334 
00335      } // namespace detail
00336    } // namespace linalg
00337 
00339 }
00340 #endif // VIENNACL_HANKEL_MATRIX_HPP