Search multiple matrices for values at common index positions

12 visualizaciones (últimos 30 días)
I am trying to analyse several tens of 90x90 matrices and I want to find a summary matrix that only shows a logical 1 if an element has any non zero value that is common to all the matrices at the same index position. In the example below the desired result is to show that there is a value in common between all matrices in position [2,2] and [4,4]. I do not wish to show the values themselves or compare their values. I've tried working with ismember , find , intersect , a==b for just two matrices but nothing seems to do the trick. I can't seem to find a similar query in the archives either. Does anyone know of a suitable function or do I need to write an element by element search routine across all the matrices . All matrices are double and all identically sized .
a =
1 0 0 0 0
0 3 0 0 0
0 0 5 0 0
0 0 0 7 8
>> d = [ 0 0 0 12 0; 0 3 0 4 0; 0 0 0 0 0 ; 34 0 0 9 0]
d =
0 0 0 12 0
0 3 0 4 0
0 0 0 0 0
34 0 0 9 0
>> e = [ 0 0 0 0 0; 0 15 0 0 0; 0 0 0 2 0 ; 0 0 0 5 0]
e =
0 0 0 0 0
0 15 0 0 0
0 0 0 2 0
0 0 0 5 0
>> Result=[ 0 0 0 0 0; 0 1 0 0 0; 0 0 0 0 0 ; 0 0 0 1 0]
Result =
0 0 0 0 0
0 1 0 0 0
0 0 0 0 0
0 0 0 1 0
  6 comentarios
AndyT
AndyT el 24 de Jun. de 2015
Thanks for the good advice Stephen, I am now coming to understand the power of matlab when you properly use dimensional properties of arrays and you have stopped me learning bad practices early on.
Stephen23
Stephen23 el 24 de Jun. de 2015
Editada: Stephen23 el 24 de Jun. de 2015
Learn to use the dimensions of arrays and MATLAB will fly...
MATLAB is a high-level language, and it works best when data is kept together as much as possible. Avoid nesting, multiple variables and loops (unless you really have to). Then you can use vectorized code to really get the best out of MATLAB: neat and fast operations.
You should read some other tips for writing efficient MATLAB code.
Good luck and have fun!

Iniciar sesión para comentar.

Respuesta aceptada

James Tursa
James Tursa el 23 de Jun. de 2015
Editada: James Tursa el 23 de Jun. de 2015
If you are just looking for when there are non-zero entries in the same index in all matrices, e.g.,
Result = a & d & e;
To process "several tens" of these matrices, you may want to write a function. How the function is written will depend on how you have your matrices stored (individual variables, members of a cell array or struct, etc). E.g., if they are individual variables, then a function like this might be a good start:
function g = allnz(varargin)
n = nargin;
if( n )
g = logical(varargin{1});
for k=2:n
g = g & varargin{k};
end
else
g = [];
end
Then you could call it like this:
Result = allnz(a,d,e);
  2 comentarios
Guillaume
Guillaume el 24 de Jun. de 2015
In my opinion, a better implementation (no loop) of your allnz would be:
function g = allnz(varargin)
dimplus1 = ndims(varargin{1}) + 1;
g = all(cat(dimplus1, varargin{:}), dimplus1);
end
AndyT
AndyT el 24 de Jun. de 2015
Thanks James and Guillaume , I think this gets to the heart of my problem and combines the good advice to concatenate all the matrices into one larger array. Thanks to all for taking the time to assist me .

Iniciar sesión para comentar.

Más respuestas (4)

Andrei Bobrov
Andrei Bobrov el 24 de Jun. de 2015
a.*d.*e > 0;
  1 comentario
AndyT
AndyT el 24 de Jun. de 2015
Thanks Andrei , very elegant though I take the points above that I may need to reformat all my matrices into one larger stacked array for the work I need to do,

Iniciar sesión para comentar.


Guillaume
Guillaume el 23 de Jun. de 2015
Editada: Guillaume el 24 de Jun. de 2015
As given in the example:
result = all(cat(3, a, d, e), 3)
Note that if you tens of these matrices, rather than putting them in individual variables, you're better off putting them in a cell array:
allmatrices = {a, b, c, d, e, f, ...};
In which case the above is simply:
result = all(cat(3, allmatrices{:}), 3);
Or even better since they all have the same size, just stack them all up in the third dimension as I have done as a first step, so:
allmatrices = cat(3, a, b, c, d, e, f, ...);
In which case the code is simply:
result = all(allmatrices, 3);
  1 comentario
AndyT
AndyT el 24 de Jun. de 2015
Thanks Guillaume, an excellent way of using the dim=3 parameter to stack the all and cat functions. I'll remember this.

Iniciar sesión para comentar.


Azzi Abdelmalek
Azzi Abdelmalek el 23 de Jun. de 2015
Editada: Azzi Abdelmalek el 23 de Jun. de 2015
a=[ 1 0 0 0 0 ; 0 3 0 0 0 ; 0 0 5 0 0 ; 0 0 0 7 8]
d=[ 0 0 0 12 0; 0 3 0 4 0; 0 0 0 0 0 ; 34 0 0 9 0]
e=[ 0 0 0 0 0; 0 15 0 0 0; 0 0 0 2 0 ; 0 0 0 5 0]
aa=~~a
dd=~~d
ee=~~e
aa&dd&ee

Martin Brown
Martin Brown el 24 de Jun. de 2015
As above, reformat your code to put the matrices into a single 3D matrix, something like:
A(:,:,1) = [1 0; 0 1];
A(:,:,2) = [2 0; 0 0];
find(sum(A(:,:,1:end)~=0,3)==2);

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Community Treasure Hunt

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

Start Hunting!

Translated by