Multiple names for a single variable.

Hi folks, I'm wondering if this is possible and how one would go about doing it.
I have a structure data. It has a field say, ActiveInd, so data.ActiveInd. I want to be able to have some kind of shorthanded name to keep the code easier to read and shorter, say AInd. Now I could (and have) code that says soemthing like:
AInd = data.ActiveInd
[do stuff to AInd]
data.ActiveInd = AInd.
Of course the doing stuff to AInd means I now have two variables, AInd and data.ActiveInd increasing memory usage. With tons of spare memory this isn't an issue but I'm starting to push up against memory caps. I'd love to able use both AInd and data.ActiveInd to point to and alter the same stuff in memory without using excess memory. Is this possible?

回答(1 个)

James Tursa
James Tursa 2021-1-27
There are no "variable pointers" in MATLAB, so no generic alias capability as you would probably want. Other options to consider:
  • Use data.Activelnd spelled out in all your code, instead of an assigned copy
  • Use functions to modify data.Activelnd with special syntax that allows "in-place" modification
  • Use classdef objects derived from handle that would essentially allow the alias behavior you want

13 个评论

An example for point 2:
function main % [EDITED] Main code inside a function
format debug
data.ActiveInd = rand(1, 20);
data.ActiveInd
% Structure address = ece6d9f0
% m = 1
% n = 100
% pr = ad92e920
data.ActiveInd = doStuff(data.ActiveInd)
data.ActiveInd
% Structure address = 7a66320
% m = 1
% n = 100
% pr = 13e0ef460
end
function AInd = doStuff(AInd)
AInd(13) = 27;
end
This means, that accessing a struct field does not work inplace. Is there another way?
@Jan: The above is not coded according to the "in-place" rules as I understand them. I think you would have to call doStuff from within a function to get the "in-place" behavior, so you might try that instead of calling it from the command line. But, even if you did this, now that I think about it I am not sure that this will work for structure fields because of the shared data copy created when data.ActiveInd is used for the argument. I.e., I'm not sure the shared data copy can be avoided in this case, which would disallow the "in-place" behavior.
Could someone else run this in a real .m file, not in LiveScript, and see if you see the same thing I see?
format debug
data.ActiveInd = rand(1, 20);
fprintf('data\n');
data
fprintf('data.ActiveInd\n');
data.ActiveInd
fprintf('doStuff about to be applied to data.ActiveInd\n');
data.ActiveInd = doStuff(data.ActiveInd);
fprintf('doStuff has been applied\n')
data
fprintf('New data.ActiveInd\n');
data.ActiveInd
function AInd = doStuff(AInd)
fprintf('doStuff: AInd before\n');
AInd
AInd(13) = 27;
fprintf('doStuff: AInd after\n');
AInd
end
In particular, look at the second time that data is displayed. First time,
data =
struct with fields:
ActiveInd: [0.8147 0.9058 0.1270 0.9134 0.6324 0.0975 0.2785 0.5469 0.9575 0.9649 0.1576 0.9706 0.9572 0.4854 0.8003 0.1419 0.4218 0.9157 0.7922 0.9595]
Then after the value in the field is updated to 27:
data =
struct with fields:
ActiveInd: [0.8147 0.9058 0.1270 0.9134 0.6324 0.0975 0.2785 0.5469 0.9575 0.9649 0.1576 0.9706 0 0.4854 0.8003 0.1419 0.4218 0.9157 0.7922 0.9595]
Notice that the 13th field has become 0 -- not remained the same and not become 27!
And yet when the field content is specifically requested immediately after that, it displays as 27.
Separate issue: It looks like "format debug" does reliably not work in LiveScript !
I am still chasing when it works or not.
My code shows that the address of data.ActiveInd is consistent going into doStuff, but that it changes as soon as it is written to, which is consistent with copy-on-write sematics.
What I was hoping was to see whether the address of the overall struct data itself changed, but unfortunately format debug does not display the address of struct . Is the entire struct copy-on-write, or only the field?
Run from function file:
data
data =
struct with fields:
ActiveInd: [1×20 double]
data.ActiveInd
ans =
Structure address = 208ffd1c1c0
m = 1
n = 20
pr = 208964b25c0
Columns 1 through 8
0.9593 0.5472 0.1386 0.1493 0.2575 0.8407 0.2543 0.8143
Columns 9 through 16
0.2435 0.9293 0.3500 0.1966 0.2511 0.6160 0.4733 0.3517
Columns 17 through 20
0.8308 0.5853 0.5497 0.9172
doStuff about to be applied to data.ActiveInd
doStuff: AInd before
AInd =
Structure address = 208ffd1c1c0
m = 1
n = 20
pr = 208964b25c0
Columns 1 through 8
0.9593 0.5472 0.1386 0.1493 0.2575 0.8407 0.2543 0.8143
Columns 9 through 16
0.2435 0.9293 0.3500 0.1966 0.2511 0.6160 0.4733 0.3517
Columns 17 through 20
0.8308 0.5853 0.5497 0.9172
doStuff: AInd after
AInd =
Structure address = 208ffb68400
m = 1
n = 20
pr = 208970333a0
Columns 1 through 8
0.9593 0.5472 0.1386 0.1493 0.2575 0.8407 0.2543 0.8143
Columns 9 through 16
0.2435 0.9293 0.3500 0.1966 27.0000 0.6160 0.4733 0.3517
Columns 17 through 20
0.8308 0.5853 0.5497 0.9172
doStuff has been applied
data =
struct with fields:
ActiveInd: [1×20 double]
New data.ActiveInd
ans =
Structure address = 208ffb68400
m = 1
n = 20
pr = 208970333a0
Columns 1 through 8
0.9593 0.5472 0.1386 0.1493 0.2575 0.8407 0.2543 0.8143
Columns 9 through 16
0.2435 0.9293 0.3500 0.1966 27.0000 0.6160 0.4733 0.3517
Columns 17 through 20
0.8308 0.5853 0.5497 0.9172
@Jan: So I did an "in-place" test and, as I suspected, using the in-place syntax works for stand-alone variables but not for structure fields (and probably not for cell array elements either). The shared data copy happens prior to the actual function call and this effectively disables the in-place behavior.
Jan
Jan 2021-1-28
编辑:Jan 2021-1-28
@James Tursa: "The above is not coded according to the "in-place" rules as I understand them." You are right. I ran it inside a function on my computer (R2018b) and copied the code partially only. I've edited my code above.
The output of the debug information show the expected behavior: Forwarding the field to the funtion creates a shared data copy, modifying the contents triggers a deep copy and returning the modified value to the caller does not copy but reuse the modified array.
Conclusion: There is no way for modifying a struct field in-place using a function.
James, which version of MATLAB did you happen to run in? I was using R2020b (MATLAB Online), which showed all of the contents of the data field instead of summarizing [1x20 double]
@Walter: PC Win64 R2020a
@Walter Roberson: In my Win10/R2018b system, your code shows expected behavior: The element is set to 27 immediately. But I see this
format debug
data.ActiveInd = 1:3;
% data.ActiveInd % Uncommenting does not let the zeros disappear
data
data.ActiveInd
% Output:
data = struct with fields:
ActiveInd: [0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0]
ans =
Structure address = 100266a0
m = 1
n = 20
pr = ff92c9c0
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
With data.ActiveInd=rand(1,3) this effect does not appear.
The test I just did with R2020b on Mac has data display with field ActiveInd that is [8 8 8] -- right length but wrong content.

请先登录,再进行评论。

类别

帮助中心File Exchange 中查找有关 Structures 的更多信息

标签

Community Treasure Hunt

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

Start Hunting!

Translated by