Turn off "smart behavior" in Matlab
Asked Answered
M

2

6

There is one thing I do not like on Matlab: It tries sometimes to be too smart. For instance, if I have a negative square root like

a = -1; sqrt(a)

Matlab does not throw an error but switches silently to complex numbers. The same happens for negative logarithms. This can lead to hard to find errors in a more complicated algorithm.

A similar problem is that Matlab "solves" silently non quadratic linear systems like in the following example:

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

Obviously x does not satisfy A*x==b (It solves a least square problem instead).

Is there any possibility to turn that "features" off, or at least let Matlab print a warning message in this cases? That would really helps a lot in many situations.

Mulch answered 14/12, 2011 at 13:51 Comment(5)
I am wondering why people downvote this question. I think, it is totally legit to ask this. Moreover, I am sure that there are a lot of people who lost time searching for subtle bugs because of the described behavior.Mulch
The way your question reads may sound to some like "I didn't really read the documentation that states that Matlab supports complex numbers, and that explains what the backslash operator does. Can I make Matlab do what I falsely assumed it would do, because I'm really frustrated here about my inability to read the documentation?". While I disagree with you on the issue with the backslash operator, I agree that complex numbers can be indicative of a problem. Thus it would be nice if there was a "dbstop if complex" in addition to "dbstop if nan/inf" in the debugger.Stuartstub
@Stuartstub I have tried to formulate the question in such a way that the reader does not have this impression, seems like I failed :(. You are right, the documentation is perfectly clear on that. I think that Matlab "overuses" the operator which could lead to bugs and that is bad. Another one that is often made wrong by beginners is the following: A (wrong defined) function like f=@(x) x*((x+1)/x) gives the result f([1,2])=[1.6,3.2] whereas most beginners would expect the result [2,3]. In a larger program such bugs are very hard to find.Mulch
Ok, that's just a mean function. Allowing matrix division and multiplication to operate on scalars (e.g. 1x1 matrices) is a tricky one; not everybody will understand that Matlab is short for "Matrix Laboratory". Anyway, you may be interested in #1710799. Maybe you want to your function example as a new answer.Stuartstub
@Stuartstub You can kind of simulate the effect of a dbstop if complex using conditional breakpoints with the condition ~isreal. Not exactly the same, but close.Trish
S
3

I don't think there is anything like "being smart" in your examples. The square root of a negative number is complex. Similarly, the left-division operator is defined in Matlab as calculating the pseudoinverse for non-square inputs.

If you have an application that should not return complex numbers (beware of floating point errors!), then you can use isreal to test for that. If you do not want the left division operator to calculate the pseudoinverse, test for whether A is square.

Alternatively, if for some reason you are really unable to do input validation, you can overload both sqrt and \ to only work on positive numbers, and to not calculate the pseudoinverse.

Stuartstub answered 14/12, 2011 at 14:3 Comment(4)
Of course, I can check all my parameters but in 90% of the cases if my input is real valued, the output should also be real. Furthermore, the solution of a linear system is what people in most cases expect when the backslash operator is used. I simply would like to trigger the behavior by a parameter.Mulch
@Boris: We seem to go at this very differently, then. In 100% of the cases where I take the square root of a negative value, I expect complex output. Also, I use the backslash operator exclusively for overdetermined systems (since the other should never occur in my applications).Stuartstub
@Boris: Unfortunately, there is no built-in switch that only allows real numbers to occur in calculations (unless you want to work with all integers).Stuartstub
Indeed this is very different. What I mean with 90% is that if one expects a complex output of the square root of a negative number, then the input is most likely also already complex. It's a pity that there is not such a switch, because I (and my colleagues too) really lost time because of this. We often use Matlab to quickly implement algorithms and make some tests with it.Mulch
B
3

You need to understand all of the implications of what you're writing and make sure that you use the right functions if you're going to guarantee good code. For example:

  • For the first case, use realsqrt instead
  • For the second case, use inv(A) * b instead

Or alternatively, include the appropriate checks before/after you call the built-in functions. If you need to do this every time, then you can always write your own functions.

Bosson answered 14/12, 2011 at 14:3 Comment(5)
The ad hominem was uncalled for (and has been deleted), but otherwise, the solution is not deserving a downvote. +1 from me for finding realsqrt.Stuartstub
The proposal inv(A)*b is very slow in many cases (especially when A is sparse) and should not be used.Mulch
@Boris, I agree, but if you need a version that only works when A is square and non-singular, then it's the simplest option. You're best option is two wrap the backslash in your own function.Bosson
@Jonas, I agree. It wasn't supposed to be taken that serious.Bosson
There are of course also reallog and realpow. These all appear to be native (compiled) functions.Elope

© 2022 - 2024 — McMap. All rights reserved.