ViennaCL - The Vienna Computing Library  1.5.0
viennacl/linalg/power_iter.hpp
Go to the documentation of this file.
00001 #ifndef VIENNACL_LINALG_POWER_ITER_HPP_
00002 #define VIENNACL_LINALG_POWER_ITER_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 
00027 #include <cmath>
00028 #include <vector>
00029 #include "viennacl/linalg/bisect.hpp"
00030 #include "viennacl/linalg/prod.hpp"
00031 #include "viennacl/linalg/norm_2.hpp"
00032 
00033 namespace viennacl
00034 {
00035   namespace linalg
00036   {
00038     class power_iter_tag
00039     {
00040       public:
00041 
00047         power_iter_tag(double tfac = 1e-8, vcl_size_t max_iters = 50000) : termination_factor_(tfac), max_iterations_(max_iters) {}
00048 
00050         void factor(double fct){ termination_factor_ = fct; }
00051 
00053         double factor() const { return termination_factor_; }
00054 
00055         vcl_size_t max_iterations() const { return max_iterations_; }
00056         void max_iterations(vcl_size_t new_max) { max_iterations_ = new_max; }
00057 
00058       private:
00059         double termination_factor_;
00060         vcl_size_t max_iterations_;
00061 
00062     };
00063 
00071     template< typename MatrixT >
00072     typename viennacl::result_of::cpu_value_type<typename MatrixT::value_type>::type
00073     eig(MatrixT const& matrix, power_iter_tag const & tag)
00074     {
00075 
00076       typedef typename viennacl::result_of::value_type<MatrixT>::type           ScalarType;
00077       typedef typename viennacl::result_of::cpu_value_type<ScalarType>::type    CPU_ScalarType;
00078       typedef typename viennacl::result_of::vector_for_matrix<MatrixT>::type    VectorT;
00079 
00080       CPU_ScalarType eigenvalue;
00081       vcl_size_t matrix_size = matrix.size1();
00082       VectorT r(matrix_size);
00083       VectorT r2(matrix_size);
00084       std::vector<CPU_ScalarType> s(matrix_size);
00085 
00086       for(vcl_size_t i=0; i<s.size(); ++i)
00087         s[i] = (i % 3) * CPU_ScalarType(0.1234) - CPU_ScalarType(0.5);   //'random' starting vector
00088 
00089       detail::copy_vec_to_vec(s,r);
00090 
00091       //std::cout << s << std::endl;
00092 
00093       double epsilon = tag.factor();
00094       CPU_ScalarType norm = norm_2(r);
00095       CPU_ScalarType norm_prev = 0;
00096       long numiter = 0;
00097 
00098       for (vcl_size_t i=0; i<tag.max_iterations(); ++i)
00099       {
00100         if (std::fabs(norm - norm_prev) / std::fabs(norm) < epsilon)
00101           break;
00102 
00103         r /= norm;
00104         r2 = viennacl::linalg::prod(matrix, r);  //using helper vector r2 for the computation of r <- A * r in order to avoid the repeated creation of temporaries
00105         r = r2;
00106         norm_prev = norm;
00107         norm = norm_2(r);
00108         numiter++;
00109       }
00110 
00111       eigenvalue = norm;
00112       return eigenvalue;
00113     }
00114 
00115 
00116   } // end namespace linalg
00117 } // end namespace viennacl
00118 #endif