Skylark (Sketching Library)
0.1
|
00001 #ifndef SKYLARK_CHEBYSHEV_HPP 00002 #define SKYLARK_CHEBYSHEV_HPP 00003 00004 #include "../../base/base.hpp" 00005 #include "../../utility/elem_extender.hpp" 00006 #include "../../utility/typer.hpp" 00007 #include "../../utility/external/print.hpp" 00008 #include "precond.hpp" 00009 00010 namespace skylark { namespace nla { 00011 00012 // We can have a version that is indpendent of Elemental. But that will 00013 // be tedious (convert between [STAR,STAR] and vector<T>, and really 00014 // elemental is a very fudmanetal to Skylark. 00015 #if SKYLARK_HAVE_ELEMENTAL 00016 00022 template<typename MatrixType, typename RhsType, typename SolType> 00023 void ChebyshevLS(const MatrixType& A, const RhsType& B, SolType& X, 00024 double sigma_L, double sigma_U, 00025 iter_params_t params = iter_params_t(), 00026 const precond_t<SolType>& P = id_precond_t<SolType>()) { 00027 00028 typedef typename utility::typer_t<MatrixType>::value_type value_t; 00029 typedef typename utility::typer_t<MatrixType>::index_type index_t; 00030 00031 typedef MatrixType matrix_type; 00032 typedef RhsType rhs_type; // Also serves as "long" vector type. 00033 typedef SolType sol_type; // Also serves as "short" vector type. 00034 00035 typedef utility::print_t<rhs_type> rhs_print_t; 00036 typedef utility::print_t<sol_type> sol_print_t; 00037 00038 bool log_lev1 = params.am_i_printing && params.log_level >= 1; 00039 bool log_lev2 = params.am_i_printing && params.log_level >= 2; 00040 00042 index_t m = base::Height(A); 00043 index_t n = base::Width(A); 00044 index_t k = base::Width(B); 00045 00047 const value_t eps = 32*std::numeric_limits<value_t>::epsilon(); 00048 if (params.tolerance<eps) params.tolerance=eps; 00049 else if (params.tolerance>=1.0) params.tolerance=(1-eps); 00050 else {} /* nothing */ 00051 00052 double its = (std::log(params.tolerance) - std::log(2)) 00053 / std::log((sigma_U - sigma_L)/(sigma_U + sigma_L)) + 1; 00054 00055 double d = (sigma_U * sigma_U + sigma_L * sigma_L) / 2; 00056 double c = (sigma_U * sigma_U - sigma_L * sigma_L) / 2; 00057 00058 base::Zero(X); 00059 rhs_type R(B); 00060 sol_type V(X), AR(X); 00061 00062 double alpha = 0.0, beta = 0.0; 00063 for(int i = 0; i < its; i++) { 00064 switch(i) { 00065 case 0: 00066 beta = 0.0; 00067 alpha = 1.0 / d; 00068 break; 00069 00070 case 1: 00071 beta = (c * c) / (d * d * 2); 00072 alpha = 1 / (d - c * c / (2 * d)); 00073 break; 00074 00075 default: 00076 beta = alpha * alpha * c * c / 4.0; 00077 alpha = 1 / (d - alpha * c * c / 4.0); 00078 break; 00079 } 00080 00081 base::Gemm(elem::ADJOINT, elem::NORMAL, 1.0, A, R, AR); 00082 P.apply_adjoint(AR); 00083 base::Scal(beta, V); 00084 base::Axpy(1.0, AR, V); 00085 P.apply(V); 00086 base::Axpy(alpha, V, X); 00087 base::Gemm(elem::NORMAL, elem::NORMAL, -alpha, A, V, 1.0, R); 00088 } 00089 } 00090 00091 #endif 00092 00093 } } 00095 #endif // SKYLARK_CHEBYSHEV_HPP