Array of struct manipulating

4 Ansichten (letzte 30 Tage)
Majed
Majed am 20 Nov. 2011
I have array of struct
x.a
x.b
x.c
I want to do the following two operations
  1. x(:).a = x(:).a +10
  2. x(:).c = x(:).a / x(:).b
for all element without using for loop
  6 Kommentare
Majed
Majed am 21 Nov. 2011
a is a struct member of type integer (I was mistaken )
and x(:) is the whole array of struct
Jan
Jan am 22 Nov. 2011
@Majed: Why do you want to avoid the FOR loop?! It would be much nicer and most likely more efficient than creating intermediate vectors, split them to a cell and distribute it over different fields again. The elements are independent from eachotehr, the calculations are independent, so a FOR loop is the straightest method.

Melden Sie sich an, um zu kommentieren.

Antworten (4)

David Young
David Young am 20 Nov. 2011
It depends whether your data is a structure of arrays or an array of structures. See this video for the difference (and google matlab structures and arrays for more information).
If you choose to use a structure of arrays, you can just do
x.a = x.a + 10;
etc. If you use an array of structures, it's more fiddly.
  1 Kommentar
Majed
Majed am 21 Nov. 2011
I mentioned in the question that I have array of struct,
I have no solution for that !!

Melden Sie sich an, um zu kommentieren.


Jan
Jan am 21 Nov. 2011
Unfortunately you did not answer my question about the size and type of the fields and the dimensions of the struct. But let me guess at least - perhaps this helps:
x(1).a = 2;
x(2).a = 3;
x(1).b = 17;
x(2).b = 23;
result = [x.a] ./ [x.b]
  1 Kommentar
Majed
Majed am 21 Nov. 2011
That did not work for my case,
I need to assign this to an existing element in the struct

Melden Sie sich an, um zu kommentieren.


Fangjun Jiang
Fangjun Jiang am 21 Nov. 2011
%%construct a structure array
M=3;
s=struct('a',repmat({1},M,1),'b',repmat({2},M,1),'c',repmat({3},M,1));
%process
N=length(s);
temp=[s.a]+10;
temp=mat2cell(temp,1, ones(N,1));
[s.a]=temp{:};
temp=[s.a]./[s.b];
temp=mat2cell(temp,1, ones(N,1));
[s.c]=temp{:};

Jan
Jan am 22 Nov. 2011
Fangjun's approach is nice and works without loops. But creating the temporary arrays wastes a lot of time. A simple FOR loop would be more efficient:
M = 3;
s0 = struct('a', repmat({1},M,1), 'b',repmat({2},M,1), 'c',repmat({3},M,1));
tic
for k = 1:1000
s = s0;
N = length(s);
temp = [s.a]+10;
temp = mat2cell(temp,1, ones(N,1));
[s.a] = temp{:};
temp = [s.a]./[s.b];
temp = mat2cell(temp,1, ones(N,1));
[s.c]= temp{:};
end
toc
% Elapsed time is 0.237474 seconds.
tic
for k = 1:1000
s = s0;
for i = 1:numel(s)
s(i).a = s(i).a + 10;
s(i).c = s(i).a / s(i).b;
end
end
toc
% Elapsed time is 0.024864 seconds.
For this tiny data set the FOR loop is 10 times faster. For larger data with N=300, I get at least a speedup factor of 3.
  1 Kommentar
Fangjun Jiang
Fangjun Jiang am 22 Nov. 2011
Good point, Jan. However, when I changed M to be 300. The result is opposite.
Elapsed time is 3.575805 seconds.
Elapsed time is 5.151734 seconds.
Elapsed time is 3.550913 seconds.
Elapsed time is 5.179092 seconds.
Elapsed time is 3.552488 seconds.
Elapsed time is 5.137140 seconds.

Melden Sie sich an, um zu kommentieren.

Kategorien

Mehr zu Structures finden Sie in Help Center und File Exchange

Community Treasure Hunt

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

Start Hunting!

Translated by