MATLAB ters eğik çizgi operatörü kare matrisler için


36

Birkaç kodumu "stok" MATLAB kodları ile karşılaştırıyordum. Sonuçlara şaşırdım.

Örnek bir kod koştum (Sparse Matrix)

n = 5000;
a = diag(rand(n,1));
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('Inv(A)*B');
tic;inv(a)*b;toc;

Sonuçlar :

    For a\b
    Elapsed time is 0.052838 seconds.

    For LU
    Elapsed time is 7.441331 seconds.

    For Conj Grad
    Elapsed time is 3.819182 seconds.

    Inv(A)*B
    Elapsed time is 38.511110 seconds.

Yoğun Matris için:

n = 2000;
a = rand(n,n);
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('For INV(A)*B');
tic;inv(a)*b;toc;

Sonuçlar:

For a\b
Elapsed time is 0.575926 seconds.

For LU
Elapsed time is 0.654287 seconds.

For Conj Grad
Elapsed time is 9.875896 seconds.

Inv(A)*B
Elapsed time is 1.648074 seconds.

Kahretsin nasıl bu kadar muhteşem?


1
MATLAB'in ters eğik çizgisi, başka bir deyişle, doğrusal denklemler sistemi için doğrudan çözücü, seyrek matris için Multifrontal yöntemini kullanır, bu yüzden A \ B bu kadar harikadır.
Shuhao Cao,

1
Tim Davis'in cise.ufl.edu/research/sparse adresindeki kodunu kullanır . Ayrıca önemsiz olmayan bir probleminiz olduğunda berbat da ortadan
kalkar

1
"LULU" nedir? Neden bir LU faktoringi ve daha sonra doğrudan çözme uygulamasının iyi bir uygulaması olduğunu düşünüyorsunuz?
Jed Brown

3
@Nunoxic Ne uygulaması? Kendin yazdın mı? Yüksek performanslı yoğun doğrusal cebir, genellikle algoritma olarak iyi anlaşılmış olsa da, modern donanım üzerinde verimli bir şekilde uygulanması kolay değildir. En iyi BLAS / Lapack uygulamaları, bu büyüklükteki bir matris için en üst noktaya yaklaşmalıdır. Ayrıca, yorumlarınızdan LU ve Gaussian Eliminasyonun farklı algoritmalar olduğuna inanıyorsunuz.
Jed Brown

1
Intel MKL kullanılarak yazılmış bir Fortran kodu çağırıyor.
12'de

Yanıtlar:


37

Matlab'da '\' komutu, A matrisinin yapısına bağlı olan ve A'nın özelliklerine ilişkin kontrolleri (küçük yükü) içeren bir algoritma çağırır.

  1. A seyrek ve bantlı ise, bantlı bir çözücü kullanın.
  2. A, bir üst ya da alt üçgen matris ise, geriye doğru bir ikame algoritması kullanın.
  3. Eğer A simetrik ise ve gerçek pozitif köşegen unsurlara sahipse, bir Cholesky faktoringi deneyin. A seyrekse, doldurmayı en aza indirmek için önce yeniden sıralama uygulayın.
  4. Yukarıdaki kriterlerden hiçbiri yerine getirilmezse, kısmi dönme ile Gauss eleme işlemini kullanarak genel bir üçgen faktörlendirme yapın.
  5. A seyrekse, UMFPACK kütüphanesini kullanın.
  6. A kare değilse, belirsiz sistemler için QR faktoringine dayalı algoritmalar kullanın.

Yükü azaltmak için Matlab'da linsolve komutunu kullanmak ve bu seçenekler arasından kendiniz için uygun bir çözücü seçmek mümkündür.


10000x10000 yapılandırmasız yoğun matrisle sıfırdan farklı (Yüksek yoğunluklu) tüm öğelerle uğraştığımı varsayarsak en iyi bahisim ne olurdu? Yoğun matrisler için çalışan bu 1 algoritmayı izole etmek istiyorum. LU, QR veya Gauss Eliminasyonu mu?
Soruşturma

1
Gauss Eliminasyonunun çağrıldığı 4. Adım gibi geliyor; bu, performansı artırmak için A yapısının kullanılamadığı en genel duruma karşılık geliyor. Bu nedenle, temel olarak bu bir LU faktoringi ve ardından bir ileri geri ardından bir değiştirme ornatımıdır.
Allan P. Engsig-Karup,

Teşekkürler! Sanırım bu bana düşünmem için bir yön veriyor. Şu anda Gauss Elimi, bu tür yapılandırılmamış problemleri çözmek için elimizdeki en iyisidir, doğru mu?
Soruşturma

37

a\bÖzel matrisiniz için ne yaptığını görmek spparms('spumoni',1)istiyorsanız, etkilendiğiniz algoritmayı tam olarak ayarlayabilir ve anlayabilirsiniz. Örneğin:

spparms('spumoni',1);
A = delsq(numgrid('B',256));
b = rand(size(A,2),1);
mldivide(A,b);  % another way to write A\b

çıkacak

sp\: bandwidth = 254+1+254.
sp\: is A diagonal? no.
sp\: is band density (0.01) > bandden (0.50) to try banded solver? no.
sp\: is A triangular? no.
sp\: is A morally triangular? no.
sp\: is A a candidate for Cholesky (symmetric, real positive diagonal)? yes.
sp\: is CHOLMOD's symbolic Cholesky factorization (with automatic reordering) successful? yes.
sp\: is CHOLMOD's numeric Cholesky factorization successful? yes.
sp\: is CHOLMOD's triangular solve successful? yes.

bu yüzden "\" nin bu durumda "CHOLMOD" ile bittiğini görebiliyorum.


3
Hiç duymadığım yeni MATLAB ayarları için +1. İyi oyundu efendim.
Geoff Oxberry

2
Hey teşekkürler! İçinde help mldivide.
dranxo

16

Seyrek matrisler için, Matlab " \" işlemi için UMFPACK'i kullanır ; bu, örneğinizde, temelde değerleri atersine çevirir ve değerleri ile çarpar b. Bu örnek için, yine de b./diag(a)daha hızlı kullanmanız gerekir .

Yoğun sistemler için ters eğik çizgi operatörü biraz daha karmaşıktır. Verildiğinde ne kısa bir açıklaması yapılır burada . Bu açıklamaya göre, örneğin, Matlab a\bgeriye doğru ikameyi kullanarak çözecektir . Genel kare matrisler için bir LU ayrışımı kullanılır.


Regd. Seyreklik, bir diag matrisinin inv'i basitçe köşegen elemanların tersi olur, bu yüzden b./diag(a) çalışacaktı, ancak a b, genel seyrek matrisler için de olağandışı bir şekilde çalışıyor. Neden linsolve veya LULU (LU’nun optimize edilmiş versiyonum değil), bu durumda yoğun matrisler için a \ b'den daha hızlı değildir.
Soruşturma

@ Adoxic LULU'nuz, yoğun matrisin köşegenliğini veya üçgenliğini tespit etmek için herhangi bir şey yapıyor mu? Aksi halde, içeriğinden veya yapısından bağımsız olarak her matris için uzun sürecektir.
Pedro

Biraz. Ancak, Linsolve OPT bayrakları ile yapı hakkında tanımlamak için her şeyi tanımladım. Ancak, bir \ b daha hızlı.
tahkikat

@Nunoxic, bir kullanıcı işlevini her çağırdığınızda, genel masraflara neden olursunuz. Matlab ters eğik çizgi için dahili olarak her şeyi yapar, örneğin sağ tarafın ayrışması ve ardından uygulanması, çok az ek yüke sahip olması nedeniyle daha hızlı olacaktır. Ayrıca, testlerinizde, güvenilir zamanlamalar elde etmek için birden fazla çağrı kullanmanız gerekir tic; for k=1:100, a\b; end; toc.
Pedro

5

Genel bir kural olarak, eğer makul bir karmaşıklığa sahip seyrek bir matrisiniz varsa (yani, 5-nokta stencil olması gerekmez, ama aslında sıra başına sıfır sayısının olduğu Stokes denklemlerinin ayrıklaştırılması olabilir. 5'ten çok daha büyükse), o zaman UMFPACK gibi seyrek bir doğrudan çözücü tipik olarak, problem yaklaşık 100.000 bilinmeyenden daha büyük değilse, yinelemeli bir Krylov çözücüyü yener.

Başka bir deyişle, 2d takdirsizleştirmelerden kaynaklanan çoğu seyrek matris için doğrudan bir çözücü en hızlı alternatiftir. Yalnızca hızlıca 100.000 bilinmeyenin üzerine çıktığınız 3B sorunlar için, yinelemeli bir çözücü kullanmak zorunlu hale gelir.


3
Bunun soruyu nasıl cevapladığı benim için net değil, ancak öncül ile de ilgileniyorum. Direkt çözücüler, mütevazı büyüklükteki 2D problemleri için iyi çalışma eğilimindedir, fakat direkt çözücüler 100k bilinmeden önce 3D'de iyi acı çekmeye meyillidirler (tepe ayırıcılar 2D'den çok daha büyüktür). Ayrıca, çoğu durumda (örneğin eliptik operatörler), yinelemeli çözücülerin orta boyutlu 2B problemlerde bile doğrudan çözücülerden daha hızlı yapılabileceğini, ancak bunu yapmak için büyük çaba sarf edebileceğini iddia ediyorum (örneğin, multidrid performansı elde etmek için doğru malzemeleri kullanmak). .
Jed Brown

1
Sorunlarınız oldukça küçükse ve örtük çözücüler tasarlamayı düşünmek istemiyorsanız veya sorunlarınız çok zorsa (yüksek frekanslı Maxwell gibi) ve kariyerinizi iyi çözücüler tasarlamaya adamak istemiyorsanız, o zaman ben seyrek doğrudan çözücülerin mükemmel bir seçim olduğuna katılıyorum.
Jed Brown

Aslında benim sorunum iyi ve yoğun bir çözücü tasarlamaktır. Bunun gibi özel bir uygulamam yok (Dolayısıyla, yapı yok). Kodlarımdan birkaçını değiştirmek ve onları şu anda kullanılanlarla rekabet edebilmek istedim. Sadece bir b hakkında ve her zaman kodumun saçmalığını nasıl geçtiğini merak ediyordum.
tahkikat

@JedBrown: Evet, belki de kayda değer miktarda çabayla, 2d problemlerinde bile yinelemeli çözücüler doğrudan çözücüyü geçebilir. Ama neden yapıyorsun? <100k bilinmeyenlerle ilgili sorunlar için, 2d'deki seyrek doğrudan çözücüler yeterince hızlıdır. Söylemek istediğim şudur: bu küçük problemler için zamanınızı kontrol etmek ve en iyi parametre kombinasyonunu bulmak için harcamayın - sadece kara kutuyu alın.
Wolfgang Bangerth,

5 noktalı bir şablon kullanarak (~ 0.05 saniye ile karşılaştırıldığında ~ 0.5 saniye) 100k dofs ile "kolay" 2D problemleri için seyrek bir Cholesky ve (matris tabanlı) geometrik multigrid arasında bir büyüklük çalışma zamanı farkı sırası var. Şablonunuz ikinci komşular kullanıyorsa (örneğin dördüncü dereceden kararsızlaştırma, bazı doğrusal olmayan reoloji, dengeleme vb. Seçenekler için Newton), köşe ayırıcılarının boyutu kabaca ikiye katlanır, bu nedenle doğrudan çözmenin maliyeti yaklaşık 8 kat artar (maliyet daha fazladır) MG için soruna bağlı). Birçok zaman adımında veya optimizasyon / UQ döngülerinde bu farklılıklar önemlidir.
Jed Brown
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.