pre allocating / extracting data from vector based on condition

לק"י
Hello!
I want to find a way other then if statement to go through vector and check if some conditions apply to each cell and to return 1 or 0 in accordance to the result of the conditions.
for example, I have a vector called vorroi, which contains the candidate points to be ploted in a plot.
the current process that decides if the current cell of vorroi will be plottted (passed the statements) is this for statement:
if ismember(1, c{j})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{j},1),v(c{j},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{j},1),v(c{j},2)))==0) %ismember(0, inpolygon(v(c{j},1),v(c{j},2), fhpos(:,1), fhpos(:,2)))~=1
which asks if the candidate point voronoi *(some background about voronoi in the end) area is inf (ismember(1, c{j})), and if it crosses one of two lines I draw (isempty statements).
It would be very beneficial to compute the result of the if statement without the need to fo through that loop. is it possible? and how?
I tried several attempts, such as:
plgnsinmrkd=[vorroi(ismember(1, c{vorroi(:,1)})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0))];
plgnsinmrkd=vorroi(ismember(1, c{vorroi(:,1)})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0));
plgnsinmrkd=(vorroi(ismember(1, c{vorroi(:,1)})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0)));
and it didn't do it, the output is:
> plgnsinmrkd=(vorroi(ismember(1, c{vorroi(:,1)})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0)));
>> plgnsinmrkd
plgnsinmrkd =
[]
I thiought it would be something like other line I wrote:
datintmrkd=(cell2mat(dat(:,3))>minint(m) & maxint(m)>cell2mat(dat(:,3))); %create a vector that assings 1 to coresponding cell within data only if in minint and maxint range.
but somewhy it doesn't work.
Sorry for all the questions lately, and thank you all!
Amit.
*A little background - Voronoin gives back 2 vectors, v and c that are the (x and y points of the vertices - v vector) and (index of vertices which relate to each polygon created in the voronoi - c vector). more info here: N-D Voronoi diagram - MATLAB voronoin (mathworks.com).

4 件のコメント

Jan
Jan 2023 年 2 月 9 日
"is this for statement:" - There is no for statement in the posted code.
"which asks if the candidate point voronoi *(some background about voronoi in the end) area is inf (ismember(1, c{j})), and if it crosses one of two lines I draw (isempty statements)." - The ismember command is commented, such that the description does not match the code.
"It would be very beneficial to compute the result of the if statement without the need to fo through that loop." - Without seeing the relevant part of the code, especially the loop, it is hard to estimate, if another code is faster.
Due to the need of vertical scrolling lines as:
plgnsinmrkd=[vorroi(ismember(1, c{vorroi(:,1)})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{vorroi(:,1)},1),v(c{vorroi(:,1)},2)))==0))];
are extremely hard to read and to understand. Simplifying the names of the variables would be very useful also:
A = vorroi(:, 1);
B = crsvrtcl;
C = crshrzntl;
y = A(ismember(1, c{A}) == 0 && ...
(~isempty(polyxpoly(B(:,1), B(:,2), v(B{A}, 1), v(c{A},2))) || ...
~isempty(polyxpoly(C(:,1), C(:,2), v(c{A}, 1), v(c{A},2)))));
The next simplification is:
ismember(1, c{A(:,1)}) == 0 % ==>
all(c{A(:,1)} ~= 1)
This does not solve your problem, but I can read it successfully at least.
Amit Ifrach
Amit Ifrach 2023 年 2 月 9 日
編集済み: Amit Ifrach 2023 年 2 月 9 日
לק"י
Hi Jan,
First of all, as allways, thanks for the help!
I thought the the 'if' is a statement, at least what I could understand from quick googling.
I tried to as clear as I could, and i'm sorry if it is not clear enough, I'll try again.
generally - the code needs to analyze voronoi plot.
(1) The code saves 3 vectors (x, y and intensity) from a csv, and filters out points based on the intensity threshold I specify (this parts works well and isn't shown here). the x and y vectors are calles xroi and yroi because I used ROI to get them and I won't write about it here.
(2) Then a voronoin command is apllied, which finds for every point the maximal area arround it. the output of this command gives 2 vectors, v and c. v indicate the vertices x and y positions, and c is cell array that hold the indexes of all vertices of an area. v(c{i}) will give the 'i'th area's vertices (which from I can plot and claculate area etc).
(3) I prepare to filter out points i'm interested in with the loop. I creat a cross based on 2 lines of a rectangle drawn by getrect:
%drwrct - draw rectangle
%crsvrtcl - cross vertical
%crshrzntl - cross horizontal
if m==1 && reanalyzeolddata==0 && drwline==1
hold on
drwrct=getrect;
crsvrtcl=[(drwrct(1)+drwrct(3)/2) drwrct(2); (drwrct(1)+drwrct(3)/2) drwrct(2)+drwrct(4)];
crshrzntl=[drwrct(1) (drwrct(2)+drwrct(4)/2); (drwrct(1)+drwrct(3)) (drwrct(2)+drwrct(4)/2)];
plot(crsvrtcl(:,1),crsvrtcl(:,2),'LineWidth',2, 'Color' , 'red');
plot(crshrzntl(:,1), crshrzntl(:,2),'LineWidth',2, 'Color' , 'red');
end
<- dash lined rectangle
cross based on rectangle->
(4) To prepare for a loop that will scan all the points, I make a vector called vorroi that i the length of all the points of xroi. I know it is an 'excess' of code, but, the reason I call it vorroi is it should stand for voronoi ROI, and is called like this because I have another 'brach' (or option) of code that allows me to filter points by drawfreehand tool. like draw with mouse polygon and ask which points are in it with inpolygon command. plesae ignore the saving of graphics.
%save plotted image to subfolder of specified values and
%inputs.
hold off
myAxes=findobj(sp1,'Type','Axes');
fnsp1=append(erase(files{i}, '.csv'),' sp1.png');
sp1path=(append(pwd ,append('\',append(erase(files{i}, '.csv'),append('\',append(append(append(append(append(append(erase(files{i}, '.csv'),' sp1 '), 'intensity range ', string(minint(m)), ' i '), string(maxint(m)), '.png')))))))));
exportgraphics(myAxes,[sp1path]);
if drwline==0 % this line IS NOT USED!
vorroi=inpolygon(xroi,yroi,fhpos(:,1),fhpos(:,2));
elseif drwline==1
vorroi=[1:length(xroi)];
end
ind=[]; % indicator vector.
polx=[]; %create empty vector to store x values.
poly=[]; %create empty vector to store y values.
plgnsin=[]; %empty vector to mark/store polygons that went through the conditions of the next if statement.
k=1; %define vector (k) to iterate
After that, the code creats some other vectors to contain data for the loop (ind, polx, poly, plgnsin,k) .
(5) Then I want to apply a condition, that the areas crossed by any one of the two horizontal or vertical lines will be 'chosen' by the conditions I mention in the for loop. for this I use the for and if like this:
for j=2:length(vorroi)
if ismember(1, c{j})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{j},1),v(c{j},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{j},1),v(c{j},2)))==0);
plgnsin=[plgnsin ; j]; % plgnsin = polygons in
% get the polygon vertice's x,y coordinates
polx=v(c{j},1); %polygon x points
poly=v(c{j},2); %polygon y points
pgon=polyshape(polx,poly);
if m==1 && polyarea(polx,poly)>0;
intsum1(k,1)=introi(j);
area1(k,1)=polyarea(polx,poly);
elseif m==2 && polyarea(polx,poly)>0;
intsum2(k,1)=introi(j);
area2(k,2)=polyarea(polx,poly);
elseif m==3 && polyarea(polx,poly)>0;
intsum3(k,1)=introi(j);
area3(k,3)=polyarea(polx,poly);
else
display (ERROR)
end
k=k+1;
else
% add areas to specific areas vector by the
% intensity range
if m==1
intsum1(k,1)=0;
area1(k,1)=0;
elseif m==2
intsum2(k,1)=0;
area2(k,2)=0;
elseif m==3
intsum3(k,1)=0;
area3(k,3)=0;
else
display (ERROR)
end
k=k+1;
end
and for every j that enters the 'if' condition, I want to save it to be able to get back to it later to plot and color. further more, I want to save the area of the polygon that the 'j'th point have. I have 3 conditions where to save the area, which is indicated by m (m can store 1,2 or 3 from previous area of the code), you can ignore them if you want.
an else condition is written to address what will happend if the point does not answer the conditions. irrelevant for you I think.
(6) When this is finished, I want to go back and do some plotting and calculations to the points that did make it throgh the conditions and their indexes are stored in the plgnsin vector. in a for loop I want to get:
1. each polygon's area
2. plot each polygon - and though it is not written in the code, I should also write lines of plot(pgon) within this loop to plot them.
3. color each polygon by heat-map normalized to the maximal area in the vector.
for(ii=1:length(plgnsin(:,1)))
plgnsin(ii,2)=[polyarea(v(c{plgnsin(ii,1)},1),v(c{plgnsin(ii,1)},2))];
end
plgnsin(:,3)=plgnsin(:,2)/max(plgnsin(:,2));
max(plgnsin(:,2))
min(plgnsin(:,2))
% figure (3)
sp2=subplot(2,2,2);
plot(pgon); %plot polygon of x and y coordinates suplied by polyx and polyy
hold on
plot(xroi(j),yroi(j),'*r'); %plot red '*' of x and y coordinates suplied by xroi and yroi
xlabel('nm');
ylabel('nm');
title('Chosen voronoi polygons');
basically, I f I could sum up, I just want to do this smarter if possible. that means, that if I could 'mark' from the first place each index on the vorroi or xroi vector from the start baed on the conditions mentioned above in (5) it would save TONS of time. some waht like vorroi(find based on conditions) if a thing like this exist. then every thing else will be much simpler for me. just want to do it smart.
Hope it is not too long and clear enough :(.
Thanks alot, again and a hundred time again,
Amit.
The whole code:
%* NOTE! drwline=1 in this code!
if m==1 && reanalyzeolddata==0 && drwline==1
hold on
drwrct=getrect;
crsvrtcl=[(drwrct(1)+drwrct(3)/2) drwrct(2); (drwrct(1)+drwrct(3)/2) drwrct(2)+drwrct(4)];
crshrzntl=[drwrct(1) (drwrct(2)+drwrct(4)/2); (drwrct(1)+drwrct(3)) (drwrct(2)+drwrct(4)/2)];
plot(crsvrtcl(:,1),crsvrtcl(:,2),'LineWidth',2, 'Color' , 'red');
plot(crshrzntl(:,1), crshrzntl(:,2),'LineWidth',2, 'Color' , 'red');
end
%save plotted image to subfolder of specified values and
%inputs.
hold off
myAxes=findobj(sp1,'Type','Axes');
fnsp1=append(erase(files{i}, '.csv'),' sp1.png');
sp1path=(append(pwd ,append('\',append(erase(files{i}, '.csv'),append('\',append(append(append(append(append(append(erase(files{i}, '.csv'),' sp1 '), 'intensity range ', string(minint(m)), ' i '), string(maxint(m)), '.png')))))))));
exportgraphics(myAxes,[sp1path]);
if drwline==0 % this line IS NOT USED!
vorroi=inpolygon(xroi,yroi,fhpos(:,1),fhpos(:,2));
elseif drwline==1
vorroi=[1:length(xroi)];
end
ind=[]; % indicator vector.
polx=[]; %create empty vector to store x values.
poly=[]; %create empty vector to store y values.
plgnsin=[]; %empty vector to mark/store polygons that went through the conditions of the next if statement.
k=1; %define vector (k) to iterate
for j=2:length(vorroi)
if ismember(1, c{j})==0 && (isempty(polyxpoly(crsvrtcl(:,1),crsvrtcl(:,2),v(c{j},1),v(c{j},2)))==0 || isempty(polyxpoly(crshrzntl(:,1),crshrzntl(:,2),v(c{j},1),v(c{j},2)))==0);
plgnsin=[plgnsin ; j];
% get the polygon vertice's x,y coordinates
polx=v(c{j},1);
poly=v(c{j},2);
pgon=polyshape(polx,poly);
if m==1 && polyarea(polx,poly)>0;
intsum1(k,1)=introi(j);
area1(k,1)=polyarea(polx,poly);
elseif m==2 && polyarea(polx,poly)>0;
intsum2(k,1)=introi(j);
area2(k,2)=polyarea(polx,poly);
elseif m==3 && polyarea(polx,poly)>0;
intsum3(k,1)=introi(j);
area3(k,3)=polyarea(polx,poly);
else
display (ERROR)
end
k=k+1;
else
% add areas to specific areas vector by the
% intensity range
if m==1
intsum1(k,1)=0;
area1(k,1)=0;
elseif m==2
intsum2(k,1)=0;
area2(k,2)=0;
elseif m==3
intsum3(k,1)=0;
area3(k,3)=0;
else
display (ERROR)
end
k=k+1;
end
end
end
for(ii=1:length(plgnsin(:,1)))
plgnsin(ii,2)=[polyarea(v(c{plgnsin(ii,1)},1),v(c{plgnsin(ii,1)},2))];
end
plgnsin(:,3)=plgnsin(:,2)/max(plgnsin(:,2));
max(plgnsin(:,2))
min(plgnsin(:,2))
% figure (3)
sp2=subplot(2,2,2);
plot(pgon); %plot polygon of x and y coordinates suplied by polyx and polyy
hold on
plot(xroi(j),yroi(j),'*r'); %plot red '*' of x and y coordinates suplied by xroi and yroi
xlabel('nm');
ylabel('nm');
title('Chosen voronoi polygons');
Jan
Jan 2023 年 2 月 10 日
Sorry, this is far too extensive for a question in the forum. Split the problem into parts. If a question can be understood in less then 2 minutes, it has much higher chances to get an answer. Maybe this helps: https://www.mathworks.com/matlabcentral/answers/6200-tutorial-how-to-ask-a-question-on-answers-and-get-a-fast-answer .
Amit Ifrach
Amit Ifrach 2023 年 2 月 11 日
לק"י
Hi Jan, thanks for the tip. I deconstructed it to some basic questions as you said. hope it would be easier to understand then.
Have a great week and thanks for everything!
Amit.

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

回答 (0 件)

カテゴリ

ヘルプ センター および File ExchangeVoronoi Diagram についてさらに検索

質問済み:

2023 年 2 月 9 日

コメント済み:

2023 年 2 月 11 日

Community Treasure Hunt

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

Start Hunting!

Translated by