ViennaCL - The Vienna Computing Library
1.5.2
|
00001 #ifndef VIENNACL_HANKEL_MATRIX_HPP 00002 #define VIENNACL_HANKEL_MATRIX_HPP 00003 00004 /* ========================================================================= 00005 Copyright (c) 2010-2014, 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