Manipulating Values in an Array with Logical Indexing

20 Ansichten (letzte 30 Tage)
Felix Tessarek
Felix Tessarek am 4 Dez. 2020
Kommentiert: Star Strider am 5 Dez. 2020
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

Akzeptierte Antwort

Star Strider
Star Strider am 4 Dez. 2020
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 Kommentare
Felix Tessarek
Felix Tessarek am 5 Dez. 2020
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 am 5 Dez. 2020
Felix Tessarek —
Thank you for posting the amplification and clarification!

Melden Sie sich an, um zu kommentieren.

Weitere Antworten (1)

Ameer Hamza
Ameer Hamza am 4 Dez. 2020
Bearbeitet: Ameer Hamza am 4 Dez. 2020
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 Kommentar
Felix Tessarek
Felix Tessarek am 4 Dez. 2020
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.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Creating and Concatenating Matrices finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by