How to add tolerance for isequal?

126 次查看(过去 30 天)
Hi,
I am comparing two .mat files, both have very complicated struct type data but they should be almost identical. In this case, I don't found other method except for isequal can perform the comparsion.
data = load('MMC4_cpu_HVDC.mat');
data_ref = load('MMC4_cpu_HVDC_ref.mat');
isequal(data,data_ref)
The code above produced ans = 0. I checked using visdiff, found that it is due to some very small difference in number.
visdiff('MMC4_cpu_HVDC.mat', 'MMC4_cpu_HVDC_ref.mat')
% 13.581349668075767
% ans =
% 13.5813
% 13.581349668075765
% ans =
% 13.5813
I would like to ask if it is possible to add a tolerance factor to isequal? or are there other ways to compare these two .mat files? Example data are attached. Many thanks.
Andy

采纳的回答

Bjorn Gustavsson
Bjorn Gustavsson 2021-1-21
If you had asked for tolerances for regular arrays this would've been reasonably straightforward. Something like this:
isapproximatelyequal = @(x1,x2,tol) all(abs(real(x1(:)-x2(:)))<tol) & all(abs(imag(x1(:)-x2(:)))<tol);
But for structs this is a too unspecified operation, in my opinion. What with a pair of structs where one has an additional field 'OK' that is just a simple flag. Are those structs similar enough if everything else i identical? Perhaps you can wrap the isapproximatelyequal above into a function that compares fields in your structs. Something like this:
function OK = isapproximatelyequal_structs(S1,S2,tol)
OK = 0;
fields2 = fieldnames(S2);
fields1 = fieldnames(S1);
toCheck = intersect(fields1,fields2); % for example
for iField = numel(toCheck):-1:1
curr_field = toCheck(iField)';
OK(iField) = isapproximatelyequal(S1.(curr_field{:}),S2.(curr_field{:}),tol);
end
if all(OK)
OK = 1;
else
OK = 0;
end
function OK = isapproximatelyequal(x1,x2,tol)
OK = 0;
try
OK = all(abs(real(x1-x2))<tol) & all(abs(imag(x1-x2))<tol);
catch
OK = 0;
end
This function will not work for structs with more complicated structure, for that you'll have to call the function recursively untill you reach fields that are arrays where isapproximatelyequal will work as you want. You should also have checks on array-sizes since the new implicit expansion might give false positives in isapproximatelyequal.
HTH
  2 个评论
And Meng
And Meng 2021-1-21
Thank you Bjorn. I have modify the code you provided, and it is working perfectly fine for me now.

请先登录,再进行评论。

更多回答(1 个)

Patrik Forssén
Patrik Forssén 2022-6-16
Uploaded an isequal function with floating-point tolerance settings here,
This code with your data,
data = load('MMC4_cpu_HVDC.mat');
data_ref = load('MMC4_cpu_HVDC_ref.mat');
isequaltol(data, data_ref)
will return true

类别

Help CenterFile Exchange 中查找有关 Structures 的更多信息

标签

产品


版本

R2015b

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by