2011-12-14 32 views
6

Có một điều tôi không thích trên Matlab: Nó cố gắng đôi khi quá thông minh. Ví dụ: nếu tôi có căn bậc hai âm nhưTắt "hành vi thông minh" trong Matlab

a = -1; sqrt(a) 

Matlab không phát sinh lỗi nhưng chuyển âm thầm sang số phức. Điều tương tự cũng xảy ra đối với logarit âm. Điều này có thể dẫn đến khó tìm lỗi trong một thuật toán phức tạp hơn.

Một vấn đề tương tự là Matlab "giải quyết" các hệ thống tuyến tính âm thầm phi bậc hai như trong ví dụ sau:

A=eye(3,2); b=ones(3,1); x = A \ b 

Rõ ràng x không đáp ứng A*x==b (Nó giải quyết một vấn đề bình phương tối thiểu thay vì).

Có khả năng nào để tắt "tính năng" đó hay ít nhất hãy để Matlab in một thông báo cảnh báo trong trường hợp này? Điều đó thực sự sẽ giúp ích rất nhiều trong nhiều tình huống.

+1

Tôi tự hỏi tại sao mọi người downvote câu hỏi này. Tôi nghĩ, hoàn toàn hợp pháp để hỏi điều này. Hơn nữa, tôi chắc chắn rằng có rất nhiều người mất thời gian tìm kiếm các lỗi tinh vi vì hành vi được mô tả. – Boris

+1

Cách đọc câu hỏi của bạn nghe có vẻ giống như "Tôi đã không thực sự đọc tài liệu nói rằng Matlab hỗ trợ các số phức và giải thích điều mà toán tử backslash làm. Tôi có thể làm Matlab làm những gì tôi giả định rằng nó sẽ làm, bởi vì tôi thực sự thất vọng ở đây về việc tôi không thể đọc được tài liệu này? ". Mặc dù tôi không đồng ý với bạn về vấn đề với toán tử dấu gạch chéo ngược, tôi đồng ý rằng các số phức có thể là dấu hiệu của một vấn đề. Vì vậy, nó sẽ là tốt đẹp nếu có một "dbstop nếu phức tạp" ngoài "dbstop nếu nan/inf" trong trình gỡ rối. – Jonas

+0

@ Jason Tôi đã cố gắng xây dựng câu hỏi theo cách mà người đọc không có ấn tượng này, có vẻ như tôi đã thất bại: (Bạn nói đúng, tài liệu này hoàn toàn rõ ràng về điều đó. Tôi nghĩ rằng Matlab "lạm dụng" nhà điều hành có thể dẫn đến lỗi và điều đó là xấu.Một cái khác thường bị sai bởi người mới bắt đầu là như sau: Hàm A (sai được xác định) như 'f = @ (x) x * ((x + 1)/x)' cho kết quả 'f ([1,2]) = [1.6,3.2] 'trong khi hầu hết người mới bắt đầu mong đợi kết quả '[2,3]'. Trong một chương trình lớn hơn lỗi như vậy là rất khó tìm. – Boris

Trả lời

3

Tôi không nghĩ có bất cứ điều gì như "thông minh" trong ví dụ của bạn. Căn bậc hai của một số âm là phức tạp. Tương tự, toán tử phân chia bên trái được định nghĩa trong Matlab như tính toán giả cho các đầu vào không vuông.

Nếu bạn có ứng dụng không trả về số phức (hãy xem xét các lỗi dấu phẩy động!), Thì bạn có thể sử dụng isreal để kiểm tra điều đó. Nếu bạn không muốn toán tử phân chia bên trái tính toán giả, kiểm tra xem liệu A có phải là hình vuông hay không. Ngoài ra, nếu vì một lý do nào đó bạn thực sự không thể thực hiện xác nhận đầu vào, bạn có thể quá tải cả sqrt\ để chỉ hoạt động trên các số dương và không tính toán giả.

+0

Tất nhiên, tôi có thể kiểm tra tất cả các thông số của mình nhưng trong 90% các trường hợp nếu đầu vào của tôi có giá trị thực, đầu ra cũng phải là thực. Hơn nữa, các giải pháp của một hệ thống tuyến tính là những gì mọi người trong nhiều trường hợp mong đợi khi các nhà điều hành dấu gạch chéo ngược được sử dụng. Tôi chỉ muốn kích hoạt hành vi bằng một tham số. – Boris

+1

@Boris: Dường như chúng tôi đi theo cách này rất khác. Trong 100% các trường hợp mà tôi lấy căn bậc hai của một giá trị âm, tôi mong đợi đầu ra phức tạp. Ngoài ra, tôi sử dụng toán tử dấu gạch chéo ngược dành riêng cho các hệ thống được xác định trước (vì hệ thống khác không bao giờ xảy ra trong các ứng dụng của tôi). – Jonas

+1

@Boris: Thật không may, không có chuyển đổi tích hợp chỉ cho phép các số thực xuất hiện trong các phép tính (trừ khi bạn muốn làm việc với tất cả các số nguyên). – Jonas

3

Bạn cần hiểu tất cả các tác động của nội dung bạn đang viết và đảm bảo rằng bạn sử dụng đúng chức năng nếu bạn đảm bảo mã tốt. Ví dụ:

  • Đối với trường hợp đầu tiên, sử dụng realsqrt thay
  • Đối với trường hợp thứ hai, sử dụng inv(A) * b thay

Hoặc cách khác, bao gồm kiểm tra thích hợp trước/sau khi bạn gọi built-in chức năng. Nếu bạn cần phải làm điều này mỗi lần, sau đó bạn luôn có thể viết các chức năng của riêng bạn.

+0

Các * quảng cáo hominem * đã được uncalled cho (và đã bị xóa), nhưng nếu không, giải pháp không xứng đáng là một downvote. 1 từ tôi để tìm 'realsqrt'. – Jonas

+2

Đề xuất 'inv (A) * b' là rất chậm trong nhiều trường hợp (đặc biệt là khi A là thưa thớt) và không nên được sử dụng. – Boris

+0

@Boris, tôi đồng ý, nhưng nếu bạn cần một phiên bản chỉ hoạt động khi A là hình vuông và không có số ít, thì đó là tùy chọn đơn giản nhất. Bạn đang lựa chọn tốt nhất là hai bọc dấu gạch chéo ngược trong chức năng của riêng bạn. – Nzbuu