Büyük simetrik kare seyrek matrislerin (30000x30000'e kadar) en küçük özdeğerlerine karşılık gelen az sayıda (5-500) özvektörü, değerlerin% 0.1'inden daha azının sıfır olmadığı hesaplamaya çalışıyorum.
Şu anda konu hakkında çeşitli mesajlar aracılığıyla anladım shift-invert modunda (sigma = 0.0) scipy.sparse.linalg.eigsh kullanıyorum tercih edilen çözümdür. Ancak, çoğu durumda sorunu çözmek 1 saate kadar sürebilir. Öte yandan, dokümantasyondan beklenen en büyük özdeğerleri (sistemimde alt saniye) istersem işlev çok hızlıdır.
Matlab'a işten daha aşina olduğum için, Octave'deki sorunu çözmeyi denedim, bu da bana aynı sonucu birkaç saniye içinde (sigma = 0) birkaç saniye içinde verdi (alt 10s). Özvektör hesaplamasını içeren algoritmanın bir parametre taramasını yapmak istediğim için, bu tür zaman kazancı python'da da olması harika olurdu.
Öncelikle parametreleri değiştirdim (özellikle tolerans), ancak zaman ölçeklerinde çok fazla değişmedi.
Windows'da Anaconda kullanıyorum, ancak scipy (büyük bir acıydı) tarafından kullanılan LAPACK / BLAS'ı mkl'den (varsayılan Anaconda) OpenBlas'a (belgelere göre Octave tarafından kullanılan) değiştirmeye çalıştım, ancak bir değişiklik göremedim verim.
Kullanılan ARPACK (ve nasıl) hakkında değişecek bir şey olup olmadığını anlayamadım?
Aşağıdaki kod için bir testcase'i aşağıdaki dropbox klasörüne yükledim: https://www.dropbox.com/sh/l6aa6izufzyzqr3/AABqij95hZOvRpnnjRaETQmka?dl=0
Python bölgesinde
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)
Octave'de:
M=dlmread('M.txt');
M=spconvert(M);
[evecs,evals] = eigs(M,6,0);
Herhangi bir yardım appriciated!
Yorum ve önerilere dayanarak denediğim bazı ek seçenekler:
Oktav:
eigs(M,6,0)
ve eigs(M,6,'sm')
bana aynı sonucu ver:
[1.8725e-05 1.0189e-05 7.5622e-06 7.5420e-07 -1.2239e-18 -2.5674e-16]
iken eigs(M,6,'sa',struct('tol',2))
için yakınsak
[1.0423 2.7604 6.1548 11.1310 18.0207 25.3933]
çok daha hızlı, ancak yalnızca tolerans değerleri 2'nin üzerindeyse, aksi takdirde hiç bir şekilde birleşmez ve değerler oldukça farklıdır.
Python:
eigsh(M,k=6,which='SA')
ve eigsh(M,k=6,which='SM')
her ikisi de yakınsama yapmıyor (yakınsamada ARPACK hatası oluşmadı). Sadece eigsh(M,k=6,sigma=0.0)
en küçük olanlar için oktavdan farklı olan bazı özdeğerler (neredeyse bir saat sonra) verir (1 ek küçük değer bile bulunur):
[3.82923317e-17 3.32269886e-16 2.78039665e-10 7.54202273e-07 7.56251500e-06 1.01893934e-05]
Tolerans yeterince yüksekse eigsh(M,k=6,which='SA',tol='1')
, elde edilen diğer değerlere yaklaşan sonuçlar da alırım
[4.28732218e-14 7.54194948e-07 7.56220703e-06 1.01889544e-05, 1.87247350e-05 2.02652719e-05]
yine farklı sayıda küçük özdeğer ile. Hesaplama süresi hala yaklaşık 30 dakikadır. Farklı çok küçük değerler anlaşılabilir olsa da, 0'ın katlarını temsil edebildikleri için, farklı çokluk beni şaşırtıyor.
Ek olarak, henüz çözemediğim SciPy ve Octave'de bazı temel farklılıklar var gibi görünüyor.