ViennaCL - The Vienna Computing Library
1.5.2
|
00001 #ifndef VIENNACL_LINALG_JACOBI_PRECOND_HPP_ 00002 #define VIENNACL_LINALG_JACOBI_PRECOND_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 00025 #include <vector> 00026 #include <cmath> 00027 #include "viennacl/forwards.h" 00028 #include "viennacl/vector.hpp" 00029 #include "viennacl/compressed_matrix.hpp" 00030 #include "viennacl/tools/tools.hpp" 00031 #include "viennacl/linalg/sparse_matrix_operations.hpp" 00032 #include "viennacl/linalg/row_scaling.hpp" 00033 00034 #include <map> 00035 00036 namespace viennacl 00037 { 00038 namespace linalg 00039 { 00040 00043 class jacobi_tag {}; 00044 00045 00048 template <typename MatrixType, 00049 bool is_viennacl = detail::row_scaling_for_viennacl<MatrixType>::value > 00050 class jacobi_precond 00051 { 00052 typedef typename MatrixType::value_type ScalarType; 00053 00054 public: 00055 jacobi_precond(MatrixType const & mat, jacobi_tag const &) : diag_A(viennacl::traits::size1(mat)) 00056 { 00057 init(mat); 00058 } 00059 00060 void init(MatrixType const & mat) 00061 { 00062 diag_A.resize(viennacl::traits::size1(mat)); //resize without preserving values 00063 00064 for (typename MatrixType::const_iterator1 row_it = mat.begin1(); 00065 row_it != mat.end1(); 00066 ++row_it) 00067 { 00068 bool diag_found = false; 00069 for (typename MatrixType::const_iterator2 col_it = row_it.begin(); 00070 col_it != row_it.end(); 00071 ++col_it) 00072 { 00073 if (col_it.index1() == col_it.index2()) 00074 { 00075 diag_A[col_it.index1()] = *col_it; 00076 diag_found = true; 00077 } 00078 } 00079 if (!diag_found) 00080 throw "ViennaCL: Zero in diagonal encountered while setting up Jacobi preconditioner!"; 00081 } 00082 } 00083 00084 00086 template <typename VectorType> 00087 void apply(VectorType & vec) const 00088 { 00089 assert(viennacl::traits::size(diag_A) == viennacl::traits::size(vec) && bool("Size mismatch")); 00090 for (vcl_size_t i=0; i<diag_A.size(); ++i) 00091 vec[i] /= diag_A[i]; 00092 } 00093 00094 private: 00095 std::vector<ScalarType> diag_A; 00096 }; 00097 00098 00103 template <typename MatrixType> 00104 class jacobi_precond< MatrixType, true> 00105 { 00106 typedef typename viennacl::result_of::cpu_value_type<typename MatrixType::value_type>::type ScalarType; 00107 00108 public: 00109 jacobi_precond(MatrixType const & mat, jacobi_tag const &) : diag_A(mat.size1(), viennacl::traits::context(mat)) 00110 { 00111 init(mat); 00112 } 00113 00114 00115 void init(MatrixType const & mat) 00116 { 00117 detail::row_info(mat, diag_A, detail::SPARSE_ROW_DIAGONAL); 00118 } 00119 00120 00121 template <unsigned int ALIGNMENT> 00122 void apply(viennacl::vector<ScalarType, ALIGNMENT> & vec) const 00123 { 00124 assert(viennacl::traits::size(diag_A) == viennacl::traits::size(vec) && bool("Size mismatch")); 00125 vec = element_div(vec, diag_A); 00126 } 00127 00128 private: 00129 viennacl::vector<ScalarType> diag_A; 00130 }; 00131 00132 } 00133 } 00134 00135 00136 00137 00138 #endif 00139 00140 00141