Skylark (Sketching Library)  0.1
/var/lib/jenkins/jobs/Skylark/workspace/algorithms/Krylov/Chebyshev.hpp
Go to the documentation of this file.
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