Anonymous Function : asymmetric read/write behaviour
4 visualizaciones (últimos 30 días)
Mostrar comentarios más antiguos
Benoit Beaulieu
el 8 de Nov. de 2023
Editada: Benoit Beaulieu
el 11 de Nov. de 2023
I'm trying to use function handles to create an equivalent to a "with" statement in VBA or a alias in Python but I find myself facing a behaviour I don't understand. maybe some of you could help me understand why I get an error.
Boiled down to the simplest, here's what I get:
a=@(x)x{1};
y={10};
a(y)
try a(y)=100
catch ME
ME
end
The reading part works well but the next line results in an error. Why is there an asymmetry while evaluating the parentasis?
EDIT :
The most efficient to create a VBA:with or Python:alias equivalent in Matlab I found is to do an actual copy of a structure subpart, make modifications and reassign the edited branch copy to its original structure as:
S=struct();
S.Branch0 = "Just Some Data";
S.Branch1=struct();
for i=1:10
% Setting up preexisting values in the structure
for j=1:10
S.Branch1(i).NotCopiedProperty{j} = i;
end
S.Branch1(i).CopiedProperty = 10:-1:1;
% Create a phantom copy of the whole branch
with = S.Branch1;
% Add properties to the phantom branch
with(i).NewProperty1='Some Text';
with(i).NewProperty2={'A1','A2'};
% Create a copy of the original data and the edit it
with(i).CopiedProperty(i) = 0;
% Overwrite the original subBranch with the phantom branch
S.Branch1=with;
end
disp(S)
disp(S.Branch1)
Limitations : If new fields are to be added in a loop, the "with" structure must capture all instances at looping level.
% DOES NOT WORK
with = S.Branch1(1); % Points to ELEMENT
with.NewProperty1='New Text';
S.Branch1(1)=with;
% DO INSTEAD :
with = S.Branch1; % Points to ARRAY
with(i).NewProperty1='New Text';
S.Branch1=with;
% STILL WORKS
with = S.Branch1(1);
with.ExistingProperty1='Replacement Text';
S.Branch1(1)=with;
2 comentarios
Steven Lord
el 8 de Nov. de 2023
What exactly are you hoping to do with that last line? If a(y) returned 10 on both sides, what would you expect this command to do in MATLAB?
10 = 100
Walter Roberson
el 8 de Nov. de 2023
They are trying to create an alias. So they would like a(y) to be an alias for y{1} including for assignment purposes. They would like a(y)=100 to act the same as y{1} = 100
Respuesta aceptada
Walter Roberson
el 8 de Nov. de 2023
a(1) = @(x)x{1}
a(1) = @(x)x{1}.^2 + 3
a
When an anonymous function appears on the left of an = then it is a request to modify the anonymous function. If the anonymous function already exists then the request will fail unless the subscript is one of 1 or true or false or []
If you want to be able to use a syntax like a(y)=100 to mean y{1}=100 then you would need to define a class to do the operations, and y would have to be a handle class
There is no simple "syntactic sugar" in MATLAB that can emulate with
6 comentarios
Steven Lord
el 10 de Nov. de 2023
If you only extract the Parent property once (since you're not modifying it in your second loop) the times tell a different story:
%%Creating a structure
s=struct();
s.Parent.Property1=100000;
s.Parent.Property2=1:s.Parent.Property1;
%% Measuring ct with direct access (pointer like)
tic
for i=1:s.Parent.Property1
% this line writes zeros, to the array while requiring some calculation
% time
s.Parent.Property2(i)=abs(s.Parent.Property2(i))-i;
end
m.direct=seconds(toc);
%% Measuring ct creating a copy of the sub-structure for every calculation
% "with" statement inside the loop to evaluate the impact on a sample greater
% than 1
s.Parent.Property2=1:s.Parent.Property1;
tic
with=s.Parent;
for i=1:with.Property1
with.Property2(i)=abs(with.Property2(i))-i;
end
s.Parent=with;
m.with=seconds(toc);
disp(m);
More time also means a greater memory usage as there are 2 instances of the structure or object at any time in the loop using the "With" variation.
It's not that simple. MATLAB does something known as copy-on-write, in which it only makes copies of an array when it needs to.
tic
A = ones(1e4);
toc
tic
B = A;
toc
If the statement B = A; made a copy of A, it would have taken a similar amount of time as the line that created A. Instead, the copy's only made when B is modified.
tic
B(1) = 2;
toc
How does this work with struct arrays?
tic
S = struct('A', ones(1e4), 'C', 1);
toc
tic
T = S.C;
T(1) = 2;
toc
tic
S.C = T;
toc
The lines that create or manipulate T don't interact with S.A at all.
Más respuestas (0)
Ver también
Categorías
Más información sobre Environment and Settings en Help Center y File Exchange.
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!