Tôi đang cố gắng tính toán một vài (5-500) hàm riêng tương ứng với các giá trị riêng nhỏ nhất của ma trận thưa đối xứng vuông lớn (lên tới 30000x30000) với ít hơn 0,1% giá trị là khác không.
Tôi hiện đang sử dụng scipy.spzzy.linalg.eigsh trong chế độ shift-invert (sigma = 0.0), mà tôi đã tìm ra qua các bài đăng khác nhau về chủ đề này là giải pháp ưa thích. Tuy nhiên, phải mất tới 1h để giải quyết vấn đề trong hầu hết các trường hợp. Mặt khác, chức năng này rất nhanh, nếu tôi yêu cầu các giá trị riêng lớn nhất (giây phụ trên hệ thống của tôi), được mong đợi từ tài liệu này.
Vì tôi quen thuộc hơn với Matlab từ công việc, tôi đã thử giải quyết vấn đề trong Octave, điều này cho tôi kết quả tương tự bằng cách sử dụng eigs (sigma = 0) chỉ trong vài giây (phụ 10 giây). Vì tôi muốn thực hiện quét tham số của thuật toán bao gồm tính toán eigenvector, loại tăng thời gian đó cũng sẽ rất tuyệt khi có trong python.
Lần đầu tiên tôi thay đổi các tham số (đặc biệt là dung sai), nhưng điều đó không thay đổi nhiều về thời gian.
Tôi đang sử dụng Anaconda trên Windows, nhưng đã thử chuyển LAPACK / BLAS được sử dụng bởi scipy (đó là một nỗi đau rất lớn) từ mkl (Anaconda mặc định) sang OpenBlas (được sử dụng bởi Octave theo tài liệu), nhưng không thể thấy sự thay đổi trong hiệu suất.
Tôi không thể tìm ra, liệu có gì đó để thay đổi về ARPACK đã sử dụng (và làm thế nào) không?
Tôi đã tải lên một testcase cho mã bên dưới vào thư mục dropbox sau: https://www.dropbox.com/sh/l6aa6izufzyzqr3/AABqij95hZOvRpnnjRaETQmka?dl=0
Trong Python
import numpy as np
from scipy.sparse import csr_matrix, csc_matrix, linalg, load_npz
M = load_npz('M.npz')
evals, evecs = linalg.eigsh(M,k=6,sigma=0.0)
Trong Octave:
M=dlmread('M.txt');
M=spconvert(M);
[evecs,evals] = eigs(M,6,0);
Bất kỳ trợ giúp đều được đánh giá cao!
Một số tùy chọn bổ sung tôi đã thử dựa trên các nhận xét và đề xuất:
Octave:
eigs(M,6,0)
và eigs(M,6,'sm')
cho tôi kết quả tương tự:
[1.8725e-05 1.0189e-05 7.5622e-06 7.5420e-07 -1.2239e-18 -2.5674e-16]
trong khi eigs(M,6,'sa',struct('tol',2))
hội tụ đến
[1.0423 2.7604 6.1548 11.1310 18.0207 25.3933]
nhanh hơn nhiều, nhưng chỉ khi các giá trị dung sai lớn hơn 2, nếu không nó hoàn toàn không hội tụ và các giá trị khác nhau mạnh.
Python:
eigsh(M,k=6,which='SA')
và eigsh(M,k=6,which='SM')
cả hai đều không hội tụ (lỗi ARPACK khi không đạt được độ hội tụ). Chỉ eigsh(M,k=6,sigma=0.0)
đưa ra một số giá trị riêng (sau gần một giờ), khác với quãng tám cho những giá trị nhỏ nhất (thậm chí 1 giá trị nhỏ bổ sung được tìm thấy):
[3.82923317e-17 3.32269886e-16 2.78039665e-10 7.54202273e-07 7.56251500e-06 1.01893934e-05]
Nếu dung sai đủ cao, tôi cũng nhận được kết quả eigsh(M,k=6,which='SA',tol='1')
, gần với các giá trị thu được khác
[4.28732218e-14 7.54194948e-07 7.56220703e-06 1.01889544e-05, 1.87247350e-05 2.02652719e-05]
một lần nữa với một số lượng khác nhau nhỏ. Thời gian tính toán vẫn gần 30 phút. Mặc dù các giá trị rất nhỏ khác nhau có thể hiểu được, vì chúng có thể đại diện cho bội số của 0, bội số khác nhau gây trở ngại cho tôi.
Ngoài ra, dường như có một số khác biệt cơ bản trong SciPy và Octave, mà tôi chưa thể tìm ra.