ViennaCL - The Vienna Computing Library
1.5.0
|
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