How to put non repeated elements of a symmetric matrix in a row vector?

3 ビュー (過去 30 日間)
ahmad
ahmad 2023 年 2 月 24 日
コメント済み: dpb 2023 年 2 月 24 日
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

回答 (3 件)

Jan
Jan 2023 年 2 月 24 日
編集済み: Jan 2023 年 2 月 24 日
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.

Walter Roberson
Walter Roberson 2023 年 2 月 24 日
In the special case where the diagonal is zero, see squareform()

dpb
dpb 2023 年 2 月 24 日
編集済み: dpb 2023 年 2 月 24 日
"... 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
m = 4×4
1 2 3 4 2 6 7 8 3 7 11 12 4 8 12 16
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
v = 1×10
1 2 3 4 6 7 8 11 12 16
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 件のコメント
dpb
dpb 2023 年 2 月 24 日
" 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.

サインインしてコメントする。

カテゴリ

Help Center および File ExchangeMatrix Indexing についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by