Reputation: 25
I have the following array of structures called test, where each field is a [1x3] structure array containing a matrix. I would like to create a new field, levelsq, which squares element-by-element each matrix. I can do this with a loop:
[test(1:3).level] = deal([1,1],[2,2],[3,3])
for i = 1:3
test(i).levelsq = test(i).level.^2
end
test.level
ans =
1 1
ans =
2 2
ans =
3 3
test.levelsq
ans =
1 1
ans =
4 4
ans =
9 9
I have got some of the way by separating and concatenating the elements, but have not yet been able to add the new field:
temp = num2cell([test.level].^2)
test.levelsq = temp{:}
??? Illegal right hand side in assignment. Too many elements.
I then tried reshaping the temp variable, but it is still not in the correct form
temp2= reshape(temp,2,3)'
temp2 =
[1] [1]
[4] [4]
[9] [9]
Is there an easier way to do this without looping or having to separate the contents? Thanks.
Upvotes: 1
Views: 979
Reputation: 14118
test = arrayfun(@(x) setfield(x, 'levelsq', x.level .^ 2), test);
BTW, if you set column vectors, you can easy access the array's values:
>> [test.level]
ans =
1 2 3
1 2 3
>> [test.levelsq]
ans =
1 4 9
1 4 9
Upvotes: 1
Reputation: 173
You might want to consider what data types you need for your application. You are currently using numeric arrays, cell arrays, and structs (doubly nested structs at that!).
The "Matlab" approach would be to do all this using numeric arrays, aka matrices. They are highly optimized and very conducive to mathematical operations.
You could do:
level = [ 1 1; 2 2; 3 3;];
levelsq = level.^2;
If you wanted a single data structure to hold both level
and levelsq
, you could concatenate the two into a three-dimensional matrix:
test = cat(3, level, levelsq);
And you could access level by calling test(:,:,1)
, and acces levelsq by calling test(:,:,2)
.
If, on the other hand, you need to keep the data structure you are using, you can't beat @Serg.
Upvotes: 0