Elcio Silveira
Elcio Silveira

Reputation: 25

How to create a k matrix according to an array of indices using matlab?

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

Answers (4)

Luis Mendo
Luis Mendo

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

m7913d
m7913d

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

Sardar Usama
Sardar Usama

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

juef
juef

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

Related Questions