ViennaCL - The Vienna Computing Library  1.5.0
viennacl/linalg/jacobi_precond.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_JACOBI_PRECOND_HPP_
00002 #define VIENNACL_LINALG_JACOBI_PRECOND_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 
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