Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Assign values w/ multiple conditions

Tags:

matrix

matlab

Let's have a M = [10 x 4 x 12] matrix. As example I take the M(:,:,4):

val(:,:,4) =

     0     0     1     0
     0     1     1     1
     0     0     0     1
     1     1     1     1
     1     1     0     1
     0     1     1     1
     1     1     1     1
     1     1     1     1
     0     0     1     1
     0     0     1     1

How can I obtain this:

val(:,:,4) =

     0     0     3     0
     0     2     2     2
     0     0     0     4
     1     1     1     1
     1     1     0     1
     0     2     2     2
     1     1     1     1
     1     1     1     1
     0     0     3     3
     0     0     3     3
  • If I have 1 in the first column then all the subsequent 1's should be 1.
  • If I have 0 in the first column but 1 in the second, all the subsequent 1's should be 2.
  • If I have 0 in the first and second column but 1 in the third then all the subsequent 1's should be 3.
  • If I have 0 in the first 3 columns but 1 in the forth then this one should be four.

Note: The logical matrix M is constructed:

Tab = [reshape(Avg_1step.',10,1,[]) reshape(Avg_2step.',10,1,[]) ...
    reshape(Avg_4step.',10,1,[]) reshape(Avg_6step.',10,1,[])];

M = Tab>=repmat([20 40 60 80],10,1,size(Tab,3));
like image 517
gmeroni Avatar asked Mar 04 '26 11:03

gmeroni


2 Answers

This is a very simple approach that works for both 2D and 3D matrices.

%// Find the column index of the first element in each "slice".
[~, idx] = max(val,[],2);  

%// Multiply the column index with each row of the initial matrix
bsxfun(@times, val, idx);
like image 69
Stewie Griffin Avatar answered Mar 06 '26 03:03

Stewie Griffin


This could be one approach -

%// Concatenate input array along dim3 to create a 2D array for easy work ahead 
M2d = reshape(permute(M,[1 3 2]),size(M,1)*size(M,3),[]);

%// Find matches for each case, index into each matching row and
%// elementwise multiply all elements with the corresponding multiplying
%// factor of 2 or 3 or 4 and thus obtain the desired output but as 2D array
%// NOTE: Case 1 would not change any value, so it was skipped.
case2m = all(bsxfun(@eq,M2d(:,1:2),[0 1]),2);
M2d(case2m,:) = bsxfun(@times,M2d(case2m,:),2);

case3m = all(bsxfun(@eq,M2d(:,1:3),[0 0 1]),2);
M2d(case3m,:) = bsxfun(@times,M2d(case3m,:),3);

case4m = all(bsxfun(@eq,M2d(:,1:4),[0 0 0 1]),2);
M2d(case4m,:) = bsxfun(@times,M2d(case4m,:),4);

%// Cut the 2D array thus obtained at every size(a,1) to give us back a 3D
%// array version of the expected values
Mout = permute(reshape(M2d,size(M,1),size(M,3),[]),[1 3 2])

Code run with a random 6 x 4 x 2 sized input array -

M(:,:,1) =
     1     1     0     1
     1     0     1     1
     1     0     0     1
     0     0     1     1
     1     0     0     0
     1     0     1     1
M(:,:,2) =
     0     1     0     1
     1     1     0     0
     1     1     0     0
     0     0     1     1
     0     0     0     1
     0     0     1     0
Mout(:,:,1) =
     1     1     0     1
     1     0     1     1
     1     0     0     1
     0     0     3     3
     1     0     0     0
     1     0     1     1
Mout(:,:,2) =
     0     2     0     2
     1     1     0     0
     1     1     0     0
     0     0     3     3
     0     0     0     4
     0     0     3     0
like image 27
Divakar Avatar answered Mar 06 '26 02:03

Divakar