Find a vector in a structure
2 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
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?
0 comentarios
Respuesta aceptada
Andrei Bobrov
el 17 de En. de 2012
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,:)
0 comentarios
Más respuestas (1)
David Young
el 16 de En. de 2012
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 comentarios
David Young
el 17 de En. de 2012
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.
Ver también
Categorías
Más información sobre Numeric Types en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!