MATLAB Answers

What is the best way to keep two variables synchronized?

10 views (last 30 days)
Michael
Michael on 19 Apr 2017
Edited: Adam on 21 Apr 2017
I am looking for advice on the best way to approach this problem. My initial instinct was that pointers would be the way to go, but MATLAB doesn't have "normal" pointers and any pointer-like solutions I've seen are hacks using functions or classes derived from handles that I'm not sure would work particularly well in my situation. So perhaps I'm thinking about this all wrong and there's a cleaner way to do things from the start...
Here's the situation: I am doing thermodynamic type calculations in two closed fluid loops. For each loop I have a single structure variable that contains the various items in the loop. Let's suppose that one loop has a heat source and a heat exchanger in it and the other has a heat sink and a heat exchanger in it, forgetting about things like temperatures and neglecting all the other loop pieces to keep things simple. These loops are connected via that common heat exchanger which is a part of both loops.
So my calculations might be such that they effectively set the following items:
loop1.heatSource.heatLoad=10;
loop1.heatExchanger.hotFlow=1;
loop1.heatExchanger.heatLoad=10;
Now I'm ready to do some calculations in the second loop to get that heat load to the heat sink. Let's say I now want to calculate the heat exchanger's cold side flow rate (i.e. the loop 2 flow rate). These calculations belong to loop 2, yet the heat exchanger is the same one for both loops. So right now what I do is:
loop2.heatExchanger=loop1.heatExchanger; % I need the heatLoad value for my calculation and I want to keep things synced
Then I do my calculation and arrive at:
loop2.heatExchanger.coldFlow=2;
Because these heat exchangers are actually the same piece, I then currently copy the structure back over to loop 1 so it's up to date.
loop1.heatExchanger=loop2.heatExchanger; % update loop 1's structure with the newly calculated value
Having to do these copies is an error prone approach. I would like to somehow establish a linking/pointer/alias type relationship between loop1.heatExchanger and loop2.heatExchanger such that I don't need to do any copying, my coldFlow=2 assignment would immediately get reflected back to the loop 1 instance, and it would always be true that loop1.heatExchanger and loop2.heatExchanger would always have the exact same fields set to the exact same values.
I have considered making heatExchanger not contained within either loop (i.e. a separate variable in the same scope as loop1 and loop2) so there would be only a single instance of that heat exchanger, but that then loses the fact that that heat exchanger is indeed part of loop 1 and also is part of loop 2. Looking at the contents of the loop1 variable for example I wouldn't have any information about that important piece of the loop.
I do create the heatExchanger structure and all the fields it will have at the beginning of my code and initialize the fields with NaNs to make it obvious when things haven't been set/copied. That does help identify mistakes of forgotten copies, but it doesn't at all address the need for those copies in the first place or help when a copy is missed after a value has been set initially.
Any help/guidance on a good way to approach this or structure my variables/code is greatly appreciated.

  0 Comments

Sign in to comment.

Accepted Answer

James Tursa
James Tursa on 19 Apr 2017
"... any pointer-like solutions I've seen are hacks using functions or classes derived from handles ..."
This is really the only way, in MATLAB, to do directly what you are trying to do. The indirect way, of course, is to do the manual copying. So I think you are stuck with one of these (or similar) approaches.
MATLAB variables are not "tied down", so to speak, to any particular memory. As your program executes the data pointers for a variable can change, and in fact the variable itself can change its location in memory. So any memory pointers that you might want to employ simply would not be reliable. The advantage of a handle derived class is that the data pointers for the individual variables are forced to be tied to each other ... effectively they are forced to be shared data copies of each other. So changes in one variable are instantly reflected in the other since they share the same data memory.

  3 Comments

Michael
Michael on 20 Apr 2017
James - thank you for the quick response.
In playing around just now it occurred to me that I could make classes for specific components like the heat exchanger derived from the handle class rather than use some generic classdef ptr < handle type thing as I had been thinking based on my initial "how to" searches.
So this is what I tried just now. I made the following class definition:
classdef classdef_HX < handle
properties
hotFlow = nan;
coldFlow = nan;
heatLoad = nan;
HXmass = nan;
end
end
And then the following seems to work the way I want.
>> loop1=struct('heatSource',struct('heatLoad',nan,'Temp',nan),'heatExchanger',classdef_HX);
>> loop2=struct('heatExchanger',classdef_HX,'heatSink',struct('heatLoad',nan));
>> loop2.heatExchanger = loop1.heatExchanger;
>> loop1.heatSource.Temp=200;
>> loop1.heatSource.heatLoad=10;
>> loop1.heatExchanger.hotFlow=1;
>> loop1.heatExchanger.heatLoad=loop1.heatSource.heatLoad;
>> loop2.heatExchanger.coldFlow=2;
>> loop2.heatSink.heatLoad=1.1*loop2.heatExchanger.heatLoad;
>> loop1.heatSource
ans =
heatLoad: 10
Temp: 200
>> loop1.heatExchanger
ans =
classdef_HX with properties:
hotFlow: 1
coldFlow: 2
heatLoad: 10
HXmass: NaN
>> loop2.heatExchanger
ans =
classdef_HX with properties:
hotFlow: 1
coldFlow: 2
heatLoad: 10
HXmass: NaN
>> loop2.heatSink
ans =
heatLoad: 11
Can you confirm that there's nothing "dangerous" about having structure variables which have non-identical fields and only one of those fields is linked via the handle derived class as I've done? As long as the above is safe, I think it's a very attractive solution.
Adam
Adam on 20 Apr 2017
handle-derived classes definitely wouldn't fall under the definition of a hack. I use them all over the place to allow GUIs and objects to communicate with each other while accessing the same data.
There is no problem with having a struct that contains some normal data types and some handle-class objects. I wouldn't do it myself, but that is just because I would use classes throughout instead of structs, but the general idea is the same - a field on a struct is analagous to a property on a class.
One big thing that is missing from Matlab's handle-based OOP approach is that you cannot have the concept of a const reference/pointer as you can in C++ which does open up code to rather more bugs than you'd often like. If a class has a public property or function that changes its state then every copy of an object of that class will always have access to set those and you can't change that unfortunately. But that is just a coding issue that means you have to take that bit more care yourself.
Michael
Michael on 20 Apr 2017
Thanks for the feedback. I guess I didn't realize that handle-derived classes were intended to be usable in this way. This seems incredibly powerful, so I'm really glad to know that this is a reasonable thing to do in general.
In my particular application I can't really use classes alone because loop1 and loop2 will contain very different components (i.e. not all the same struct fields, which would mean not having all the same class properties), but I do see the point you're making.
Thank you both for the help!

Sign in to comment.

More Answers (0)


Translated by