How to compare array's values with each other?
Afficher commentaires plus anciens
In an array (a) with indexes from 1 to m, I want to compare the values of this array one by one with each other, and if the distance (Difference) between two values is more than a value (z), for example, the difference between a(i) and a(j) at indexes i and j is more than z, I want to save these two indexes i and j and represent them in the output. I wrote these codes:
if abs(a(i)-a(j))> z
disp(i);
disp(j);
fprintf('result is between %10.6f and %10.6f',i,j);
end
but there is an error in if line:
Subscript indices must either be real positive integers or logicals.
How can I define indexes for matlab. Is a for loop (for i=1:m) needed for passing the array, If a loop is necessary, should I put fprintf out of the loop because it will repeat. For saving and representing the indexes i and j in the output, I'm looking for better functions besides disp or fprintf.
Réponse acceptée
Plus de réponses (1)
Jon
le 31 Juil 2019
Staying close to what you have started here, you could put your code into a double loop, for example
% assign threshold
z = 10; % or what ever your threshold is
% find number of elements to loop through
N = length(a)
% preallocate array to hold results
% elements of D will be set to true (1) when
% a(i) and a(j) are further apart than threshold
D = zeros(N,N)
for i = 1:N
for j = 1:N
D(i,j)=abs(a(i)-a(j))> z
end
end
% display indices of elements whose absolute difference exceeds threshold, z
[idxI, idxJ] = find(D)
disp(idxI)
disp(idxJ)
5 commentaires
Jon
le 31 Juil 2019
I had not seen Guillaume's answer until after I posted mine, but clearly his approach is much more compact and in the spirit of good MATLAB programming, to avoid loops and vectorize when possible. In this case he takes good advantage of MATLAB's implicit expansion capability introduced after 2016b. See https://www.mathworks.com/help/matlab/matlab_prog/compatible-array-sizes-for-basic-operations.html and also https://blogs.mathworks.com/loren/2016/10/24/matlab-arithmetic-expands-in-r2016b/
I still forget that it is now a well defined operation to for example subtract a row vector from a column vector (assuming they both have the same number of elements)
Guillaume
le 31 Juil 2019
Even before R2016b, you could do the same with bsxfun (or meshgrid, ndgrid, or repmat at the expense of a bit more memory):
distance = bsxfun(@minus, a, a.'); %works both pre- and post- R2016b, but from R2016b implicit expansion is usually faster
Good point.
One question @Guillaume, I notice you use the transpose operator:
.'
rather than the conjugate transpose operator:
'
For real vectors the result will be the same. Do you recommend using the transpose operator even when the problem involves only real matrices?
Guillaume
le 31 Juil 2019
For real matrix, I don't think there's any difference in performance between the two, so you can indeed use either.
However, since the OP never specified that the vectors were pure real, and since the original code would have worked with complex numbers, I used the plain transpose so as not to change the meaning of the distance formula.
By default, I tend to use .' so that the code works the same with real or complex numbers, when all is meant is changing the direction of a vector.
I'm not a mathematician, maybe it makes sense that the shorter ' is a conjugate tranpose. if the design had been up to me, I would have swapped the meaning of the two so that ' was a plain transpose and .' a conjugate transpose.
Jon
le 31 Juil 2019
@Guillaume - Thanks for the explanation.
Catégories
En savoir plus sur Matrix Indexing dans Centre d'aide et File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!