MATLAB Answers

0

Compare two or more cell arrays with a specific tolerence?

Najmeh Eskandari さんによって質問されました 2019 年 2 月 18 日
最新アクティビティ Rik
さんによって コメントされました 2019 年 2 月 20 日
Hi.
I have a cell array with length 3 :
M_t={{[0,1],[0 0 2]},{[0,1.01],[0 0 2]},{[0,1],[0 .001 2]}};
I want to compare these 3 arrays with a specific tolerence. How can i do this?
I have tried intersect before.
Thanks.

  7 件のコメント

Jan
2019 年 2 月 19 日
@Najmeh Eskandari: Please remember that I cannot read your mind.
If we use these two inputs:
a = {[0, 1], [0, 0, 2]}
b = {[0, 1.01], [0, 0, 2]}
what does "comparing" mean then exactly? Does "tolerance" mean an abolsute tolerance, or a relative one? Does the limit concern the maximum deviation between all elements, or the aritrhmetic or geometric mean between the elements? Do the cells need to have the same number of elements, and do the arrays need to have the same number of elements and do they need to be the same type? Does the order of elements matter or do you want to ignore it? "Comparing" can mean a variety of things and there is no unique definition.
Even for 2 scalars, there are a lot of different "comparisons":
a < b, a <= b, a == b, a > b, a >= b % Without tolerance
abs(a - b) <= tol % Compare equality with tolerance:
abs(a - b) / abs(a) <= tol
abs(a - b) / abs(b) <= tol
abs(a - b) / max(abs(a), abs(b)) <= tol
abs(a - b) / min(abs(a), abs(b)) <= tol
abs(a - b) / 0.5 * (abs(a) + abs(b)) <= tol
% The same with: < tol
% Or a combination with && or || between relative and absolute tolerance
% Or the same for < and > with a tolerance
% And with or without considering the type:
% are uint(8) and double(8) equal?
If you compare vectors, the order can matter, of the mean, min, max difference or maybe even the std. The number of elements might be equal or not. The relative tolerance might consider the maximum absolute value of one array, or of both array. Are these array euqal:
[0, 1] & [1e-100, 1+1e15] ?
[0, 0] & [1e-20, 1e-100] ?
[0, 1e15] & [1, 1e15+1] ?
[0, 1] & [1, 0] ?
Please spend the time to define exactly, what you want. It would most likely be a waste of time, if the readers guess the details.
Najmeh Eskandari 2019 年 2 月 20 日
suppose that i use ismembertol:
ismembertol([0,1],[0,1.01],1e-02)
logical
1 1
ismembertol([0,0,2],[0,0,2],1e-02)
logical
1 1 1
in this case i want to get result 1 but forexample in case:
ismembertol([0,1],[0,1.5],1e-02)
logical
1 0
ismebertol([0,0,2],[0,0,2],1e-02)
logical
1 1
the final result that i want is:
0
I have several cell arrays with such matrices and want to compare the arrays. If in the way that i described the matrices are equal the result shuld be 1.
-The absolute error is my concern.
Jan
2019 年 2 月 20 日
In the case
ismebertol([0,0,2],[0,0,2],1e-02)
the output has 3 elements, not "logical1 1". Is this a typo?
ismembertol uses a strange scaling: for the elements u of the array A and the elements v of the array B:
abs(u-v) <= tol*max(abs([A(:);B(:)]))
This means, that the tolerance is multiplied my the maximum absolute value of the arrays. I do not know a case, where this is really useful.
ismembertol([1, 900], [20, 1000], 1)
Is the result [true, true] expected?!
For all of my cases, ismembertol did not offer a useful method to apply the tolerence. What a pity.
By the way, you still did not mention, which kind of comparison you exactly want. "The absolute error" is not a unique definition. It can mean:
all(abs(a(:) - b(:)) < tol) % or <=
any(abs(a(:) - b(:)) < tol) % or <=
sum(abs(a(:) - b(:)) < tol) < numel(A) / 2
% or a method, which does not consider the order or the elements
You have mentioned ismembertol, which does not consider the order of elements. So it is not clear, if [1, 0] and [0, 1] should be considered as equal or not.
It is hard to find out, what you exactly want. I've spent some time to ask you specific question, but I do not get clear statements and in consequence I assume, that I cannot help you.

サインイン to comment.

1 件の回答

Rik
回答者: Rik
2019 年 2 月 20 日

The code below will iterate through the cell levels. The resulting output is only true if all dimensions are equal and all elements are within tolerance.
M_t={{[0,1],[0 0 2]},{[0,1.01],[0 0 2]},{[0,1],[0 .001 3]}};
clc
assert(ismembertol_nested(M_t(1),M_t(2),0.1),'test failed for equal arrays');
assert(~ismembertol_nested(M_t(1),M_t(3),0.1),'test failed for unequal arrays');
assert(~ismembertol_nested(M_t(1),M_t{2},0.1),'test failed for unequal inputs');
function tf=ismembertol_nested(A,B,tol)
%Un-nest cell arrays until ismembertol can be used on the inner arrays.
%This will return false instead of an error if the shapes are not equal on
%any level.
try
if isa(A,'cell')
tol_cell=num2cell(repmat(tol,size(A)));
tf=all(cellfun(@ismembertol_nested,A,B,tol_cell));
else
ia=ismembertol(A,B,tol);
ib=ismembertol(B,A,tol);
tf=all([ia,ib]);
end
catch
tf=false;
end
end

  2 件のコメント

Jan
2019 年 2 月 20 日
@Rik: I'm dissapointed by the way ismembertol applies the tolerances. See my comment above:
abs(u-v) <= tol*max(abs([A(:);B(:)]))
So in ismembertol([1, 900], [20, 1000], 1) the tolerance 1 is multiplied by 1000, the maximum element, such that [1,1] is replied.
In addition the OP did not clarify yet, if the order of the elements matters or not.
Rik
2019 年 2 月 20 日
That seems strange indeed. I think it would make much more sense if that scale factor would be 1 by default, not that max. So to get the behavior I expected you need to call this
ismembertol(A,B,'DataScale',1)
I can see what the usefullness is if you are using it to check for float rounding errors, but that is not what I suspect most people would be using it for. There doesn't seem to be an easy way to search the FEX for the use of a function, so I can't check that suspicion.

サインイン to comment.



Translated by