Assign different values per column using logical indexing

I am new to logical indexing and am having some trouble with a specific issue. I want to use logical indexing to assign a certain value to all values in a column where the condition is true, and then a different value to the next column where another condition is true at the same time. E.g.:
matrix = magic(5); % data matrix
boundary_conditions = [10, 100]; % boundary conditions
matrix(matrix(:, [2,3]) < boundary_conditions) = boundary_conditions; % use logical indexing to set values of time columns
Unable to perform assignment because the left and right sides have a different number of elements.
Essentially, I want to find which values in column 2 are below 10, and which values in column 3 are below 100. Then, those that are in column 2, set them to 10, and those that are in column 3, set to 100. And have that reflected in the original matrix, so only columns 2 and 3 are changed.
For some context:
I am working on a molecular dynamics simulation, so I want to check after each timestep whether a particle has passed the boundary in the x- or y- direction.
Because of this, performance is a necessity, since I am working with ~3,000,000 time iterations. So I want to maximize my efficiency.

 採用された回答

Voss
Voss 2023 年 9 月 27 日
編集済み: Voss 2023 年 9 月 27 日

1 投票

matrix = magic(5); % data matrix
boundary_conditions = [10, 100]; % boundary conditions
disp(matrix);
17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
% using logical indexing:
idx = matrix(:,2) < boundary_conditions(1);
matrix(idx,2) = boundary_conditions(1);
idx = matrix(:,3) < boundary_conditions(2);
matrix(idx,3) = boundary_conditions(2);
disp(matrix);
17 24 100 8 15 23 10 100 14 16 4 10 100 20 22 10 12 100 21 3 11 18 100 2 9
% another approach using max() function:
matrix = magic(5); % restore original data matrix
matrix(:,2) = max(matrix(:,2),boundary_conditions(1));
matrix(:,3) = max(matrix(:,3),boundary_conditions(2));
disp(matrix);
17 24 100 8 15 23 10 100 14 16 4 10 100 20 22 10 12 100 21 3 11 18 100 2 9
% another approach using max() function:
matrix = magic(5); % restore original data matrix
matrix(:,[2 3]) = max(matrix(:,[2 3]),repmat(boundary_conditions,size(matrix,1),1));
disp(matrix);
17 24 100 8 15 23 10 100 14 16 4 10 100 20 22 10 12 100 21 3 11 18 100 2 9

4 件のコメント

Jose Pratdesaba
Jose Pratdesaba 2023 年 9 月 27 日
Thank you for the answer!
One question (more so out of curiosity): so there's no way to generalize this process for any number of columns and boundary conditions?
Voss
Voss 2023 年 9 月 27 日
編集済み: Voss 2023 年 9 月 27 日
The third approach I showed is a general approach:
matrix = magic(10); % data matrix
disp(matrix);
92 99 1 8 15 67 74 51 58 40 98 80 7 14 16 73 55 57 64 41 4 81 88 20 22 54 56 63 70 47 85 87 19 21 3 60 62 69 71 28 86 93 25 2 9 61 68 75 52 34 17 24 76 83 90 42 49 26 33 65 23 5 82 89 91 48 30 32 39 66 79 6 13 95 97 29 31 38 45 72 10 12 94 96 78 35 37 44 46 53 11 18 100 77 84 36 43 50 27 59
columns = [2,4,5,7,9];
boundary_conditions = [10,20,40,60,50]; % boundary conditions
matrix(:,columns) = max(matrix(:,columns),repmat(boundary_conditions,size(matrix,1),1));
disp(matrix);
92 99 1 20 40 67 74 51 58 40 98 80 7 20 40 73 60 57 64 41 4 81 88 20 40 54 60 63 70 47 85 87 19 21 40 60 62 69 71 28 86 93 25 20 40 61 68 75 52 34 17 24 76 83 90 42 60 26 50 65 23 10 82 89 91 48 60 32 50 66 79 10 13 95 97 29 60 38 50 72 10 12 94 96 78 35 60 44 50 53 11 18 100 77 84 36 60 50 50 59
Jose Pratdesaba
Jose Pratdesaba 2023 年 9 月 27 日
Ahh I see now, thank you very much!
Voss
Voss 2023 年 9 月 27 日
You're welcome!

サインインしてコメントする。

その他の回答 (1 件)

Dyuman Joshi
Dyuman Joshi 2023 年 9 月 27 日

1 投票

A simpler approach for your task would be
matrix = magic(5) % data matrix
matrix = 5×5
17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
matrix(:,2) = max(matrix(:,2),10)
matrix = 5×5
17 24 1 8 15 23 10 7 14 16 4 10 13 20 22 10 12 19 21 3 11 18 25 2 9
matrix(:,3) = max(matrix(:,3),100)
matrix = 5×5
17 24 100 8 15 23 10 100 14 16 4 10 100 20 22 10 12 100 21 3 11 18 100 2 9
If you have to do this for some specific columns or all the columns (for which manually doing that would be a tedious task) you can integrate a for loop.
%For example
matrix = magic(5)
matrix = 5×5
17 24 1 8 15 23 5 7 14 16 4 6 13 20 22 10 12 19 21 3 11 18 25 2 9
s = size(matrix,2);
boundary_conditions = randi([10 20],1,s)
boundary_conditions = 1×5
16 19 11 11 20
for k=1:s
matrix(:,k) = max(matrix(:,k),boundary_conditions(k));
end
matrix
matrix = 5×5
17 24 11 11 20 23 19 11 14 20 16 19 13 20 22 16 19 19 21 20 16 19 25 11 20

5 件のコメント

Jose Pratdesaba
Jose Pratdesaba 2023 年 9 月 27 日
Thank you for the answer!
I was wondering, more out of curiosity, is there any way to generalize this for any number of columns and boundary conditions? Or do you have to use a for-loop to do that?
That depends on the data you have.
One approach would be -
arr = magic(9)
arr = 9×9
47 58 69 80 1 12 23 34 45 57 68 79 9 11 22 33 44 46 67 78 8 10 21 32 43 54 56 77 7 18 20 31 42 53 55 66 6 17 19 30 41 52 63 65 76 16 27 29 40 51 62 64 75 5 26 28 39 50 61 72 74 4 15 36 38 49 60 71 73 3 14 25 37 48 59 70 81 2 13 24 35
%Random values for example
x = randi(9)
x = 5
%columns for which values to compare and change
idx = randperm(9,x)
idx = 1×5
8 4 3 7 5
%boundary conditions
val = randi([50 100],1,numel(idx))
val = 1×5
67 73 55 61 89
for k=1:x
arr(:,idx(k)) = max(arr(:,idx(k)),val(k));
end
arr
arr = 9×9
47 58 69 80 89 12 61 67 45 57 68 79 73 89 22 61 67 46 67 78 55 73 89 32 61 67 56 77 7 55 73 89 42 61 67 66 6 17 55 73 89 52 63 67 76 16 27 55 73 89 62 64 75 5 26 28 55 73 89 72 74 67 15 36 38 55 73 89 73 61 67 25 37 48 59 73 89 2 61 67 35
For the same data, using Voss's vectorized approach -
arr = magic(9);
x = 5;
idx = [8 4 3 7 5];
val = [67 73 55 61 89];
arr(:,idx) = max(arr(:,idx),repmat(val,size(arr,1),1))
arr = 9×9
47 58 69 80 89 12 61 67 45 57 68 79 73 89 22 61 67 46 67 78 55 73 89 32 61 67 56 77 7 55 73 89 42 61 67 66 6 17 55 73 89 52 63 67 76 16 27 55 73 89 62 64 75 5 26 28 55 73 89 72 74 67 15 36 38 55 73 89 73 61 67 25 37 48 59 73 89 2 61 67 35
Jose Pratdesaba
Jose Pratdesaba 2023 年 9 月 27 日
Thank you very much!!
Dyuman Joshi
Dyuman Joshi 2023 年 9 月 27 日
You are welcome!

サインインしてコメントする。

カテゴリ

ヘルプ センター および File ExchangeCreating and Concatenating Matrices についてさらに検索

製品

リリース

R2022b

質問済み:

2023 年 9 月 27 日

コメント済み:

2023 年 9 月 27 日

Community Treasure Hunt

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

Start Hunting!

Translated by