2009-06-02 98 views
14

Tôi có hai ma trận x và y, cả hai đều là kết quả từ các thuật toán/thường trình khác nhau được cho là để tính cùng một kết quả. Trong khi tôi biết rằng isequal() sẽ kiểm tra nếu x và y là cùng một ma trận, các mục trong các ma trận đó sẽ không chính xác giống nhau (nghĩa là một số mục có thể giảm 5% trong trường hợp xấu nhất). Trong kịch bản này, phương pháp nào tốt nhất để so sánh chúng để xem liệu chúng có đủ gần để được xem là kết quả tương tự không? Cảm ơn trước cho lời khuyên.So sánh hai ma trận trong Matlab

+1

Câu hỏi này khá cũ, nhưng về mặt toán học bạn muốn sử dụng 'chuẩn (A-B)/norm (A) ', không phải giải pháp bên dưới. – rlbond

Trả lời

5

Sửa đổi Edric's giải pháp:

absTol = 1e-3; % You choose this value to be what you want! 
relTol = 0.05; % This one too! 
absError = x(:)-y(:); 
relError = absError./x(:); 
relError(~isfinite(relError)) = 0; % Sets Inf and NaN to 0 
same = all((abs(absError) < absTol) & (abs(relError) < relTol)); 

Các biến cùng sẽ là false nếu hoặc tuyệt đối hoặc lỗi tương đối của bất kỳ phần tử nào lớn hơn bất kỳ dung sai nào bạn chọn. Ngoài ra, nếu bất kỳ phần tử nào của x xảy ra chính xác 0, thì một số thành phần của relError có thể kết thúc hoặc là vô hạn hoặc không phải số, vì vậy tôi đã sử dụng hàm ISFINITE để bỏ qua các giá trị đó bằng cách đặt chúng đến 0.

Tôi sẽ không đề xuất sử dụng IMAGESC để so sánh ô, vì 1) dữ liệu được thu nhỏ khi hiển thị, 2) bản đồ màu cho màn hình có số lượng màu riêng biệt (mà tôi nghĩ là 256 theo mặc định, do đó rất nhiều làm tròn) và 3) các biến thể tinh tế về màu sắc có thể không rõ ràng so với sự so sánh trực quan của hai ô.

13

Hãy thử điều này:

tf = abs((A-B)./B)<0.05 

này sẽ trả về một ma trận logic đó sẽ đúng đối với mỗi phần tử nếu sự chênh lệch tương đối giữa A và B liên quan đến B với ít hơn 5 phần trăm.

Nếu bạn muốn hỏi nếu tất cả trong số này là đúng (tất cả họ đều đáp ứng các điều kiện nêu trên):

all(tf(:)) 
+0

câu trả lời hay hơn về những gì tôi thực sự nghĩ. – bastijn

+1

Bạn không cần một giá trị tuyệt đối ở đâu đó? – Jim

+0

Đúng, tôi đã thêm nó ngay bây giờ. Cảm ơn. –

4

tôi sẽ xem xét làm một cái gì đó như thế này với một sự khoan dung tuyệt đối cũng như khả năng chịu đựng tương đối:

function same = tol(x, y) 
absTol = 1e-3; 
relTol = 0.05; 
errVec = abs(x(:) - y(:)); 
same = all((errVec < absTol) | (errVec./x(:) < relTol)); 
+0

Tôi đã thử cả phương pháp của Edric và Andrew.Mặc dù tôi có một đầu ra từ hàm này là sai, khi tôi so sánh hai kết quả bằng cách vẽ chúng bằng cách sử dụng hàm imagesc(), chúng trông rất giống nhau. Do đó tôi vẫn không chắc chắn những gì để thực hiện điều này. – stanigator

1

Khi bạn có các cặp giá trị rất nhỏ trong x và y, kết quả sẽ trả về 0 mặc dù các giá trị có thể tự bỏ qua. Do đó, việc thêm vào giải pháp được chấp nhận

relError(x < absTol) = 0;

có thể được sử dụng để loại bỏ các lỗi rất nhỏ. Do đó, lỗi tương đối không được xem xét cho các giá trị này.

-2

làm sử dụng 'isequal (a, b), nơi a và b là hai ma trận, nếu 1 đó là sự thật

+1

Lưu ý rằng op cụ thể nói rằng hậu quả sẽ không hoạt động vì có lỗi. –

0

Đối với ma trận x và y có chứa các giá trị dấu chấm động, bạn có thể kiểm tra xem phần tử mảng nằm trong một chịu được sự khoan dung lẫn nhau. Mã mẫu:

tol = 0.05; 

result = abs(x - y) <= tol;