Manipulating Values in an Array with Logical Indexing

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

 Risposta accettata

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 Commenti

Thanks for the answer! This does indeed work, but it seems that I do not fully understand how the logical indexing is working. I was thinking that by using logical indexing the programm is just ignoring the values where the condition is not fulfilled. By testing your code ít does not seem that way.
The array C is initalized as a 1x20something Array depending on B. The output of C(B) is, e.g., a 1x10 Array. What does confuse me is the fact that the following code does work as well:
A = rand(5);
B = A < 0.5;
C=rand(5);
D=rand(5);
A(B) = C(B).^2+D(B).^2;
In this case the output of C(B) and D(B) is, e.g., a 10x1 Array, it is transposed to the Array in your code.
I guess this does mean that this type of Code does work, even though the right hand side is just composed of vectors, but I do have to watch out which dimensions the vectors have?
Suppose I do know that the first column of B, my logical array, is zero. That means that i only want to change the values of A(:,2:5). If i want to make the following code work, i guess i do have to transpose the 5x4 Array E into a vector with the same length as C(B) and D(B), am I right?
A(B) = C(B).^2+D(B).^2+E;
Thanks for your help!
My pleasure!
Assigning elements in a vector using a logical array follows the linear indexing convention. (This is thoroughly discussed in the documentations ection on Matrix Indexing, so I will not go into detail here.)
If you want to efficiently convert subscripts to linear indices (this is frequently necessary if the subscripts are not continguous), use the sub2ind function.
I am not certain exactly what you are doing, however the indexing scheme in my Answer works correctly, and the logical index ‘B’ correctly governs the placement of the calculated elements.
For example, one random assignment produces:
A =
0.19812 0.052677 0.94274 0.66634 0.12801
0.48969 0.73786 0.41774 0.53913 0.99908
0.33949 0.26912 0.98305 0.69811 0.17112
0.95163 0.42284 0.30145 0.66653 0.032601
0.92033 0.54787 0.7011 0.17813 0.5612
B =
5×5 logical array
1 1 0 0 1
1 0 1 0 0
1 1 0 0 1
0 1 1 0 1
0 0 0 1 0
A =
10048 1898 0.94274 0.66634 2173
4633 0.73786 881 0.53913 0.99908
3842 3637 0.98305 0.69811 7085
0.95163 12968 8066 0.66653 11453
0.92033 0.54787 0.7011 7940 0.5612
This appears to create and replace the correct elements, using the random values my code uses to do the simulation.
Your code does indeed work perfectly, I am sorry, if i wasnt clear on that. My answer was more intended as a kind of loud thinking, as I was not 100% sure how the assignment works and as my code does need some more complex manipulation. I did not know that the assignment of elements using a logical array follows the linear index convention, this does clear up some of my confusion.
With your help and insight I am confident I can solve the remaining problems by myself. The sub2ind function should come in handy.
Thanks again!
As always, my pleasure!
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.
Felix Tessarek —
Thank you for posting the amplification and clarification!

Accedi per commentare.

Più risposte (1)

Ameer Hamza
Ameer Hamza il 4 Dic 2020
Modificato: Ameer Hamza il 4 Dic 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 Commento

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.

Accedi per commentare.

Categorie

Community Treasure Hunt

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

Start Hunting!

Translated by