-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathnearly_equal.m
More file actions
95 lines (92 loc) · 3.96 KB
/
nearly_equal.m
File metadata and controls
95 lines (92 loc) · 3.96 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
function [ a, b, c ] = nearly_equal(a, b)
% This file is part of GPCCA.
%
% Copyright (c) 2018, 2017 Bernhard Reuter
%
% If you use this code or parts of it, cite the following reference:
%
% Reuter, B., Weber, M., Fackeldey, K., Röblitz, S., & Garcia, M. E. (2018). Generalized
% Markov State Modeling Method for Nonequilibrium Biomolecular Dynamics: Exemplified on
% Amyloid β Conformational Dynamics Driven by an Oscillating Electric Field. Journal of
% Chemical Theory and Computation, 14(7), 3579–3594. https://doi.org/10.1021/acs.jctc.8b00079
%
% GPCCA is free software: you can redistribute it and/or modify
% it under the terms of the GNU Lesser General Public License as published
% by the Free Software Foundation, either version 3 of the License, or
% (at your option) any later version.
%
% This program is distributed in the hope that it will be useful,
% but WITHOUT ANY WARRANTY; without even the implied warranty of
% MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
% GNU General Public License for more details.
%
% You should have received a copy of the GNU Lesser General Public License
% along with this program. If not, see <http://www.gnu.org/licenses/>.
% -------------------------------------------------------------------------
% Checks if two floats a, b are equal with respect to the precision.
% The precision can bei either mp or double.
% Based on code from http://www.http://floating-point-gui.de/errors/comparison/
% Written by Bernhard Reuter, Theoretical Physics II, University of
% Kassel, 2017
% -----------------------------------------------------------------------
% catch inappropriate use
assert( (isa(a,'mp') || isa(a,'double')), ...
'nearly_equal:a_DataTypeError', 'a is neither mp nor double')
assert( (isa(b,'mp') || isa(b,'double')), ...
'nearly_equal:b_DataTypeError', 'b is neither mp nor double')
% -----------------------------------------------------------------------
class_t1 = class(a);
class_t2 = class(b);
if (strcmp(class_t1,class_t2))
class_t = class_t1;
else
disp(['class(a)=' class_t1 ' is not equal class(b)=' class_t2 '!'])
disp('will convert to datatype double before comparison ')
a = double(a) ;
b = double(b) ;
class_t = 'double' ;
end
function r = num_t(expression)
if (nargin > 0)
if(strcmp(class_t,'mp')), r = mp(expression);
else
if isnumeric(expression)
r = expression;
else
r = eval(expression);
end;
end;
else
r = class_t;
end;
end % num_t
% -----------------------------------------------------------------------
absA = abs(a) ;
absB = abs(b) ;
diff = abs(a - b) ;
if (a == b) % shortcut, handles infinities
c = true ;
return
elseif (a == num_t('0.0') || b == num_t('0.0') || diff < realmin(num_t))
% a or b is zero or both are extremely close to it
% relative error is less meaningful here.
% In case of standard double floats diff has to be smaller than
% eps*realmin (as suggested by
% http://www.http://floating-point-gui.de/errors/comparison/).
if strcmp(num_t,'double')
c = ( diff < (eps(num_t) * realmin(num_t)) ) ;
% In case of multiprecision diff<eps*realmin doesn't work, since
% realmin('mp') is really the smallest positive floating point
% number and not the "smallest positive NORMALIZED floating point
% number": denormal values like 0.00001*realmin!=0 are possible in
% double floating point precision but not in multiprecision mode -
% there 0.00001*realmin==0 ALWAYS!
elseif strcmp(num_t,'mp')
c = ( diff < realmin(num_t) ) ;
end
return
else % use relative error
c = (diff / min((absA + absB), realmax(num_t)) < eps(num_t)) ;
return
end
end