Array of struct manipulating

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 commentaires

Jan
Jan le 20 Nov 2011
What are the types and dimensions of the fields a, b, c? What is the size of x?
Jan
Jan le 21 Nov 2011
If you search for help, answering my question would be a good idea. Currently the two operations are not clear enough: You cannot apply a calculation on the lefthand side in Matlab.
Majed
Majed le 21 Nov 2011
a is string
b and c are integers
and x is too huge
Titus Edelhofer
Titus Edelhofer le 21 Nov 2011
If a is a string, what is x(:).a + 10?
Majed
Majed le 21 Nov 2011
a is a struct member of type integer (I was mistaken )
and x(:) is the whole array of struct
Jan
Jan le 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.

Connectez-vous pour commenter.

Réponses (4)

David Young
David Young le 20 Nov 2011

0 votes

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 commentaire

Majed
Majed le 21 Nov 2011
I mentioned in the question that I have array of struct,
I have no solution for that !!

Connectez-vous pour commenter.

Jan
Jan le 21 Nov 2011

0 votes

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 commentaire

Majed
Majed le 21 Nov 2011
That did not work for my case,
I need to assign this to an existing element in the struct

Connectez-vous pour commenter.

Fangjun Jiang
Fangjun Jiang le 21 Nov 2011

0 votes

%%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 le 22 Nov 2011

0 votes

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 commentaire

Fangjun Jiang
Fangjun Jiang le 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.

Connectez-vous pour commenter.

Catégories

Question posée :

le 20 Nov 2011

Community Treasure Hunt

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

Start Hunting!

Translated by