128 lines
4.3 KiB
Matlab
128 lines
4.3 KiB
Matlab
function result = compareFloats(varargin)
|
|
%compareFloats Compare floating-point arrays using tolerance.
|
|
% result = compareFloats(A, B, compare_type, tol_type, tol, floor_tol)
|
|
% compares the floating-point arrays A and B using a tolerance. compare_type
|
|
% is either 'elementwise' or 'vector'. tol_type is either 'relative' or
|
|
% 'absolute'. tol and floor_tol are the scalar tolerance values.
|
|
%
|
|
% There are four different tolerance tests used, depending on the comparison
|
|
% type and the tolerance type:
|
|
%
|
|
% 1. Comparison type: 'elementwise' Tolerance type: 'relative'
|
|
%
|
|
% all( abs(A(:) - B(:)) <= tol * max(abs(A(:)), abs(B(:))) + floor_tol )
|
|
%
|
|
% 2. Comparison type: 'elementwise' Tolerance type: 'absolute'
|
|
%
|
|
% all( abs(A(:) - B(:) <= tol )
|
|
%
|
|
% 3. Comparison type: 'vector' Tolerance type: 'relative'
|
|
%
|
|
% norm(A(:) - B(:) <= tol * max(norm(A(:)), norm(B(:))) + floor_tol
|
|
%
|
|
% 4. Comparison type: 'vector' Tolerance type: 'absolute'
|
|
%
|
|
% norm(A(:) - B(:)) <= tol
|
|
%
|
|
% Note that floor_tol is not used when the tolerance type is 'absolute'.
|
|
%
|
|
% compare_type, tol_type, tol, and floor_tol are all optional inputs. The
|
|
% default value for compare_type is 'elementwise'. The default value for
|
|
% tol_type is 'relative'. If both A and B are double, then the default value
|
|
% for tol is sqrt(eps), and the default value for floor_tol is eps. If either
|
|
% A or B is single, then the default value for tol is sqrt(eps('single')), and
|
|
% the default value for floor_tol is eps('single').
|
|
%
|
|
% If A or B is complex, then the tolerance test is applied independently to
|
|
% the real and imaginary parts.
|
|
%
|
|
% For elementwise comparisons, compareFloats returns true for two elements
|
|
% that are both NaN, or for two infinite elements that have the same sign.
|
|
% For vector comparisons, compareFloats returns false if any input elements
|
|
% are infinite or NaN.
|
|
|
|
% Steven L. Eddins
|
|
% Copyright 2008-2009 The MathWorks, Inc.
|
|
|
|
if nargin >= 3
|
|
% compare_type specified. Grab it and then use parseFloatAssertInputs to
|
|
% process the remaining input arguments.
|
|
compare_type = varargin{3};
|
|
varargin(3) = [];
|
|
if isempty(strcmp(compare_type, {'elementwise', 'vector'}))
|
|
error('compareFloats:unrecognizedCompareType', ...
|
|
'COMPARE_TYPE must be ''elementwise'' or ''vector''.');
|
|
end
|
|
else
|
|
compare_type = 'elementwise';
|
|
end
|
|
|
|
params = xunit.utils.parseFloatAssertInputs(varargin{:});
|
|
|
|
A = params.A(:);
|
|
B = params.B(:);
|
|
|
|
switch compare_type
|
|
case 'elementwise'
|
|
magFcn = @abs;
|
|
|
|
case 'vector'
|
|
magFcn = @norm;
|
|
|
|
otherwise
|
|
error('compareFloats:unrecognizedCompareType', ...
|
|
'COMPARE_TYPE must be ''elementwise'' or ''vector''.');
|
|
end
|
|
|
|
switch params.ToleranceType
|
|
case 'relative'
|
|
coreCompareFcn = @(A, B) magFcn(A - B) <= ...
|
|
params.Tolerance * max(magFcn(A), magFcn(B)) + ...
|
|
params.FloorTolerance;
|
|
|
|
case 'absolute'
|
|
coreCompareFcn = @(A, B) magFcn(A - B) <= params.Tolerance;
|
|
|
|
otherwise
|
|
error('compareFloats:unrecognizedToleranceType', ...
|
|
'TOL_TYPE must be ''relative'' or ''absolute''.');
|
|
end
|
|
|
|
if strcmp(compare_type, 'elementwise')
|
|
compareFcn = @(A, B) ( coreCompareFcn(A, B) | bothNaN(A, B) | sameSignInfs(A, B) ) & ...
|
|
~oppositeSignInfs(A, B) & ...
|
|
~finiteAndInfinite(A, B);
|
|
else
|
|
compareFcn = @(A, B) coreCompareFcn(A, B) & ...
|
|
isfinite(magFcn(A)) & ...
|
|
isfinite(magFcn(B));
|
|
end
|
|
|
|
if isreal(A) && isreal(B)
|
|
result = compareFcn(A, B);
|
|
else
|
|
result = compareFcn(real(A), real(B)) & compareFcn(imag(A), imag(B));
|
|
end
|
|
|
|
result = all(result);
|
|
|
|
%===============================================================================
|
|
function out = bothNaN(A, B)
|
|
|
|
out = isnan(A) & isnan(B);
|
|
|
|
%===============================================================================
|
|
function out = oppositeSignInfs(A, B)
|
|
|
|
out = isinf(A) & isinf(B) & (sign(A) ~= sign(B));
|
|
|
|
%===============================================================================
|
|
function out = sameSignInfs(A, B)
|
|
|
|
out = isinf(A) & isinf(B) & (sign(A) == sign(B));
|
|
|
|
%===============================================================================
|
|
function out = finiteAndInfinite(A, B)
|
|
|
|
out = xor(isinf(A), isinf(B));
|
|
|