Python'da çok büyük ve seyrek bir bitişiklik matrisinin tüm özdeğerlerini hesaplamanın en hızlı yolu nedir?


12

Scipy.sparse.linalg.eigsh kullanmaktan çok büyük ve seyrek bir bitişiklik matrisinin tüm özdeğerlerini ve özvektörlerini hesaplamanın daha hızlı bir yolu olup olmadığını anlamaya çalışıyorum. matrisin simetri özellikleri. Bir bitişiklik matrisi de ikiliktir, bu da beni daha hızlı bir yol olduğunu düşündürüyor.

Rastgele 1000x1000 seyrek bitişiklik matrisi oluşturdum ve x230 ubuntu 13.04 dizüstü bilgisayarımdaki çeşitli yöntemler arasında karşılaştırma yaptım:

  • scipy.sparse.linalg.eigs: 0.65 saniye
  • scipy.sparse.linalg.eigsh: 0.44 saniye
  • scipy.linalg.eig: 6.09 saniye
  • scipy.linalg. sekiz: 1,60 saniye

Seyrek eigs ve eigsh ile, istenen özdeğerlerin ve özvektörlerin sayısını k, matrisin sırası olarak ayarladım.

Sorun daha büyük matrislerle başlar - 9000x9000 matriste, scipy.sparse.linalg.eigsh 45 dakika sürdü!


1
NB. scipy.sparse.linalg.eigsh olduğunu ARPACK
pv.

4
Takip etmek için, matrisiniz ne kadar büyük olursa, iç özdeğerleri (yani, en büyük veya en küçük özdeğerleri) doğru bir şekilde hesaplama olasılığınız o kadar az olur. Ayrıştırdığınız matristen hangi bilgilere ihtiyacınız var?
Geoff Oxberry

1
Bu soru burada çapraz olarak yayınlanmıştır . Çapraz yayınlanan sürümün kapalı olmasını tavsiye edeceğim.
Aron Ahmadia

2
A ^ k hesaplamak istiyorum. Yeniden düşündükten sonra, böyle bir matrisle, doğrudan çoğaltma (A A A ...) rathen'i hesaplamak için özdeğiştirmeyi kullanmaktan çok daha hızlı olduğunu düşünüyorum. Tabii ki, k bağlıdır.
Noam Peled

2
Evet, doğrudan yap. Özdeğiştirmenin sonuçları seyrek değildir, bu nedenle depolama sorunlarınız olacaktır (o zaman k yeterince büyükse yine A ^ k değildir). Related stackoverflow.com/a/9495457/424631
dranxo

Yanıtlar:


6

FILTLAN , seyrek simetrik matrislerin iç özdeğerlerini hesaplamak için bir C ++ kütüphanesidir. Sadece buna adanmış bir paketin olması, bunun oldukça zor bir sorun olduğunu söylemelidir. Simetrik bir matrisin en büyük veya en küçük birkaç özdeğerini bulmak, Lanczos algoritmasını değiştirerek / ters çevirerek yapılabilir, ancak spektrumun ortası başka bir konudur. Bunu kullanmak istiyorsanız, python'dan bir C ++ programını çağırmak için SWIG kullanabilirsiniz.

Son hedefiniz matrisin büyük güçlerini hesaplamaksa, sadece en büyük özdeğerlere karşılık gelen özvektörleri hesaplayabilirsiniz, büyük güçleri alırken daha küçük modların daha az önemli olacağı bilgisine sahip içerik.

k

Bunlar sizin için zaten açıksa beni affet: numpy'ye float yerine tamsayıdan oluştuğunu söyleyerek matrisin ikili doğasından yararlanabilirsiniz.

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

bir16bir2bir4bir8günlük2kk

Eğer hız endişeniz varsa ve bir NVIDIA GPU'nuz varsa, Python'dan CUSP veya cuSPARSE gibi paralel seyrek lineer cebir kütüphanesini çağırmayı da keşfedebilirsiniz.


1

Daniel Shapero'nun cevabı hakkında yorum yapmak istiyorum ama yeterli SE itibarım yok.

Kabul edilen cevap beni çok karıştırıyor. Bence ters çevirme modunun iç özdeğerleri hesaplamak için kolayca kullanılabileceğini düşünüyorum. Bkz. Https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

Orijinal soruyu cevaplamak için: nadiren büyük bir seyrek matrisin tüm öz değerlerini istemeniz söz konusudur. Genellikle, ekstrüzyon veya bazı iç değer kümeleri istersiniz. Bu durumda, bir Hermitian matrisi eigshiçin daha hızlıdır. Hermityalı olmayanlar için gitmeniz gerekecek eigs. Ve numpy eigveya çok daha hızlı eigh.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.