Làm thế nào để toán tử dấu gạch chéo MATLAB giải cho ma trận vuông?


36

Tôi đã so sánh một vài mã của tôi với mã MATLAB "chứng khoán". Tôi ngạc nhiên với kết quả.

Tôi đã chạy một mã mẫu (Ma trận thưa thớt)

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;

Các kết quả :

    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.

Đối với ma trận dày đặc:

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;

Các kết quả:

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.

Làm thế quái nào là một \ b tuyệt vời như vậy?


1
Dấu gạch chéo ngược tích hợp của MATLAB, nói cách khác, bộ giải trực tiếp cho hệ phương trình tuyến tính, sử dụng phương pháp Multifrontal cho ma trận thưa thớt, đó là lý do tại sao A \ B rất tuyệt vời.
Shuhao Cao

1
Nó sử dụng mã của Tim Davis có sẵn tại cise.ufl.edu/research/spzzy . Ngoài ra, sự tuyệt vời sẽ biến mất khi bạn gặp phải một vấn đề không hề nhỏ
stali

1
"LULU" là gì? Tại sao bạn nghĩ rằng đó là một triển khai tốt của một yếu tố LU và giải quyết trực tiếp tiếp theo?
Jed Brown

3
@Nunoxic thực hiện? Bạn đã tự viết nó? Đại số tuyến tính dày đặc hiệu suất cao, trong khi thường được hiểu rõ về mặt thuật toán, không dễ thực hiện hiệu quả trên phần cứng hiện đại. Việc triển khai BLAS / Lapack tốt nhất sẽ đạt gần đến đỉnh điểm cho một ma trận có kích thước đó. Ngoài ra, từ nhận xét của bạn, tôi nhận được ấn tượng rằng bạn nghĩ LU và Gaussian Elimination là các thuật toán khác nhau.
Jed Brown

1
Nó gọi mã Fortran được viết bằng Intel MKL.
Thắc mắc

Câu trả lời:


37

Trong Matlab, lệnh '\' gọi một thuật toán phụ thuộc vào cấu trúc của ma trận A và bao gồm các kiểm tra (chi phí nhỏ) trên các thuộc tính của A.

  1. Nếu A thưa thớt và có dải, sử dụng một bộ giải dải.
  2. Nếu A là ma trận tam giác trên hoặc dưới, sử dụng thuật toán thay thế ngược.
  3. Nếu A đối xứng và có các yếu tố đường chéo dương thực sự, hãy thử hệ số nhân Cholesky. Nếu A thưa thớt, sử dụng sắp xếp lại trước để giảm thiểu điền vào.
  4. Nếu không có tiêu chí nào ở trên được đáp ứng, hãy thực hiện hệ số tam giác tổng quát bằng cách sử dụng loại bỏ Gaussian với trục xoay một phần.
  5. Nếu A thưa thớt thì sử dụng thư viện UMFPACK.
  6. Nếu A không vuông, sử dụng thuật toán dựa trên yếu tố QR cho các hệ thống không xác định.

Để giảm chi phí, có thể sử dụng lệnh linsolve trong Matlab và tự mình chọn một người giải quyết phù hợp trong số các tùy chọn này.


Giả sử tôi đang xử lý một ma trận dày đặc không cấu trúc 10000x10000 với tất cả các yếu tố khác không (Mật độ cao), điều gì sẽ là lựa chọn tốt nhất của tôi? Tôi muốn tách 1 thuật toán đó hoạt động cho các ma trận dày đặc. Là loại bỏ LU, QR hay Gaussian?
Thắc mắc

1
Âm thanh giống như Bước 4 trong đó Loại bỏ Gaussian được gọi tương ứng với trường hợp chung nhất trong đó không có cấu trúc nào của A có thể được khai thác để tăng hiệu suất. Vì vậy, về cơ bản, đây là một yếu tố LU và tiếp theo là một bước thay thế tiếp theo.
Allan P. Engsig-Karup

Cảm ơn! Tôi nghĩ rằng điều đó cho tôi một hướng để suy nghĩ. Hiện tại, Gaussian Elimination là cách tốt nhất chúng ta có để giải quyết các vấn đề phi cấu trúc như vậy, điều đó có đúng không?
Thắc mắc

37

Nếu bạn muốn xem những gì a\blàm cho ma trận cụ thể của bạn, bạn có thể thiết lập spparms('spumoni',1)và tìm ra chính xác thuật toán mà bạn ấn tượng. Ví dụ:

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

sẽ xuất

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.

vì vậy tôi có thể thấy rằng "\" đã kết thúc bằng cách sử dụng "CHOLMOD" trong trường hợp này.


3
+1 cho cài đặt MATLAB mới mà tôi chưa từng nghe đến. Chơi tốt, thưa ngài.
Geoff Oxberry

2
Này cảm ơn nhé! Nó ở trong help mldivide.
dranxo

16

Đối với các ma trận thưa thớt, Matlab sử dụng UMFPACK cho \hoạt động "", trong ví dụ của bạn, về cơ bản chạy qua các giá trị của a, đảo ngược chúng và nhân chúng với các giá trị của b. Tuy nhiên, đối với ví dụ này, bạn nên sử dụng b./diag(a), nhanh hơn rất nhiều.

Đối với các hệ thống dày đặc, toán tử dấu gạch chéo ngược phức tạp hơn một chút. Một mô tả ngắn gọn về những gì được thực hiện khi được đưa ra ở đây . Theo mô tả đó, trong ví dụ của bạn, Matlab sẽ giải quyết a\bbằng cách sử dụng thay thế ngược. Đối với ma trận vuông tổng quát, phân rã LU được sử dụng.


Regd. Độ thưa thớt, việc gọi một ma trận diag đơn giản sẽ là đối ứng của các phần tử đường chéo để b./diag(a) sẽ hoạt động nhưng một \ b cũng hoạt động khủng khiếp đối với ma trận thưa thớt chung. Tại sao không phải là linsolve hoặc LULU (Phiên bản LU được tối ưu hóa của tôi) không nhanh hơn mà \ b cho ma trận dày đặc trong trường hợp đó.
Thắc mắc

@Nunoxic LULU của bạn có làm gì để phát hiện đường chéo hoặc tam giác của ma trận dày đặc không? Nếu không, nó sẽ chỉ mất nhiều thời gian với mọi ma trận, bất kể nội dung hay cấu trúc của nó.
Pedro

Một chút nào đó. Nhưng, với các cờ OPT của linsolve, tôi đã xác định mọi thứ cần xác định về cấu trúc. Tuy nhiên, a \ b nhanh hơn.
Thắc mắc

@Nunoxic, mỗi khi bạn gọi một chức năng người dùng, bạn sẽ gây ra chi phí chung. Matlab thực hiện mọi thứ cho dấu gạch chéo ngược trong nội bộ, ví dụ: phân tách và ứng dụng tiếp theo của phía bên tay phải, với rất ít chi phí, và do đó sẽ nhanh hơn. Ngoài ra, trong các thử nghiệm của bạn, bạn nên sử dụng nhiều hơn chỉ một cuộc gọi để có được thời gian đáng tin cậy, ví dụ tic; for k=1:100, a\b; end; toc.
Pedro

5

Theo nguyên tắc thông thường, nếu bạn có một ma trận thưa thớt có độ phức tạp hợp lý (nghĩa là, nó không phải là khuôn tô 5 điểm nhưng thực tế có thể là một sự rời rạc của các phương trình Stokes mà số lượng các số khác không trên mỗi hàng là lớn hơn 5), sau đó một bộ giải trực tiếp thưa thớt như UMFPACK thường đánh bại một bộ giải Krylov lặp nếu vấn đề không lớn hơn khoảng 100.000 ẩn số.

Nói cách khác, đối với hầu hết các ma trận thưa thớt do sự rời rạc 2d, một người giải trực tiếp là sự thay thế nhanh nhất. Chỉ đối với các vấn đề 3d mà bạn nhanh chóng nhận được hơn 100.000 ẩn số thì việc sử dụng một bộ giải lặp lại là điều bắt buộc.


3
Tôi không rõ điều này trả lời câu hỏi như thế nào, nhưng tôi cũng đưa ra vấn đề với tiền đề. Đúng là người giải quyết trực tiếp có xu hướng hoạt động tốt đối với các vấn đề 2D có kích thước khiêm tốn, nhưng người giải quyết trực tiếp có xu hướng chịu ảnh hưởng tốt trước 3D chưa biết 100k (dấu tách đỉnh lớn hơn nhiều so với 2D). Hơn nữa, tôi khẳng định rằng trong hầu hết các trường hợp (ví dụ: toán tử elip), bộ giải lặp có thể được thực hiện nhanh hơn bộ giải trực tiếp ngay cả đối với các vấn đề 2D có kích thước vừa phải, nhưng có thể phải nỗ lực đáng kể để làm như vậy (ví dụ: sử dụng đúng thành phần để thực hiện đa pha) .
Jed Brown

1
Nếu các vấn đề của bạn khá nhỏ và bạn không muốn nghĩ đến việc thiết kế các bộ giải ngầm, hoặc nếu các vấn đề của bạn rất khó khăn (như Maxwell tần số cao) và bạn không muốn dành sự nghiệp của mình để thiết kế các bộ giải tốt, thì tôi đồng ý rằng người giải quyết trực tiếp thưa thớt là một lựa chọn tuyệt vời.
Jed Brown

Trên thực tế vấn đề của tôi là thiết kế một bộ giải dày đặc tốt. Tôi không có một ứng dụng cụ thể nào như vậy (Do đó, không có cấu trúc). Tôi muốn điều chỉnh một vài mã của mình và làm cho chúng cạnh tranh với những gì hiện đang được sử dụng. Tôi chỉ tò mò về một \ b và làm thế nào nó luôn đánh bại những thứ tào lao ra khỏi mã của tôi.
Thắc mắc

@JedBrown: Vâng, có thể với một lượng nỗ lực đáng kể, người ta có thể có được các bộ giải lặp để đánh bại một người giải trực tiếp ngay cả đối với các vấn đề 2d nhỏ. Nhưng tại sao lại làm điều đó? Đối với các vấn đề với ẩn số <100k, bộ giải trực tiếp thưa thớt trong 2d là đủ nhanh. Điều tôi muốn nói là: đối với những vấn đề nhỏ như vậy, đừng dành thời gian mày mò và tìm ra sự kết hợp tốt nhất của các tham số - chỉ cần lấy hộp đen.
Wolfgang Bangerth

Đã có một sự khác biệt về thời gian chạy giữa cường độ đa dạng hình học Cholesky và (dựa trên ma trận) thưa thớt đối với các vấn đề 2D "dễ dàng" với 100 nghìn dofs bằng cách sử dụng stprint 5 điểm (~ 0,5 giây so với ~ 0,05 giây). Nếu stprint của bạn sử dụng hàng xóm thứ hai (ví dụ như sự phân rã bậc bốn, Newton cho một số lựa chọn về lưu biến phi tuyến, ổn định, v.v.), kích thước của các dấu tách đỉnh tăng gấp đôi, do đó chi phí giải quyết trực tiếp tăng khoảng 8 lần (chi phí cao hơn vấn đề phụ thuộc vào MG). Với nhiều bước thời gian hoặc vòng lặp tối ưu hóa / UQ, những khác biệt này rất đáng kể.
Jed Brown
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.