Nanor
Nanor

Reputation: 37

creating diagonal matrix with selected elements

I have a 4x5 matrix called A from which I want to select randomly 3 rows, then 4 random columns and then select those elements which coincide in those selected rows and columns so that I have 12 selected elements.Then I want to create a diagonal matrix called B which will have entries either 1 or 0 so that multiplication of that B matrix with reshaped A matrix (20x1) will give me those selected 12 elements of A.

How can I create that B matrix? Here is my code:

A=1:20;
A=reshape(A,4,5);
Mr=4;
Ma=3;
Na=4;
Nr=5;
M=Ma*Mr;
[S1,S2]=size(A);
N=S1*S2;
y2=zeros(size(A));
k1=randperm(S1);
k1=k1(1:Ma);
k2=randperm(S2);
k2=k2(1:Mr);
y2(k1,k2)=A(k1,k2);

Upvotes: 0

Views: 384

Answers (2)

Matt
Matt

Reputation: 2802

Here is a hack but since you are creating y2 you might as well just use it instead of creating the useless B matrix. The bsxfun answer is much better.

A=1:20;
A=reshape(A,4,5);
Mr=4;
Ma=3;
Na=4;
Nr=5;
M=Ma*Mr;
[S1,S2]=size(A);
N=S1*S2;
y2=zeros(size(A));
k1=randperm(S1);
k1=k1(1:Ma);
k2=randperm(S2);
k2=k2(1:Mr);
y2(k1,k2)=A(k1,k2);
idx = reshape(y2 ~= 0, numel(y2), []);
B = diag(idx);
% "diagonal" matrix 12x20
B = B(all(B==0,2),:) = [];
output = B * A(:)

output =

 1
 3
 4
 9
11
12
13
15
16
17
19
20

y2 from example.

y2 =

 1     0     9    13    17
 0     0     0     0     0
 3     0    11    15    19
 4     0    12    16    20

Upvotes: 0

IKavanagh
IKavanagh

Reputation: 6187

It's a little hard to understand what you want and your code isn't much help but I think I've a solution for you.

I create a matrix (vector) of zeros of the same size as A and then use bsxfun to determine the indexes in this vector (which will be the diagonal of B) that should be 1.

>> A = reshape(1:20, 4, 5);
>> R = [1 2 3]; % Random rows
>> C = [2 3 4 5]; % Random columns
>> B = zeros(size(A));
>> B(bsxfun(@plus, C, size(A, 1)*(R-1).')) = 1;
>> B = diag(B(:));
>> V = B*A(:);
>> V = V(V ~= 0)
V =
     2
     3
     4
     5
     6
     7
     8
     9
    10
    11
    12
    13

Note: There is no need for B = diag(B(:)); we could have simply used element by element multiplication in Matlab.

>> V = B(:).*A(:);
>> V = V(V ~= 0)

Note: This may be overly complex or very poorly put together and there is probably a better way of doing it. It's my first real attempt at using bsxfun on my own.

Upvotes: 4

Related Questions