2015-05-12 19 views
5

Có cách nào khác biệt và hiệu quả để tìm giá trị riêng và đối số thực, đối xứng, rất lớn, giả sử 10000x10000, ma trận thưa thớt trong Eigen3? Có một bộ giải mã riêng cho các ma trận dày đặc nhưng không sử dụng thuộc tính của ma trận, ví dụ: đó là sự đối xứng. Hơn nữa tôi không muốn lưu trữ ma trận trong dày đặc.Giá trị riêng biệt thưa thớt bằng cách sử dụng eigen3/thưa thớt

Hoặc (thay thế) có thư viện tốt hơn (+ tài liệu tốt hơn) để làm điều đó không?

Trả lời

4

Armadillo sẽ làm điều này bằng eigs_sym

Lưu ý rằng tính tất cả các giá trị riêng là một hoạt động rất tốn kém bất cứ điều gì bạn làm, thường là những gì được thực hiện là tìm chỉ k lớn nhất, hoặc giá trị riêng nhỏ nhất (đó là những gì điều này sẽ làm).

+0

Đây chính là điều tôi đang tìm kiếm và ngoài ra nó có vẻ là một thư viện nhanh. Vì đây là câu trả lời cho câu hỏi của tôi, tôi sẽ đánh dấu nó là được chấp nhận, nhưng bạn có kinh nghiệm sử dụng Eigen cho loại nhiệm vụ đó không? – Philipp

+0

Không có kinh nghiệm cá nhân sử dụng Eigen cho những thứ này tôi sợ. Tôi có xu hướng sử dụng armadillo khá nhiều dành riêng cho đại số tuyến tính trong c + +. Từ một cái nhìn nhanh qua các tài liệu nó đã không nhìn vào tôi sẽ có bất kỳ cách nào khác để làm những gì bạn muốn mà không cần mã hóa một cái gì đó bằng cách sử dụng một phân hủy QR với ma trận thưa thớt. –

1

Đối với Eigen, có một thư viện có tên là Spectra. Như được mô tả trên trang web của nó, Spectra là một thiết kế lại của thư viện ARPACK sử dụng ngôn ngữ C++.

Không giống như Armadillo, được đề xuất trong another answer, Spectra hỗ trợ long double và bất kỳ loại dấu phẩy động thực khác nào (ví dụ: boost::multiprecision::float128).

Dưới đây là một ví dụ về việc sử dụng (giống như phiên bản trong tài liệu, nhưng thích nghi cho các thí nghiệm với các loại dấu chấm động khác nhau):

#include <Eigen/Core> 
#include <SymEigsSolver.h> // Also includes <MatOp/DenseSymMatProd.h> 
#include <iostream> 
#include <limits> 

int main() 
{ 
    using Real=long double; 
    using Matrix=Eigen::Matrix<Real, Eigen::Dynamic, Eigen::Dynamic>; 

    // We are going to calculate the eigenvalues of M 
    const auto A = Matrix::Random(10, 10); 
    const Matrix M = A + A.transpose(); 

    // Construct matrix operation object using the wrapper class DenseGenMatProd 
    Spectra::DenseSymMatProd<Real> op(M); 

    // Construct eigen solver object, requesting the largest three eigenvalues 
    Spectra::SymEigsSolver<Real, 
          Spectra::LARGEST_ALGE, 
          Spectra::DenseSymMatProd<Real>> eigs(&op, 3, 6); 

    // Initialize and compute 
    eigs.init(); 
    const auto nconv = eigs.compute(); 
    std::cout << nconv << " eigenvalues converged.\n"; 

    // Retrieve results 
    if(eigs.info() == Spectra::SUCCESSFUL) 
    { 
     const auto evalues = eigs.eigenvalues(); 
     std::cout.precision(std::numeric_limits<Real>::digits10); 
     std::cout << "Eigenvalues found:\n" << evalues << '\n'; 
    } 
} 
Các vấn đề liên quan