1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64
| #include <RcppEigen.h> #include <R_ext/Lapack.h> #include <R_ext/BLAS.h>
using Eigen::Map; using Eigen::MatrixXd; using Eigen::VectorXd; using Eigen::VectorXi;
Rcpp::List eigen_sym_cpp(Rcpp::NumericMatrix xr, int num_eig = -1, bool eigenvalues_only = false, double tol = 1.5e-8) { MatrixXd A = MatrixXd::Map(xr.begin(), xr.nrow(), xr.ncol()); char jobz = eigenvalues_only ? 'N' : 'V', range = (num_eig == -1) ? 'A' : 'I', uplo = 'U'; int N = A.rows(), info = 0; int il = (num_eig == -1) ? 1 : (N - num_eig + 1), M = N - il + 1; double abstol = tol, vl = 0.0, vu = 0.0; int lwork = -1, liwork = -1, iwork_query; VectorXi isuppz(2 * M); VectorXd W(M); MatrixXd Z(N, M); double work_qeury; F77_CALL(dsyevr)(&jobz, &range, &uplo, &N, A.data(), &N, &vl, &vu, &il, &N, &abstol, &M, W.data(), Z.data(), &N, isuppz.data(), &work_qeury, &lwork, &iwork_query, &liwork, &info); lwork = (int) work_qeury; liwork = iwork_query; VectorXd work(lwork); VectorXi iwork(liwork); F77_CALL(dsyevr)(&jobz, &range, &uplo, &N, A.data(), &N, &vl, &vu, &il, &N, &abstol, &M, W.data(), Z.data(), &N, isuppz.data(), work.data(), &lwork, iwork.data(), &liwork, &info);
W.reverseInPlace(); if (eigenvalues_only) return Rcpp::List::create( Rcpp::Named("LAPACK_info") = info, Rcpp::Named("values") = W ); MatrixXd Z2 = Z.rowwise().reverse(); return Rcpp::List::create( Rcpp::Named("LAPACK_info") = info, Rcpp::Named("vectors") = Z2, Rcpp::Named("values") = W ); }
|