2

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?

0

4 Answers 4

2

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.

Sign up to request clarification or add additional context in comments.

2 Comments

Why are dynamic variables/matrices a bad idea? Read here: stackoverflow.com/questions/32467029/… Also don't use i and j as variable names. Read here why: stackoverflow.com/questions/14790740/…
Having said that, if you really want those matrices separately, in the 2nd for loop, use this line instead: assignin('base',['Mpop',num2str(jj)],vertcat(tmp{jj,:}));
1

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.

Comments

1

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.

2 Comments

How I will access Mpop1, Mpop2, etc in this case?
@ElcioSilveira Just like as in my answer. result{1}, result{2}, ...
0

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

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.