How to use logical indexing for slices of a 3D matrix

74 visualizaciones (últimos 30 días)
Anh Mai
Anh Mai el 21 de Ag. de 2021
Comentada: Anh Mai el 22 de Ag. de 2021
Hi guys, I am trying to set value for different page of 3D matrix based on 2D matrix logical command.
domain=rand(4,4,4);
domain2D=domain(:,:,1);
condition1=domain2D>0.5;%logical index all elements of first slice that greater than 0.5
condition2=domain2D<0.2;%logical index all elements of first slice that smaller than 0.2
domain2D(condition)=10;%assign all elements that greater than 0.5 a value of 10.
domain2D(condition2)=5;%assign all elements that smaller than 0.2 a value of 5.
After running the above code, we get the following
condition1 =
4×4 logical array
1 0 1 0
1 0 0 0
1 1 1 1
0 0 0 0
>> condition2
condition2 =
4×4 logical array
0 1 0 1
0 0 0 0
0 0 0 0
1 0 0 0
As you can see, we can easily apply condition1 and condition2 for a 2D array, which is 1st slice of the 3D array, ie domain(:,:,1). Now, based on the condition1 and condition2, I like to use these logical indexes for any slices of the 3D array that i want. In this example, each elements falls within condition 1 a value of 10 for slice 1 to 3, and each elements falls within condition 2 a value of 5 from slice 1 to 2 of the 3D array. You can visualize the results as below picture.
If we are working with 2D array, it would be very simple as: domain(condition1)=10 (assume domain is 2D). How can we use this logical function in 3D array for any slices that I would like to?. Please help. Thank you all.

Respuesta aceptada

Adam Danz
Adam Danz el 22 de Ag. de 2021
Editada: Adam Danz el 22 de Ag. de 2021
nxm logical index applied to all pages of a 3D array
domain = rand(4,4,4);
condition1 = domain(:,:,1).*ones(size(domain)) > 0.5;
condition2 = domain(:,:,1).*ones(size(domain)) < 0.2;
domain(condition1) = 10;
domain(condition2) = 5
domain =
domain(:,:,1) = 10.0000 0.3294 0.2245 10.0000 0.4671 10.0000 10.0000 5.0000 0.2289 5.0000 0.2538 5.0000 0.2184 0.4877 10.0000 0.3680 domain(:,:,2) = 10.0000 0.9963 0.4664 10.0000 0.0913 10.0000 10.0000 5.0000 0.3675 5.0000 0.5812 5.0000 0.2225 0.0429 10.0000 0.0490 domain(:,:,3) = 10.0000 0.3901 0.6374 10.0000 0.0326 10.0000 10.0000 5.0000 0.0600 5.0000 0.7046 5.0000 0.3263 0.3253 10.0000 0.5136 domain(:,:,4) = 10.0000 0.2854 0.0045 10.0000 0.5459 10.0000 10.0000 5.0000 0.7885 5.0000 0.8755 5.0000 0.2039 0.3931 10.0000 0.7801
nxm logical indexing applied to specific pages of a 3D array
% tf is a n*m logical matrix
% pg is a row vector of pages
% output: matrix of linear indices
get3DInd = @(tf,pg)find(tf) + numel(tf)*(pg-1);
domain = rand(4,4,4);
condition1 = domain(:,:,1) > 0.5;
% Apply to pages 1 and 3
domain(get3DInd(condition1,[1,3])) = 10
domain =
domain(:,:,1) = 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 0.2942 10.0000 0.2943 0.2755 10.0000 0.2355 domain(:,:,2) = 0.4523 0.8492 0.3084 0.7687 0.1052 0.4329 0.3370 0.3450 0.8711 0.0895 0.8002 0.4803 0.5805 0.1339 0.6097 0.7108 domain(:,:,3) = 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 10.0000 0.7881 10.0000 0.0664 0.9131 10.0000 0.7121 domain(:,:,4) = 0.0603 0.1033 0.1447 0.3383 0.3646 0.5129 0.3797 0.9220 0.7900 0.1761 0.6725 0.6818 0.0385 0.4884 0.5942 0.2325
  5 comentarios
Adam Danz
Adam Danz el 22 de Ag. de 2021
Editada: Adam Danz el 22 de Ag. de 2021
Sure, get3DInd is an anonymous function with two inputs (tf, pg) and an output. tf is "condition" matrices which are n*m logical matrices that identify the rows and columns of the 3D array. pg are the page indices. It is assumed that the size of tf is the same size as the first two dimensions for the 3D array.
The purpose of the function is to produce a list of linear indices of a 3D array based on the rows and columns identified in tf and the page indices identified in pg.
Don't forget that values in Matlab are counted top-to-bottom, left-to-right, and then by pages (see previous link).
Example of linear index:
a = randi(100,2,4,3)
a =
a(:,:,1) = 82 87 15 23 57 48 55 28 a(:,:,2) = 53 12 7 17 66 86 85 96 a(:,:,3) = 19 84 17 82 100 64 42 32
linearIdx = [3 10 14 21]; % 3rd, 10th, 14th, and 21st value of 'a'
a(linearIdx)
ans = 1×4
87 66 85 17
Example of get3DInd
get3DInd = @(tf,pg)find(tf) + numel(tf)*(pg-1);
a = rand(3,3,3) % 3D array
a =
a(:,:,1) = 0.2575 0.5046 0.8256 0.0822 0.6993 0.4764 0.7970 0.0817 0.7536 a(:,:,2) = 0.2111 0.3418 0.0524 0.8924 0.8442 0.8404 0.9000 0.8456 0.1507 a(:,:,3) = 0.9856 0.0617 0.7318 0.8593 0.8626 0.8794 0.0317 0.8297 0.8641
tf = logical([0 1 0; 1 1 1; 0 1 0])
tf = 3×3 logical array
0 1 0 1 1 1 0 1 0
% Create linear indices
% The pattern in tf will be applied to pages 1 and 3
linIdx = get3DInd(tf, [1,3])
linIdx = 5×2
2 20 4 22 5 23 6 24 8 26
a(linIdx) = NaN
a =
a(:,:,1) = 0.2575 NaN 0.8256 NaN NaN NaN 0.7970 NaN 0.7536 a(:,:,2) = 0.2111 0.3418 0.0524 0.8924 0.8442 0.8404 0.9000 0.8456 0.1507 a(:,:,3) = 0.9856 NaN 0.7318 NaN NaN NaN 0.0317 NaN 0.8641
As you can see, the pattern identified in tf has been applied to the 1st and 3rd page of the 3D array 'a'.
Anh Mai
Anh Mai el 22 de Ag. de 2021
Well, you are exceptionally genius. Thank you very much for your time and thorough explanation. U just saved me from a big headache.

Iniciar sesión para comentar.

Más respuestas (0)

Categorías

Más información sobre Matrix Indexing en Help Center y File Exchange.

Etiquetas

Productos


Versión

R2021a

Community Treasure Hunt

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

Start Hunting!

Translated by