Does struct manipulation work in place when using arrayfun on an array of structs?

2 ビュー (過去 30 日間)
Charles Refvem
Charles Refvem 2024 年 4 月 19 日
編集済み: Matt J 2024 年 4 月 20 日
I would like to better understand how arrays of structured data are handled when they are manipulated using arrayfun. I've created a minimal example below to show the kind of situation I'm looking at. In this example, I'm applying a function to each struct in an array of structs using arrayfun to manipulate the structures by adding an additional field. Does this code work "in place" on the structs in the array, only allocating new memory for the new field? If this will copy the structures (or the entire array) as the fields are added, then it seems better to use a loop than arrayfun. I'd appreciate any insight into how the memory is managed during this kind of operation.
s = struct("x", {1, 2, 3});
s = arrayfun(@update, s);
function s = update(s)
s.y = s.x^2;
end

採用された回答

Matt J
Matt J 2024 年 4 月 19 日
編集済み: Matt J 2024 年 4 月 19 日
It does indeed appear that with arrayfun (unlike loops), pre-existing field contents get deep-copied to a new memory address (as indicated by pr in the results below):
s= struct("x", {1:5,2:6,3:7});
u=s; for i=1:numel(s), u(i).y=u(i).x.^2; end %loop copy
v=arrayfun(@update, s); %arrayfun copy
format debug
s(3).x
ans =
Structure address = 1ab51ab5120
m = 1
n = 5
pr = 1ab6b9a1d80
3 4 5 6 7
u(3).x
ans =
Structure address = 1ab51ab5120
m = 1
n = 5
pr = 1ab6b9a1d80
3 4 5 6 7
v(3).x
Structure address = 1ab4d81f7c0
m = 1
n = 5
pr = 1ab6d5f5500
3 4 5 6 7
function s = update(s)
s.y = s.x.^2;
end
  3 件のコメント
Steven Lord
Steven Lord 2024 年 4 月 19 日
Your function may be simpler and faster than arrayfun, but it doesn't do everything arrayfun does.
x = [1:5 -1];
y = arrayfun(@realsqrt, x, ErrorHandler = @(varargin) NaN)
y = 1x6
1.0000 1.4142 1.7321 2.0000 2.2361 NaN
<mw-icon class=""></mw-icon>
<mw-icon class=""></mw-icon>
z = arrayfun(@ones, x, UniformOutput = false)
z = 1x6 cell array
{[1]} {2x2 double} {3x3 double} {4x4 double} {5x5 double} {0x0 double}
y2 = myArrayfun(@realsqrt, x)
Realsqrt produced complex result.

Error in solution>myArrayfun (line 9)
C(i)=fun(A(i));
It also lacks the capability to handle non-uniform outputs from the function (the 'UniformOutputs' name-value argument, see the creation of z above.) There are some circumstances where you may not need the full level of flexibility of arrayfun, and in those cases you can beat the performance of arrayfun.
function C=myArrayfun(fun,A)
C=repmat( fun(A(1)), size(A) );
for i=2:numel(C)
C(i)=fun(A(i));
end
end
Matt J
Matt J 2024 年 4 月 19 日
編集済み: Matt J 2024 年 4 月 20 日
but it doesn't do everything arrayfun does.
Yes, for the purposes of this example that's true, but I can't see why any of those additional features explain why deep copying of all the input array data is done by the native arrayfun. I feel like I could add those features to my version without the deep copying, and still see a performance benefit.

サインインしてコメントする。

その他の回答 (0 件)

カテゴリ

Help Center および File ExchangeStructures についてさらに検索

製品


リリース

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by