How to put non repeated elements of a symmetric matrix in a row vector?
3 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
I have 571 matrices (625x625) . all the matrices are symmetric with names of z1,z2,...z571;
I need to put non repeated elements of each matrix in a row vector. for example by putting non repeated elements of z1 in a row vector I make row vector c1. making c2 from z2 ,...
this is my code for making c1 from z1:
c1=zeros(1,195625);
z1=zeros(625);
for i=1:625
for j=1:625
if (i<=j)
z1(i,j)=c1(1,n);
n=n+1;
end
end
end
first question is it takes long time to run. is there any way to enhence the speed?
second question: If I want to make c1 from z1, c2 from z2 ,... c571 from z571 and make a matrix called X with the rows of c1,c2,...,c571, what should I do?
Thank you for your help
0 comentarios
Respuestas (3)
Jan
el 24 de Feb. de 2023
Editada: Jan
el 24 de Feb. de 2023
You have hidden an index in the name of the variables. This was a bad idea. It is time to re-organize your data.
Are all these variables in the current workspace or inside a MAT-file? In the later case, use this to create an array instead, such that you can use indices as indices instead of cyptic names of variables:
data = load('YourFile.mat');
Z = cell(1, 571);
for k = 1:572
Z{k} = data.(sprintf('z%d', k));
end
Now it is easy to create a loop over all variables. I assume you mean c1(1,n)=z1(i,j) instead of z1(i,j)=c1(1,n), which does not match the description in the text. Then:
C = cell(size(Z));
index = triu(true(625));
for k = 1:numel(Z)
C{k} = A{k}(index);
end
Now C{1} is your c1.
0 comentarios
Walter Roberson
el 24 de Feb. de 2023
In the special case where the diagonal is zero, see squareform()
0 comentarios
dpb
el 24 de Feb. de 2023
Editada: dpb
el 24 de Feb. de 2023
"... the matrices are symmetric with names of z1,z2,...z571;"
First, do NOT create sequentially-named variables such as that; from that point on there is no way to effectively process them without ugly, slow, and error prone methods.
Instead, make a 3D array with each a plane in 3rd dimension that you can iterate over or, alternatively, a cell array could hold each as well. Which would work better could depend upon just what is being done with the arrays/matrices.
As far as the Q? to return the lower triangular section, MATLAB doesn't have a builtin that returns them directly except as a triangular lower matrix but it's easy enough to extract the elements.
Probably the cleanest way to get the vector is
m=tril(reshape(1:16,4,4)); m=m+tril(m,-1).' % make an easy to see sample matrix
Now
tmp=tril(true(size(m))); % mask the lower triangular of size of matrix m
v=m(tmp).' % the lower tri values as row vector
You could wrap the above in a function; apply it in turn on each plane of the 3D array or cell content after you redo your data strorage to eliminate the multiple variables.
The above uses a temporary to avoid recreating the mask every time on the assumption this would be done a lot; in a function it could be made a persistent variable only needing set/reset on first call or if the size changes; otherwise the whole thing could be just a one-liner creating the mask on the fly.
1 comentario
dpb
el 24 de Feb. de 2023
" wrap the above in a function; apply it in turn on each plane of the 3D array or cell content "
Or, perhaps better factoring in this case would be to pass in the array (3D or cell), compute the mask for the first element of which and then iterate over the numel() of the input array.
Ver también
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!