Vectorization: incompatible sizes of arrays

2 views (last 30 days)
O is a matrix with n_p x n_o rows; P is a matrix with n_p rows. Both matrices have three columns.The second column in O should be filled with the average of two values in the second column of P: the first value at the row ip and the second value at randomly selected row.
counter = 0;
for ip = 1:n_p
for io = 1:n_o
counter = counter + 1;
O(counter,2) = (P(ip,2) + P(randi(n_p),2))/2;
end
end
I attempted to vectorize the code as:
ip = 1:n_p;
io = 1:n_o;
O(ip(:)+io(:),2) = (P(ip(:),2)+P(randi(n_p),2))/2;
I am receiving the following message: „Arrays have incompatible sizes for this operation“. Thank you for any suggestions.

Accepted Answer

Torsten
Torsten on 18 Sep 2022
Edited: Torsten on 18 Sep 2022
n_p = 3;
n_o = 3;
P = rand(n_p,2);
R = randi(n_p,n_p*n_o,1)
R = 9×1
3 2 2 2 3 1 3 2 1
IP = (cell2mat(arrayfun(@(i)vertcat(repmat(i,1,n_o)),1:n_p,'UniformOutput',0))).'
IP = 9×1
1 1 1 2 2 2 3 3 3
O(:,2) = (P(IP,2)+P(R,2))/2
O = 9×2
0 0.8950 0 0.5663 0 0.5663 0 0.2625 0 0.5912 0 0.5663 0 0.9199 0 0.5912 0 0.8950
  3 Comments
Torsten
Torsten on 19 Sep 2022
Or:
IP = reshape(repmat(1:n_p,n_o,1),n_p*n_o,1)
But yours is shorter :-)

Sign in to comment.

More Answers (2)

Bruno Luong
Bruno Luong on 19 Sep 2022
Edited: Bruno Luong on 19 Sep 2022
Simpler one liner
O(:,2) = P(randi(end,n_o,end),2) + repelem(P(:,2),n_o) / 2;

Bruno Luong
Bruno Luong on 18 Sep 2022
Edited: Bruno Luong on 18 Sep 2022
O(:,2) = reshape(reshape(P(randi(end,n_o,end),2),n_o,[]) + reshape(P(:,2),1,[]), [],1) / 2;
  2 Comments
Bruno Luong
Bruno Luong on 19 Sep 2022
Good.
It is not easy to check the correctness due to randomness.

Sign in to comment.

Products


Release

R2022b

Community Treasure Hunt

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

Start Hunting!