complex logical indexing?

6 views (last 30 days)
Amit Ifrach
Amit Ifrach on 11 Feb 2023
Edited: Bruno Luong on 6 Mar 2023
לק"י
Hello!
lets assume I want to logically index a vector, or create a new vector that will hold the results of these logical indexing and it's complex as follow:
A - Vector that contain the index (1, 2, 3, 4, etc.) of areas (not the areas themeself, like 1.243, 2, 453.345 etc).
B - Cell array that contains numerical data in each cell (for example, {1, 25, 33, 15}) of indexes of another vector C.
C - Vector that contain 2 columns (x and y points) of a vertices, the first C(:,1) the X points of the vertices, C(:,2) the Y points of the vertices.
D - Vector that contain 2 columns (x and y points) of a vertical line, the first D(:,1) the X points of the vertical line, D(:,2) the Y points of the vertical line.
E - Vector that contain 2 columns (x and y points) of a horizontal line, the first E(:,1) the X points of the horizontal line, E(:,2) the Y points of the horizontal line.
I wish to find all the coresponding indexes in A that:
corresponding cell index in cell array B won't contain the number '1'. (so if B(1) = {1,2,25,33,56,123} it will give back a 0)
AND
areas correspond to the index of A and cross one of the two lines C and D (vertical or horizontal).
I know the conditios that do it are:
ismember(1, B{j})==0 && (isempty(polyxpoly(D(:,1),D(:,2),C(B{j},1),C(B{j},2)))==0 || isempty(polyxpoly(E(:,1),E(:,2),C(B{j},1),C(B{j},2)))==0)
I can do it with for loop such as:
for j=1
if ismember(1, B{j})==0 && (isempty(polyxpoly(D(:,1),D(:,2),C(B{j},1),C(B{j},2)))==0 || isempty(polyxpoly(E(:,1),E(:,2),C(B{j},1),C(B{j},2)))==0)
end
But I would be much faster and easier to somehow skip the loop.
Thanks (Jan?)!
Amit.
  3 Comments
Amit Ifrach
Amit Ifrach on 11 Feb 2023
לק"י
Hi Jan, thanks again!
I think I need to correct the B cell array, for it consists of many cells, so:
A = 1:33;
B = {1, 25, 33, 15}, {3, 34, 625, 7 878} , {85, 14, 2, 7, 100} , {4, 32, 6} etc.;
C = rand(33, 2);
D = rand(33, 2);
E = rand(33, 2);
about the lower case c:
""corresponding cell index in cell array B won't contain the number '1'. (so if c(1) = {1,2,25,33,56,123} it will give back a 0)" - What is c(1) = {1,2,25,33,56,123} ? A lower case "c" did not appear before."
I edited several times this post so I missed this. it should be B(1). I edited to be correct it in the main post up there.
What I actually do is to plot an X over a photo, proir to a plot of polygons of areas like so:
First, a red cross is plotted on the image that contain points -
After that the points are being 'tranlated' to polygons of areas of these points with voronoi command, like this -
Then I ask which of these plotted polygons are being 'touched' or 'crossed' by the red cross I plotted.
As you can see from the image, I can get the answer. I just want it to be much quicker. and generlize it to other matrices for future work.
Is that clear enough?
Just for being accurate enough, I will add an example vectors from my code in a .mat file, please be aware that Cexample in the file is C here, I just saved with another name to evade overide my C variable.
Thanks alot :)
Amit.
Bruno Luong
Bruno Luong on 6 Mar 2023
Edited: Bruno Luong on 6 Mar 2023
@Amit Ifrach "areas correspond to the index of A and cross one of the two lines C and D (vertical or horizontal)"
Using polyxpoly to check a Voronoi cell crossing vertical and horizontal is overkill, it is enough to check the x or y coordinates are in both sides of the line vertical or horizontal coordinates.

Sign in to comment.

Accepted Answer

Sarthak
Sarthak on 6 Mar 2023
Hi,
You can use logical indexing to achieve this without a for loop. Please refer to the following code for better understanding:
% Find indices where B does not contain 1
idx = cellfun(@(x) ~ismember(1,x), B);
% Find indices where areas correspond to the index of A and cross one of the two lines C and D (vertical or horizontal)
idx_cross = any(polyxpoly(D(:,1),D(:,2),C(A,1),C(A,2)),2) | any(polyxpoly(E(:,1),E(:,2),C(A,1),C(A,2)),2);
% Combine the two conditions using logical AND (&) operator to get the final index vector
idx_final = idx & idx_cross;
% Use the final index vector to get the corresponding indices in A
result = A(idx_final);

More Answers (0)

Community Treasure Hunt

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

Start Hunting!