ViennaCL - The Vienna Computing Library  1.4.2
viennacl/linalg/spai.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_SPAI_HPP
00002 #define VIENNACL_LINALG_SPAI_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 
00028 #include <utility>
00029 #include <iostream>
00030 #include <fstream>
00031 #include <string>
00032 #include <algorithm>
00033 #include <vector>
00034 #include <math.h>
00035 #include <map>
00036 
00037 // ViennaCL includes
00038 #include "viennacl/linalg/detail/spai/spai_tag.hpp"
00039 #include "viennacl/linalg/qr.hpp"
00040 #include "viennacl/linalg/prod.hpp"
00041 #include "viennacl/linalg/detail/spai/spai-dynamic.hpp"
00042 #include "viennacl/linalg/detail/spai/spai-static.hpp"
00043 #include "viennacl/linalg/detail/spai/sparse_vector.hpp"
00044 #include "viennacl/linalg/detail/spai/block_matrix.hpp"
00045 #include "viennacl/linalg/detail/spai/block_vector.hpp"
00046 #include "viennacl/linalg/detail/spai/fspai.hpp"
00047 #include "viennacl/linalg/detail/spai/spai.hpp"
00048 
00049 //boost includes
00050 #include "boost/numeric/ublas/vector.hpp"
00051 #include "boost/numeric/ublas/matrix.hpp"
00052 #include "boost/numeric/ublas/matrix_proxy.hpp"
00053 #include "boost/numeric/ublas/vector_proxy.hpp"
00054 #include "boost/numeric/ublas/storage.hpp"
00055 #include "boost/numeric/ublas/io.hpp"
00056 #include "boost/numeric/ublas/lu.hpp"
00057 #include "boost/numeric/ublas/triangular.hpp"
00058 #include "boost/numeric/ublas/matrix_expression.hpp"
00059 
00060 
00061 namespace viennacl
00062 {
00063     namespace linalg
00064     {
00065         
00066         typedef viennacl::linalg::detail::spai::spai_tag         spai_tag;
00067         typedef viennacl::linalg::detail::spai::fspai_tag        fspai_tag;
00068         
00073         //UBLAS version
00074         template <typename MatrixType>
00075         class spai_precond
00076         {
00077         public:
00078             typedef typename MatrixType::value_type ScalarType;
00079             typedef typename boost::numeric::ublas::vector<ScalarType> VectorType;
00084             spai_precond(const MatrixType& A,
00085                          const spai_tag& tag): tag_(tag){
00086                 
00087                 //VCLMatrixType vcl_Ap((unsigned int)A.size2(), (unsigned int)A.size1()), vcl_A((unsigned int)A.size1(), (unsigned int)A.size2()), 
00088                 //vcl_At((unsigned int)A.size1(), (unsigned int)A.size2());
00089                 //UBLASDenseMatrixType dA = A;
00090                 MatrixType pA(A.size1(), A.size2());
00091                 MatrixType At;
00092                 //std::cout<<A<<std::endl;
00093                 if(!tag_.getIsRight()){
00094                     viennacl::linalg::detail::spai::sparse_transpose(A, At);
00095                 }else{
00096                     At = A;
00097                 }
00098                 pA = At;
00099                 viennacl::linalg::detail::spai::initPreconditioner(pA, spai_m_);
00100                 viennacl::linalg::detail::spai::computeSPAI(At, spai_m_, tag_);
00101                 //(At, pA, tag_.getIsRight(), tag_.getIsStatic(), (ScalarType)_tag.getResidualNormThreshold(), (unsigned int)_tag.getIterationLimit(),
00102                  //_spai_m);
00103                 
00104             }
00108             void apply(VectorType& vec) const {
00109                 vec = viennacl::linalg::prod(spai_m_, vec);
00110             }
00111         private:
00112             // variables
00113             spai_tag tag_;
00114             // result of SPAI
00115             MatrixType spai_m_;
00116         };   
00117         
00118         //VIENNACL version
00119         template <typename ScalarType, unsigned int MAT_ALIGNMENT>
00120         class spai_precond< viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT> >
00121         {
00122             typedef viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT> MatrixType;
00123             typedef boost::numeric::ublas::compressed_matrix<ScalarType> UBLASSparseMatrixType;
00124             typedef viennacl::vector<ScalarType> VectorType;
00125             typedef viennacl::matrix<ScalarType> VCLDenseMatrixType;
00126             
00127             typedef boost::numeric::ublas::vector<ScalarType> UBLASVectorType;
00128         public:
00129             
00134             spai_precond(const MatrixType& A,
00135                          const spai_tag& tag): tag_(tag)
00136             {
00137                 viennacl::linalg::kernels::spai<ScalarType, 1>::init();
00138               
00139                 MatrixType At(A.size1(), A.size2());
00140                 UBLASSparseMatrixType ubls_A, ubls_spai_m;
00141                 UBLASSparseMatrixType ubls_At;
00142                 viennacl::copy(A, ubls_A);;
00143                 if(!tag_.getIsRight()){
00144                     viennacl::linalg::detail::spai::sparse_transpose(ubls_A, ubls_At);
00145                 }
00146                 else{
00147                     ubls_At = ubls_A;
00148                 }
00149                 //current pattern is A
00150                 //pA = ubls_At;
00151                 //execute SPAI with ublas matrix types
00152                 viennacl::linalg::detail::spai::initPreconditioner(ubls_At, ubls_spai_m);
00153                 viennacl::copy(ubls_At, At);
00154                 viennacl::linalg::detail::spai::computeSPAI(At, ubls_At, ubls_spai_m, spai_m_, tag_);
00155                 //viennacl::copy(ubls_spai_m, spai_m_);
00156                 
00157             }
00161             void apply(VectorType& vec) const {
00162                 vec = viennacl::linalg::prod(spai_m_, vec);
00163             }
00164         private:
00165             // variables
00166             spai_tag tag_;
00167             // result of SPAI
00168             MatrixType spai_m_;
00169         };
00170         
00171         
00172         //
00173         // FSPAI
00174         //
00175         
00180         //UBLAS version
00181         template <typename MatrixType>
00182         class fspai_precond
00183         {
00184             typedef typename MatrixType::value_type ScalarType;
00185             typedef typename boost::numeric::ublas::vector<ScalarType> VectorType;
00186             typedef typename boost::numeric::ublas::matrix<ScalarType> UBLASDenseMatrixType;
00187             typedef typename viennacl::matrix<ScalarType> VCLMatrixType;
00188         public:
00189             
00194             fspai_precond(const MatrixType& A,
00195                         const fspai_tag& tag): tag_(tag)
00196             {
00197                 MatrixType pA = A;
00198                 viennacl::linalg::detail::spai::computeFSPAI(A, pA, L, L_trans, tag_);
00199             }
00200             
00204             void apply(VectorType& vec) const 
00205             {
00206               VectorType temp = viennacl::linalg::prod(L_trans, vec);
00207               vec = viennacl::linalg::prod(L, temp);
00208             }
00209             
00210         private:
00211             // variables
00212             const fspai_tag & tag_;
00213             // result of SPAI
00214             MatrixType L;
00215             MatrixType L_trans;
00216         };   
00217         
00218 
00219         
00220         
00221         
00222         //
00223         // ViennaCL version
00224         //
00225         template <typename ScalarType, unsigned int MAT_ALIGNMENT>
00226         class fspai_precond< viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT> >
00227         {
00228             typedef viennacl::compressed_matrix<ScalarType, MAT_ALIGNMENT>   MatrixType;
00229             typedef viennacl::vector<ScalarType> VectorType;
00230             typedef viennacl::matrix<ScalarType> VCLDenseMatrixType;
00231             typedef boost::numeric::ublas::compressed_matrix<ScalarType> UBLASSparseMatrixType;
00232             typedef boost::numeric::ublas::vector<ScalarType> UBLASVectorType;
00233         public:
00234             
00239             fspai_precond(const MatrixType & A,
00240                         const fspai_tag & tag): tag_(tag){
00241                 //UBLASSparseMatrixType ubls_A;
00242                 UBLASSparseMatrixType ublas_A(A.size1(), A.size2());
00243                 UBLASSparseMatrixType pA(A.size1(), A.size2());
00244                 UBLASSparseMatrixType ublas_L(A.size1(), A.size2());
00245                 UBLASSparseMatrixType ublas_L_trans(A.size1(), A.size2());
00246                 viennacl::copy(A, ublas_A);
00247                 //viennacl::copy(ubls_A, vcl_A);
00248                 //vcl_At = viennacl::linalg::prod(vcl_A, vcl_A);
00249                 //vcl_pA = viennacl::linalg::prod(vcl_A, vcl_At);
00250                 //viennacl::copy(vcl_pA, pA);
00251                 pA = ublas_A;
00252                 //execute SPAI with ublas matrix types
00253                 viennacl::linalg::detail::spai::computeFSPAI(ublas_A, pA, ublas_L, ublas_L_trans, tag_);
00254                 //copy back to GPU
00255                 viennacl::copy(ublas_L, L);
00256                 viennacl::copy(ublas_L_trans, L_trans);
00257             }
00258             
00259             
00263             void apply(VectorType& vec) const 
00264             {
00265               VectorType temp(vec.size());
00266               temp = viennacl::linalg::prod(L_trans, vec);
00267               vec = viennacl::linalg::prod(L, temp);
00268             }
00269             
00270         private:
00271             // variables
00272             const fspai_tag & tag_;
00273             MatrixType L;
00274             MatrixType L_trans;
00275         };
00276         
00277         
00278     }
00279 }
00280 #endif