2013-08-31 32 views
18

Şu anda küçük bir matris yönelimli matematik kitaplığı geliştirmeye çalışıyorum (matris veri yapıları ve işlemleri için Eigen 3 kullanıyorum) ve bazılarını uygulamak istedim Lineer sistemlerin (matris formunda ifade edilen) çözümünü hesaplamak için yaygın olarak kullanılan ters eğik çizgi operatör (mldivide'a eşdeğer) gibi kullanışlı Matlab işlevleri.Matlab'ın mldivide (aka ters eğik çizgi operatörü "") nasıl uygulanır

Bunun nasıl başarılabileceği konusunda iyi bir açıklama var mı?

Teşekkür

(Zaten Moore-Penrose klasik SVD ayrışma ile pinv fonksiyonunu pseudoinverse uyguladık, ama ben sadece bunu A\b Matalb değil en azından, her zaman pinv(A)*b olmadığını okumuştum)
+2

Çok basit değil ve ben denemeye karşı son derece öneriyoruz. Sadece LAPACK'ın DGEMV'sine bağlanın. Bir sürü akıllı insan çok fazla zaman harcayarak 'mldivide' ayarladı. –

+0

Benzer soru: [MATLAB backslash operatörü, kare matrisler için Ax = b nasıl çözülür?] (Http://scicomp.stackexchange.com/questions/1001/how-does-the-matlab-backslash-operator-solve-ax -b-for-kare matrisler) – Amro

+0

@Amro, woohoo Sorum. LOL –

cevap

33

x = A\b için, backslash operatörü, farklı giriş matrislerini işlemek için bir dizi algorithms'u kapsar. Böylece A matrisi teşhis edilir ve özelliklerine göre bir yürütme yolu seçilir.

kare olmayan matrisler için
if size(A,1) == size(A,2)   % A is square 
    if isequal(A,tril(A))   % A is lower triangular 
     x = A \ b;    % This is a simple forward substitution on b 
    elseif isequal(A,triu(A))  % A is upper triangular 
     x = A \ b;    % This is a simple backward substitution on b 
    else 
     if isequal(A,A')   % A is symmetric 
      [R,p] = chol(A); 
      if (p == 0)   % A is symmetric positive definite 
       x = R \ (R' \ b); % a forward and a backward substitution 
       return 
      end 
     end 
     [L,U,P] = lu(A);   % general, square A 
     x = U \ (L \ (P*b));  % a forward and a backward substitution 
    end 
else        % A is rectangular 
    [Q,R] = qr(A); 
    x = R \ (Q' * b); 
end 

, QR decomposition kullanılır: A tam matris olduğunda

aşağıdaki page sözde kod tarif etmektedir. Kare üçgen matrisler için basit bir forward/backward substitution gerçekleştirir. Kare simetrik pozitif kesin matrisler için, Cholesky decomposition kullanılır. Aksi halde genel kare matrisler için LU decomposition kullanılır.

Güncelleme: MathWorks bazı güzel akış çizelgeleri ile mldivide ait doc sayfasında algorithm section güncelledi. Bkz. here ve here (tam ve seyrek durumlar).

bu algoritmaların tamamı

mldivide_full

LAPACK karşılık gelen yöntemler var ve aslında MATLAB ne yaptığını muhtemelen (optimize Intel MKL uygulaması ile MATLAB geminin o son sürümlerini dikkat edin).

Farklı yöntemlere sahip olmanın nedeni, katsayı matrisinin tüm özelliklerinden yararlanan denklemler sistemini çözmek için en spesifik algoritmayı kullanmaya çalışmasıdır (daha hızlı veya daha sayısal olarak kararlı olması nedeniyle). Yani kesinlikle bir genel çözücü kullanabilirsiniz, ama en verimli olmayacaktır.

Aslında, A'un neye benzediğini biliyorsanız, linsolve numaralı telefonu arayarak ve seçenekleri doğrudan belirterek ek test işlemini atlayabilirsiniz. , Yukarıdakilerin hepsi yoğun matrisleri için geçerlidir

x = pinv(A)*b 

:

A eğer siz de en az kareler çözeltisi (SVD decomposition kullanılarak uygulanır) minimal bir normunu bulmak için PINV kullanabilir, dikdörtgen ya da tekil olduğu seyrek matrisler tamamen farklı bir hikaye. Bu tür durumlarda genellikle iterative solvers kullanılır. MATLAB'ın, doğrudan çözücüler için SuiteSpase paketinden UMFPACK ve diğer ilgili kitaplıkları kullandığını düşünüyorum.seyrek matrisler ile çalışırken

, sen spparms kullanılarak seçilen gerçekleştirilen testleri ve algoritmalar tanılama bilgilerini açıp görebilirsiniz:

spparms('spumoni',2) 
x = A\b; 
Dahası

, ters eğik çizgi operatörü ayrıca gpuArray 's çalışır, Bu durumda, GPU üzerinde yürütmek için cuBLAS ve MAGMA'a güvenir.

Ayrıca dağıtılmış bilgi işlem ortamlarında çalışan (her bir işçinin dizinin yalnızca bir parçasının bulunduğu bir kümelenme kümesine bölünmüş çalışma, muhtemelen tüm matrisin bellekte aynı anda depolanamadığı) distributed arrays için uygulanır. Temel uygulama, ScaLAPACK kullanıyor. Bunların tümü uygulamak istiyorsanız oldukça istek bu

Kendinizi :)

+0

Teşekkür ederim Amro, bu çok yapıcı bir cevaptı. "A" nın karesel olmayan bir matris olması muhtemeldir, bu yüzden doğru anlaşılsaydı, kullanılacak en uygun yöntem QR ayrıştırmasıdır. Ve evet, biraz kendi kendine yeten bir kütüphane yapmak için gerekli olanı uygulamak (en azından yapmaya çalışıyorum), bu yüzden diğer matematik paketlerini kullanmak istemiyorum (algoritmaların verimliliği, şimdilik, birincil amacım değil;)). Kişisel bir proje, şu an için ciddi bir şey yok ... – 865719

+2

@ M4XMX: Evet, QR ayrışmasını kullanabilirsiniz: Ax = b -> QRx = b -> Rx = Q'b -> x = R \ (Q'b) '(son adımın basit bir geriye doğru ikame süreci olduğu). Açıklama için bkz. [Burada] (https://inst.eecs.berkeley.edu/~ee127a/book/login/l_lineqs_solving.html). Ayrıca, çeşitli kütüphaneleri kullanarak "Ax = b" nin nasıl çözüleceğini gösteren ilgili bir [soru] (http://stackoverflow.com/q/7949229/97160): GSL, Armadillo, Eigen. Tekerleği yeniden icat etmeye gerek yok :) – Amro

+2

Bence MATLAB, sayısal doğruluğu geliştirmek için [pivot] (https://en.wikipedia.org/wiki/QR_decomposition#Column_pivoting) kullanıyor olabilir. Bu, ayrıştırmadır: AP = QR, burada P, bir permütasyon matrisi – Amro

İlgili konular