Loren on the Art of MATLAB

Turn ideas into MATLAB

Note

Loren on the Art of MATLAB has been archived and will not be updated.

Another Lesson in Floating Point

In an earlier post I discussed the issue of floating point accuracy in calculations. I have another example to share today that has been lurking in the Mapping Toolbox product. The issue is with the function wrapTo180.

Contents

Work-around

There is a work-around for those of you using Mapping Toolbox with releases R2007b and R2008a.

Numerical Issue

In R2007b and R2008a, the implementation for wrapTo180 causes results from wrapTo180(lon) to differ very slightly from lon even for for certain values of lon in the interval [-180 180]. The differences are on the order of 2*eps(lon).

Test Case

The following should evaluate to true.

lon = 115.8323;

but doesn't.

isequal(lon,wrapTo180(lon))
ans =
     0

These quantities aren't equal because of the arithmetic being done: 115.8323 + 180 - 180 differs from 115.8323 by

(lon + 180 - 180) - lon
ans =
  2.8422e-014

which happens to be

2*eps(lon)
ans =
  2.8422e-014

The Code

Here's the code for wrapTo180

type wrapTo180
function lon = wrapTo180(lon)
%wrapTo180 Wrap angle in degrees to [-180 180]
%
%   lonWrapped = wrapTo180(LON) wraps angles in LON, in degrees, to the
%   interval [-180 180] such that 180 maps to 180 and -180 maps to -180.
%   (In general, odd, positive multiples of 180 map to 180 and odd,
%   negative multiples of 180 map to -180.)
%
%   See also wrapTo360, wrapTo2Pi, wrapToPi.

% Copyright 2007 The MathWorks, Inc.
% $Revision: 1.1.6.2 $  $Date: 2007/08/20 16:35:59 $

lon = wrapTo360(lon + 180) - 180;

Simple Fix

We can just skip the arithmetic operation for values,like 115.8323, that already are in the interval [-180 180]. A nice way to do this is with logical indexing and we can replace the line of code with this.

q = (lon < -180) | (180 < lon);
lon(q) = wrapTo360(lon(q) + 180) - 180;

Comments?

Have you ever had a similar issue, where a seemingly innocent code expression causes erroneous results? How have you found this out and solved it? I'd love to hear your thoughts here.




Published with MATLAB® 7.6


  • print