Adding matrix columns randomly

Hi everyone.
I have two matrices A and B with the same size.
A=B; size(800,100);
I would like to pick a random colum in A and add it to a random colum in B and generate C.
How can this be executed?
I have tried the following but it seems to me to be a longer way. Is there any shorter way of accomplishing this task?
x = randperm(size(A,2),100);
y=randperm(size(B,2),100);
C=A(:,x)+B(:,y);
Thanks for your support.

Answers (2)

John D'Errico
John D'Errico on 17 May 2020
Edited: John D'Errico on 17 May 2020
You want to pick random columns from A and B? Can they ever be the same column? Since A and B are the same matrices, we can make it very easy. But I'd really need to know if they can NEVER be the same columns, as that would change the code slightly.
Anyway, the general idea is to do this as a matrix multiply. For example, what happens when you multiply the matrix A by a vector that has only a single non-zero element, which just happens to be 1? That is, suppose you create the vector
V = zeros(100,1);
V(50) = 1;
A*V
What does the product of A*V look like? Essentially that matrix*vector multiply extracts column 50 from the matrix A.
Suppose we did the same thing for B? This time, I'll do it by inserting a RANDOM 1 in V.
VA = zeros(100,1);
VB = VA;
VA(randi(100,1)) = 1;
VB(randi(100,1)) = 1;
C = A*VA + B*VB;
In fact, since A == B, we can do this more easily.
C = A*(VA + VB);
Note that the wau I constructed VA and VB, sometimes the column chosen can be the same. If you wanted the columns to never be coincident, then this would work:
V = zeros(100,1);
V(randperm(100,2)) = 1;
C = A*V;
Next, it is not absolutely clear, but I wonder if you really want to do this 100 times, creating a new matrix C that is also 800x100?
Again, the solution depends on whether any two columns can ever coincide in that sum of columns.
The general idea is to now multiply A by a 100x100 matrix that is almost entirely zero, but happens to have exactly 2 unit elements in each column. If the columns can coincide, then the 100x100 matrix V may have the number 2 in some column. Again, all you need to do is generate the matrix V with the desired property, and then you get C by a matrix multiply.
Or, if in your real problem, if A and B happen to be DIFFERENT matrices, then create two matrices VA and VB, to do the multiplies. Again though, to truly answer your problem, I'd need to understand what constraints apply. Are A and B truly the same always? If so, then why have two matrices?
As well, can the columns chosen EVER be the same?
Without those pieces of information, the answer is difficult to pose because of the ambiguities I see in your question. But when you can answer that, it is easy. It is just a matrix multiply.
Try something like this
A = rand(800, 100);
B = rand(800, 100);
idxc = randi([1 100]);
idxb = randi([1 100]);
C = B;
C(:, idxc) = C(:, idxc) + B(:, idxb);

7 Comments

Lewis S
Lewis S on 17 May 2020
Edited: Lewis S on 17 May 2020
I suppose you meant
A = rand(800, 100);
B = rand(800, 100);
idxc = randi([1 100]);
idxb = randi([1 100]);
C = B;
C(:, idxc) = A(:, idxc) + B(:, idxb);
I think this works as well. Thank you.
Yes, but note that C=B at this line, so you can use either.
C is not the same as B. C has the same size as both B and A and is generated as the sum of the A and B. Would it be right to index it with the idxc?
Consider these two lines
C = B;
C(:, idxc) = A(:, idxc) + B(:, idxb) % when executing these lines B and C are same
Following line is equivalent to above
C(:, idxc) = A(:, idxc) + C(:, idxb)
Note that C will have the same values as matrix B except one column taken from matrix A.
I think we are not on the same page.
C is supposed to the sum of randomly selected columns from B and A. Something like this, if I am to use your code.
C=zeros(800,100)
A = rand(800, 100);
B = rand(800, 100);
idxa = randi([1 100]);
idxb = randi([1 100]);
C (:,:)= A(:, idxc) + B(:, idxb);
However, this does not return the appropriate size of the matrix.
A = rand(800, 100);
B = rand(800, 100);
idx = randperm(size(A,2),100);
idy=randperm(size(B,2),100);
C=A(:,idx)+B(:,idy);
The above code produces what I want but I thought it was long. You could look at the differences between them and let me know how I can improve it.
Yes, I misinterpreted the question. The way you have written appears to be the shortest possible way in MATLAB. Although you can omit the second input to randperm. For example
C = A(:,randperm(size(A,2))) + B(:,randperm(size(B,2)));
Thank you

Sign in to comment.

Categories

Products

Release

R2019b

Asked:

on 17 May 2020

Commented:

on 20 May 2020

Community Treasure Hunt

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

Start Hunting!