Saya membandingkan beberapa kode saya dengan "stok" kode MATLAB. Saya terkejut dengan hasilnya.
Saya menjalankan kode sampel (Matriks Jarang)
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;
Hasil:
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.
Untuk Matriks Padat:
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;
Hasil:
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.
Bagaimana sih a \ b begitu mengagumkan?
linear-algebra
performance
matlab
Pemeriksaan resmi
sumber
sumber
Jawaban:
Dalam Matlab, perintah '\' memanggil algoritma yang tergantung pada struktur matriks A dan mencakup pemeriksaan (overhead kecil) pada properti A.
Untuk mengurangi overhead, dimungkinkan untuk menggunakan perintah linsolve di Matlab dan pilih sendiri solver di antara opsi-opsi ini.
sumber
Jika Anda ingin melihat apa yang
a\b
dilakukan untuk matriks khusus Anda, Anda dapat mengaturspparms('spumoni',1)
dan mencari algoritma apa yang membuat Anda terkesan. Sebagai contoh:akan menampilkan
jadi saya bisa melihat bahwa "\" akhirnya menggunakan "CHOLMOD" dalam kasus ini.
sumber
help mldivide
.Untuk matriks jarang, Matlab menggunakan UMFPACK untuk
\
operasi " ", yang, dalam contoh Anda, pada dasarnya dijalankan melalui nilai - nilaia
, membalikkannya, dan mengalikannya dengan nilai - nilai darib
. Namun, untuk contoh ini, Anda harus menggunakanb./diag(a)
, yang jauh lebih cepat.Untuk sistem yang padat, operator backslash sedikit lebih rumit. Deskripsi singkat tentang apa yang dilakukan saat diberikan di sini . Menurut deskripsi itu, dalam contoh Anda, Matlab akan menyelesaikan
a\b
menggunakan substitusi mundur. Untuk matriks kuadrat umum, dekomposisi LU digunakan.sumber
tic; for k=1:100, a\b; end; toc
.Sebagai aturan praktis, jika Anda memiliki matriks tipis kompleksitas yang masuk akal (yaitu, itu tidak harus menjadi stensil 5 poin tetapi sebenarnya bisa menjadi diskritisasi dari persamaan Stokes yang jumlah nonzeros per baris adalah jauh lebih besar dari 5), maka pemecah langsung yang jarang seperti UMFPACK biasanya mengalahkan pemecah Krylov yang berulang jika masalahnya tidak lebih besar dari sekitar mungkin 100.000 yang tidak diketahui.
Dengan kata lain, untuk sebagian besar matriks jarang yang dihasilkan dari diskresi 2d, pemecah langsung adalah alternatif tercepat. Hanya untuk masalah 3d di mana Anda dengan cepat mendapatkan di atas 100.000 yang tidak diketahui apakah penting untuk menggunakan pemecah berulang.
sumber