Reputation: 13
I'm looking for a way to test if all elements of a matrix are greater than or equal to their corresponding indexes values in another matrix, and if not to stop evaluating. This is part of an elseif
statement for setting a lower bound for values, thus as simplified example:
Lower Bound matrix: A = [4 5 6 7]
New values matrix: B = [7 8 9 10]
Is B>=A
then yes, accept and proceed
whereas
Lower Bound matrix: A = [4 5 6 7]
New values matrix: C = [5 3 5 8]
Is C>=A
? then no, all elements of C
are not greater than A
, reject and stop
My solution so far is a bit hackneyed:
Is sum(C>=A) < length(C)
? no, then reject and stop
This gives the sum of the true/false values in the comparison C>=A
, which if all values of C
were greater would equal the length of C
, else the sum would be less than the length of C
. I keep thinking there's a simple and more elegant solution to this that I'm overlooking and would be grateful for any thoughts. Thanks!
Upvotes: 1
Views: 1701
Reputation: 65460
MATLAB has a built-in function for performing this action called all
. You can use this on a logical matrix to determine if all values are true. In your case you would pass the logical matrix: B >= A
.
A = [4,5,6,7];
B = [7,8,9,10];
all(B(:) >= A(:))
1
Notice that I have used (:)
above which ensures that both A
and B
are column vectors prior to performing the comparison. This way, they can be of any arbitrary dimension and the result of all
will always be a scalar.
While you're at it, you may also look into any
.
Upvotes: 2
Reputation: 68
I assume by an elegant solution you mean a solution which is more efficient. Lets create test data:
A = zeros(100000,100000); B = zeros(100000,100000);
Linear Loop
for i = 1:numel(A)
if A(i) < B(i)
display('different')
break
end
end
Logical indexing
if (sum(sum(B>=A))~=numel(A))
display('different')
end
The loop is better when its comes to the best case (first element is smaller):
Elapsed time is 0.000236 seconds. Elapsed time is 0.131802 seconds.
and when its the average case:
Elapsed time is 0.001993 seconds. Elapsed time is 0.196228 seconds.
But we only care about the worst case:
B(end) = 1;
Elapsed time is 8.181473 seconds. Elapsed time is 0.108002 seconds.
Upvotes: 0
Reputation: 3177
You must indeed rely on logical indexing. To check whether a given matrix B
has elements greater than or equal to their corresponding indexes values in another given matrix A
you can do something like:
if (sum(sum(B>=A))==numel(A))
%enter if body here
end
The statement B>=A
will return a logical matrix with 1
in position (i,j)
if B(i,j)>=A(i,j)
. You then sum all the 1
s inside such matrix and then check if such sum is equal to the number of elements (numel()
) in A
(or B
).
In your example. Given
A=[4 5 6 7];
B=[7 8 9 10];
the statement B>=A
will return
ans =
1 1 1 1
because all elements in B
are greater then elements in A
. Sum this vector, you'll get 4. Is the sum (4) equal to the number of elements (4)? Yes. Then all elements in B
are greater than or equal to the elements in A
.
Note: the double sum()
makes your code more robust. It will indeed work also with matrices and not just with vectors. That is because if you do sum()
on a matrix, Matlab by default does not return the sum of all its elements, but the sum along the first dimension whose size is different from 1. So if our matrix is:
C =
8 1 6
3 5 7
4 9 2
sum(C)
will return
ans =
15 15 15
(Matlab took the sum of every column).
By taking also the sum of such vector we'll get the sum of all the elements.
This ends the quick explanation regarding the nested sum()
.
Upvotes: 0