Manipulating Values in an Array with Logical Indexing

20 ビュー (過去 30 日間)
Felix Tessarek
Felix Tessarek 2020 年 12 月 4 日
コメント済み: Star Strider 2020 年 12 月 5 日
I'm having problems with logical indexing of arrays
I do have an 10x10 array A. I want to change some of these values. Which values are changed is decided by a logical array 10x10 Array B.
Something like
A(B)=10
works perfectly. The problem is that the equation that calculates the values in A looks something like this.
A(B)=C^2+D^2
C and D are also 10x10 arrays. Ideally the Code would look like this:
A(B)=C(B)^2+D(B)^2
The values in C and D to be used in the equation have to be in the same row and column as in A. With two for-loops it would look like this:
for i=1
for u=1
if B(i,u)
A(i,u)=C(i,u)^2+D(i,u)^2
end
end
end
I'm not sure if the same can be achieved with logical indexing as C(B) just gives a vector as an output and of course then the dimensions do not agree. What i want to achieve is similar to:
A=C.^2+D.^2
but i only want to change some values of A, not all of them.
I tried reshaping the vectors as a matrix, but this only works if there arent any "holes" in the logical Matrix B.
Any help would be greatly appreciated

採用された回答

Star Strider
Star Strider 2020 年 12 月 4 日
The logical indexing approach should work as you described as wanting it to.
Try this example:
A = rand(5);
B = A < 0.5
C(B) = randi(99,1,nnz(B));
D(B) = randi(99,1,nnz(B));
A(B) = C(B).^2+D(B).^2
The correct values are replaced in the correct locations. The only significant change I made is to use element-wise exponentiation (.^ instead of ^).
  6 件のコメント
Felix Tessarek
Felix Tessarek 2020 年 12 月 5 日
Just in case someone else is having problems with this, here is some code to explain my former problem and the solution. If you are trying to calculate something like the following:
A = zeros(5,5);
A(:,2:5)=0.1;
A(:,1)=10;
B = A < 0.5;
As the above equation is only false for the first column, the logical Matrix B looks like this
B =
5×5 logical array
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
0 1 1 1 1
If you create an array C with the same size as A, the following code works fine:
C=rand(5);
A(B) = C(B).^2
Even though you know that due to the logical indexing only the second to last columns are changed (5x4), the following code does not work. D is an 5x4 array.
D=zeros(5,4);
D(:)=10;
A(B) = C(B).^2+D.^2;
C(B) and D do have the same amount of elements (z=20), but the dimensions do not agree.
If you want to make it work the code has to look like this:
A(B) = C(B).^2+D(:).^2;
I guess the colon does indicate that linear indexing should be used, which does agree with the logical array.
Star Strider
Star Strider 2020 年 12 月 5 日
Felix Tessarek —
Thank you for posting the amplification and clarification!

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

その他の回答 (1 件)

Ameer Hamza
Ameer Hamza 2020 年 12 月 4 日
編集済み: Ameer Hamza 2020 年 12 月 4 日
You can use B as a mask
A=(C.^2+D.^2).*B
Only places in which B is not equal to zero will have non-zero output.
  1 件のコメント
Felix Tessarek
Felix Tessarek 2020 年 12 月 4 日
Thanks for the answer! This does work in some of my cases, but the problem is that this approach does set the other values of A to 0, which is not desired as there are other values saved in A. I could try a workaround by saving the other values in A beforehand in another array with a logical array that is just the complement of B and adding the two arrays together, but I was hoping that there is a cleaner way.

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

カテゴリ

Help Center および File ExchangeCreating and Concatenating Matrices についてさらに検索

Community Treasure Hunt

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

Start Hunting!

Translated by