필터 지우기
필터 지우기

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

조회 수: 3 (최근 30일)
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 CenterFile Exchange에서 Structures에 대해 자세히 알아보기

제품


릴리스

R2024a

Community Treasure Hunt

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

Start Hunting!

Translated by