Cách nhanh nhất để tính toán tất cả các giá trị riêng của một ma trận kề kề rất lớn và thưa thớt trong python là gì?


12

Tôi đang cố gắng tìm hiểu xem có cách nào nhanh hơn để tính toán tất cả các giá trị riêng và hàm riêng của một ma trận kề kề rất lớn và thưa thớt hơn là sử dụng scipy.spude.linalg.eigsh Theo tôi biết, phương pháp này chỉ sử dụng độ thưa thớt và thuộc tính đối xứng của ma trận. Một ma trận kề cũng là nhị phân, điều khiến tôi nghĩ rằng có một cách nhanh hơn để làm điều đó.

Tôi đã tạo một ma trận kề ngẫu nhiên 1000x1000 ngẫu nhiên và so sánh giữa một số phương thức trên máy tính xách tay x230 ub Ubuntu 13.04 của tôi:

  • scipy.spzzy.linalg.eigs: 0,65 giây
  • scipy.spzzy.linalg.eigsh: 0,44 giây
  • scipy.linalg.eig: 6.09 giây
  • scipy.linalg.eigh: 1,60 giây

Với các eigs và eigsh thưa thớt, tôi đặt k, số lượng các giá trị riêng và hàm riêng mong muốn, là thứ hạng của ma trận.

Vấn đề bắt đầu với ma trận lớn hơn - trên ma trận 9000x9000, phải mất scipy.spzzy.linalg.eigsh 45 phút!


1
Lưu ý scipy.spzzy.linalg.eigsh là ARPACK
pv.

4
Để theo dõi, ma trận của bạn càng lớn, bạn càng ít có khả năng tính toán các giá trị riêng bên trong (nghĩa là không phải là giá trị riêng lớn nhất hoặc nhỏ nhất) một cách chính xác. Bạn cần thông tin gì từ ma trận bạn đang phân hủy?
Geoff Oxberry

1
Câu hỏi này đã được đăng chéo ở đây . Tôi sẽ đề nghị rằng phiên bản đăng chéo được đóng lại.
Aron Ahmadia

2
Tôi muốn tính A ^ k. Sau khi suy nghĩ lại, tôi nghĩ với một ma trận như vậy sẽ nhanh hơn nhiều khi tính toán phép nhân trực tiếp (A A A ...) so với sử dụng phép tách rời. Tất nhiên, nó phụ thuộc vào k.
Noam Peled

2
Vâng, làm điều đó trực tiếp. Kết quả của quá trình xuất tinh không thưa thớt nên bạn sẽ gặp vấn đề về lưu trữ (sau đó một lần nữa, A ^ k cũng không đủ nếu k đủ lớn). Liên kết stackoverflow.com/a/9495457/424631
dranxo

Câu trả lời:


6

FILTLAN là một thư viện C ++ để tính toán các giá trị riêng bên trong của các ma trận đối xứng thưa thớt. Thực tế là có cả một gói dành riêng cho điều này sẽ cho bạn biết rằng đó là một vấn đề khá khó khăn. Việc tìm ra một vài giá trị riêng lớn nhất hoặc nhỏ nhất của ma trận đối xứng có thể được thực hiện bằng cách dịch chuyển / đảo ngược và sử dụng thuật toán Lanczos, nhưng giữa phổ là một vấn đề khác. Nếu bạn muốn sử dụng cái này, bạn có thể sử dụng SWIG để gọi chương trình C ++ từ python.

Nếu mục tiêu cuối cùng của bạn là tính toán sức mạnh lớn của ma trận, bạn chỉ có thể tính toán các hàm riêng tương ứng với các giá trị riêng lớn nhất, nội dung trong kiến ​​thức rằng các chế độ nhỏ hơn sẽ ít quan trọng hơn khi bạn có các quyền hạn lớn.

k

Hãy tha thứ cho tôi nếu những điều này đã rõ ràng với bạn: bạn có thể khai thác bản chất nhị phân của ma trận bằng cách nói với numpy rằng nó bao gồm các số nguyên thay vì số float, nói bằng cách sử dụng

a = np.zeros(100,dtype=np.uint)

Một16Một2Một4Mộtsố 8đăng nhập2kk

Bạn cũng có thể khám phá việc gọi một thư viện đại số tuyến tính thưa thớt song song như CUSP hoặc cuSPARSE từ Python nếu tốc độ là mối quan tâm của bạn và bạn có GPU NVIDIA.


1

Tôi muốn bình luận về câu trả lời của Daniel Shapero nhưng tôi không có đủ danh tiếng SE.

Câu trả lời được chấp nhận làm tôi bối rối rất nhiều. Tôi nghĩ chế độ đảo ngược có thể dễ dàng được sử dụng để tính toán giá trị nội địa. Xem: https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

Để trả lời câu hỏi ban đầu: hiếm khi bạn muốn tất cả các giá trị riêng của một ma trận thưa thớt lớn. Thông thường, bạn muốn cực trị hoặc một số cụm giá trị nội thất. Trong trường hợp đó, đối với ma trận Hermiti eigshnhanh hơn. Đối với người không phải là Hermiti, bạn sẽ phải đi cùng eigs. Và chúng nhanh hơn nhiều so với numpy eighay eigh.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.