ViennaCL - The Vienna Computing Library
1.5.1
|
00001 #ifndef VIENNACL_VANDERMONDE_MATRIX_HPP 00002 #define VIENNACL_VANDERMONDE_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 #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