Find a vector in a structure

조회 수: 3 (최근 30일)
Alessandro Masullo
Alessandro Masullo 2012년 1월 16일
Hello! I've this structure:
>> vortex(:).points
ans =
1 2 3
4 5 6
7 8 9
ans =
9 9 9
8 8 8
I want to find the [8 8 8] vector in any of the vortex array and the position in both the vortex and the points array. Something like:
find([8 8 8], vortex) --> vortex(2).points(2, :)
find([7 8 9], vortex) --> vortex(1).points(3, :)
How should I do?

채택된 답변

Andrei Bobrov
Andrei Bobrov 2012년 1월 17일
variant
pall = cat(1,vortex(:).points);
a = find(ismember(pall,[7 8 9],'rows'));
b = cumsum([0 arrayfun(@(x) size(x.points,1), vortex)]);
[i1 i1] = histc(a,b+100*eps);
d = a - b;
j1 = d(find(d>0,1,'last'));
out = vortex(i1).points(j1,:)

추가 답변 (1개)

David Young
David Young 2012년 1월 16일
One method:
% Test data
vortex(1).points = [1 2 3; 4 5 6; 7 8 9];
vortex(2).points = [9 9 9; 8 8 8];
searchv = [9 9 9];
% Analyse structure to find how many rows are in each points matrix.
% No need to repeat this line if searchv changes, only if vortex does.
rowsums = cumsum([0 arrayfun(@(x) size(x.points, 1), vortex)]);
% Assemble all the points arrays into one big array, and look for the first
% row that is the same as the search vector.
row = find(~any(bsxfun(@minus, vertcat(vortex(:).points), searchv), 2), 1);
% check that a matching row has been found, to avoid an obscure error later
if isempty(row)
error('Vector not found');
end
% Convert the overall row number into the structure and array indices,
% so that vortex(struct_index).points(points_index,:) is equal
% to searchv.
struct_index = find(row <= rowsums, 1) - 1
points_index = row - rowsums(struct_index)
EDIT Revised code below, inspired by andrei bobrov's answer, making use of ismember and separating out building the large matrix.
% Analyse structure to find how many rows are in each points matrix, and
% concatenate the points matrices into one big matrix.
% No need to repeat these two lines if searchv changes, only if vortex does.
rowsums = cumsum([0 arrayfun(@(x) size(x.points, 1), vortex)]);
pall = vertcat(vortex(:).points);
% Look for the last row that is the same as the search vector.
[~, row] = ismember(searchv, pall, 'rows');
% check that a matching row has been found, to avoid an obscure error later
if ~row
error('Vector not found');
end
% Convert the overall row number into the structure and array indices,
% so that vortex(struct_index).points(points_index,:) is equal
% to searchv.
struct_index = find(row <= rowsums, 1) - 1
points_index = row - rowsums(struct_index)
  댓글 수: 2
Alessandro Masullo
Alessandro Masullo 2012년 1월 17일
It works, but it's a bit slow...
I have to find a vector 180000*500 times, it would take a very long time...
Is there a more performant solution?
Thanks.
David Young
David Young 2012년 1월 17일
See if Andrei Bobrov's variant is faster. In particular I think his use of ismember is better than my method of subtracting and finding a line of zeros - it's certainly more elegant.
In addition, Andrei builds the big concatenated matrix ('pall') separately from searching it, and this is very sensible, because you should not rebuild it before searching for another vector.
It might be worth having a look at the structure of your whole program, to see if there is some way of avoiding building the structures in the first place, or of indexing them when they are being built.

댓글을 달려면 로그인하십시오.

카테고리

Help CenterFile Exchange에서 Numeric Types에 대해 자세히 알아보기

Community Treasure Hunt

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

Start Hunting!

Translated by