1

I'm using the Matlab function deg2rad to convert angles from degrees to radians (obviously). I use them for angles alpha and beta, which are in turn used to interpolate some tabular data f(alpha, beta), which is with respect to alpha and beta in degrees. For my purposes, I use them in radians, such that I have to convert back and forth every now and then.

Now, I found that - as opposed to using f(pi/180*alpha, pi/180*beta) - whenever I interpolate using f(deg2rad(alpha), deg2rad(beta)), the interpolation is outside the interpolation area at the boundaries. I.e., the interpolation boundaries are at alpha = [-4, 4], beta = [-3, 3] and interpolating along those boundaries gives me NaN when using deg2rad. This thus looks like some kind of round-off or machine precision error.

Now, as a MWE, suppose I want to check deg2rad(-3) == -3*pi/180, this gives me:

>> deg2rad(-3) == -3*pi/180
ans =
  logical
   0

My questions are the following:

  1. How do I prevent this behaviour, where using deg2rad is basically not useful for me when operating near the edges of the interpolation area?
  2. What does the deg2rad function do, other than multiplying with pi/180?

Thanks in advance.

P.s. It is even stranger than I thought, because with different angles, it does work:

>> deg2rad(2) == 2*pi/180
ans =
  logical
   1
Sam
  • 305
  • 1
  • 8

1 Answers1

5

Your question is answered by typing edit deg2rad into MATLAB. It computes:

angleInRadians = (pi/180) * angleInDegrees;

Of course, the order of operation differs between your version ((a*pi)/180) and MATLAB's (a*(pi/180)). This different order causes rounding errors to differ.

If rounding errors cause a problem in your function, your function is unstable and needs to be fixed.

Cris Luengo
  • 55,762
  • 10
  • 62
  • 120
  • I'd add that the actual difference we're talking about seems to be `-7e-18`, which is about a hundred times less than typical machine precision. – Andras Deak -- Слава Україні Nov 12 '19 at 14:57
  • 1
    @AndrasDeak: `eps(a*pi/180)` for `a=-3` is `6.9389e-18`, exactly the same size as the difference. – Cris Luengo Nov 12 '19 at 14:58
  • Thank you for explaining. However, this answers only my second question. While it could be that my function has some unstable behaviour, my MWE illustrates that roundoff errors are already present without passing any of the arguments to a function. Moreover, this roundoff error _does_ occur for one number, while it doesn't for others. – Sam Nov 12 '19 at 15:01
  • 2
    @Sam see https://stackoverflow.com/questions/588004/is-floating-point-math-broken and https://stackoverflow.com/questions/686439/why-is-24-0000-not-equal-to-24-0000-in-matlab. You need to use strategies that don't rely on exact equality. – Andras Deak -- Слава Україні Nov 12 '19 at 15:03
  • That I understand. However, this means that I can never use Matlab's native interpolating functions, such as `interpn`, at the boundaries, whenever the nodes are the result of a calculation. Should I then write a function on top of _each_ other function, defining some tolerance level? Isn't this very cumbersome? – Sam Nov 12 '19 at 15:08
  • @Sam can you explain what problem you're trying to solve? Why the edges are important? If your problem is that errors push the results outside of a valid angle range, you can clip the values to your range. Similarly to how you might end up getting more than 1 for a cosine if you're computing the angle between two vectors. – Andras Deak -- Слава Україні Nov 12 '19 at 15:10
  • For this particular problem, I am only trying to plot the tabular data, but interpolated. Therefore, it is not _really_ a problem in the sense that I could also manually enter `2.99999` instead of `3`. However, I still don't quite understand how such a Matlab-native function can be useful if it dismisses equality of two numbers based on an `eps` that is approximately 100 times smaller than machine precision. If we should always test number equality using tolerances, why are we allowed to test `number1 == number2` at all? – Sam Nov 12 '19 at 15:16
  • 2
    @Sam: There is no MATLAB function doing anything wrong here. Rounding errors are inherent to floating-point arithmetic. See the Q&As linked by Andras above. The case is, you have a function that is not robust against rounding errors. You need to make it robust. If you want help with that, edit your question to include the actual problem you're trying to solve here. Note that strict equality comparison is useful in some cases, but not in others. It's up to you, as the user of floating-point arithmetic, to know its limitations. – Cris Luengo Nov 12 '19 at 15:23
  • @CrisLuengo, as indicated, my actual problem has already been solved by entering `deg2rad(2.99)` instead of `deg2rad(3)`. My point is that I don't _have_ a function, other than using `interpn`, with the query points calculated. The equality comparison doesn't happen anywhere, except in my MWE. Upon interpolation, the calculated query points `vq` are deemed out of bounds, because apparently due to rounding off, `vq > bounds`. I am well aware that Matlab functions aren't wrong, but I was just wondering how equality can be dismissed based on an error 100x smaller than machine precision. – Sam Nov 12 '19 at 15:39
  • @Sam: I would recommend that you fix your interpolation problem by converting everything to degrees and rounding to a certain number of digits, rather than converting to radian. Since your limits are at -3 and 3 degrees, it makes sense to use degrees. Note that comparing rounded values for equality is quite robust. – Cris Luengo Nov 12 '19 at 15:53