Reputation: 25
I need to create k
matrix with diferent numbers of rows in MatLab. How can I do it?
Supose that I have k=5
and that I have 2
matrix, like that ones (The matrix Mpop
can be seen as any matrix)
Mpop =
0.9284 0.9299 -46.3239 1.2597 15.1842 21.8344 68.1583
-0.9948 -2.0102 -44.9439 1.7241 15.7423 38.2638 83.2077
1.1801 -0.9930 -41.8621 3.5203 14.3528 92.4522 134.3142
0.8557 -0.8754 -41.7513 2.7033 13.9570 67.2608 109.0121
1.1149 1.9312 -41.6132 2.6042 14.7964 66.1055 107.7187
1.1153 0.1656 -41.2766 4.4585 13.8216 120.1216 161.3983
-1.1358 -1.9447 -40.9061 1.9565 14.6642 47.1186 88.0247
0.0062 -0.2411 -40.4918 1.5405 13.8066 33.3358 73.8276
-0.1984 -1.1021 -39.9417 1.2500 13.6128 24.7840 64.7256
0.0876 -0.2284 -39.8141 2.2970 13.4819 56.0590 95.8732
and (IDX
is a vector with values 1
to k
)
IDX =
3
4
1
3
2
3
4
5
3
4
So, if line i
of IDX
is equal to 1
, I need to put the line i
of Mpop
in matrix Mpop1
, in the same way, if line i
of IDX
is equal to 2
, I need to put the line i
of Mpop
in matrix Mpop2
, etc.
I can do it in this way
Mpop1 = zeros(10,7);
Mpop2 = zeros(10,7);
Mpop3 = zeros(10,7);
Mpop4 = zeros(10,7);
Mpop5 = zeros(10,7);
for i=1:npop
if IDX(i,1)==1
Mpop1(i,:) = Mpop(i,:)
elseif IDX(i)==2
Mpop2(i,:) = Mpop(i,:)
elseif IDX(i)==3
Mpop3(i,:) = Mpop(i,:)
elseif IDX(i)==4
Mpop4(i,:) = Mpop(i,:)
else IDX(i)==5
Mpop5(i,:) = Mpop(i,:)
end
end
Mpop1 = Mpop1(all(Mpop1,2),:)
Mpop2 = Mpop2(all(Mpop2,2),:)
Mpop3 = Mpop3(all(Mpop3,2),:)
Mpop4 = Mpop4(all(Mpop4,2),:)
Mpop5 = Mpop5(all(Mpop5,2),:)
but it is not good because K
can be diferent from 5
.
So, how can I do it if I have any value of K
?
Upvotes: 2
Views: 90
Reputation: 112749
As stated by Sardar Usama, it's better use a cell array rather than creating dynamic variables.
Here's another way to create that cell array without loops, using the accumarray
function:
result = accumarray(IDX, (1:numel(IDX)).', [], @(x){Mpop(sort(x),:)})
This splits the integers from 1
to numel(IDX)
in groups as determined by the values in IDX
; applies those indices into the original matrix Mpop
; and packs the resulting submatrices in a cell array.
Upvotes: 1
Reputation: 11072
As suggested by juef, using cell arrays is the way to go:
% define the length of the arrays/matrices
nID = max(IDX);
npop = length(IDX);
% allocate memory
Mpops = cell(nID, 1);
[Mpops{:}] = deal(zeros(10,7));
% fill the matrices
for i=1:npop
Mpops{IDX(i)}(i, :) = Mpop(i,:);
end
% remove empty rows
for i=1:nID
Mpops{i} = Mpops{i}(all(Mpops{i},2),:);
end
Upvotes: 0
Reputation: 19689
It would be a bad idea to create those 5 matrices. Rather use a cell array and use its indexes to access/use a particular matrix. Here is a solution using 2 loops:
numIDX = numel(IDX); %Number of elements of IDX
tmp = cell(k,numIDX); %Pre-allocation
for ii=1:numIDX
tmp{IDX(ii),ii}=Mpop(ii,:); %Converted the if-else conditions into a single line
end
req = cell(k,1); %Pre-allocation of the required cell
for jj=1:k
req{jj}=vertcat(tmp{jj,:}); %vertically concatenating/ removing the empty cells of tmp
end
Now use the indices of this cell array to access Mpop1
, Mpop2
, Mpop3
, Mpop4
, and Mpop5
i.e. with req{1}
, req{2}
, req{3}
, req{4}
, and req{5}
respectively.
Upvotes: 2
Reputation: 90
If your matrixes have different names, there isn't much else you can do by working this way. A good way to achieve this, however, would probably be to use cell arrays (see this StackOverflow answer about them). Basically, all your matrixes will be in a single variable, and you can select the right matrix with an index, which would be IDX(i)
in your case.
Upvotes: 1