Looking for data structure ideas for App Designer GUI used to set simulation inputs

Hi all,
I’m looking for advice or ideas on how to manage data structures.
I have an App Designer GUI for a user to input data, which is then written to a save file (.mat). This file is loaded into an agent-based Monte Carlo simulation.
The agents used in the simulation are unlimited in number, include multiple agent types, and each instance (for each agent type) stores multiple data classes (e.g., strings, doubles, Booleans, arrays, etc.)
Currently, the data flow in the GUI is: data input field -> Map Container object -> Cell Array in the input GUI.
And, when used by the sim, the data flow is: Cell Array -> Map Container object (in a loop) -> named variable (in a function called in the loop)
For example:
% Numeric input field callback in the data input GUI
app.GreenAgent_InputsMap(Var1) = app.GreenAgent_Var1_InputField.Value;
% Write inputs map to cell array (by index) in the data input GUI, which is then saved to a .mat file
% (without the .app scope)
app.GreenAgent_InputsCells{n} = app.GreenAgent_InputsMap.keys();
app.GreenAgent_InputCells{n+1} = app.GreenAgent_InputsMap.values();
% In the simulation, the .mat file is opened (in a loop)
GreenAgent_InputsMap = containers.Map(GreenAgent_InputCells{n}, GreenAgent_InputCells{n+1});
GreenAgent_Var1 = GreenAgent_InputsMap(Var1);
I use the Map Containers to: 1) use names (like a dictionary) rather than index position in a cell array; and 2) store multiple data types. I use the Cell Arrays to unpack data for each agent type iteratively.
There are too many variables in each agent type to outright name the variables individually, especially considering an unlimited number of each agent type can be created by the user. As is, I’m effectively creating 3 copies of each variable:
  1. The App Designer input field (the input fields switch whenever a different agent of the same type is selected for editing)
  2. The Map Container key/value pair (the Map Container is overwritten whenever a different agent of the same type is selected for editing)
  3. The Cell Array where the data is ultimately stored and used by the sim (to support looping over an unlimited number of agents)
I’m wondering if there is a more elegant solution. For instance, it would be nice if each variable for an agent (i.e., in the Map Container) supported highlighting in the MATLAB editor to quickly find all the instances where that variable ('Var1' in the example code) is called and/or overwritten. I've thought about using structure arrays to take the place of the Map Containers and Cell Arrays, but that wouldn't solve the highlighting limitation, and I'm not sure if that is the best approach either.
Thanks for reading to this point!

5 Comments

It is a bit unclear, what is the issue here, other than code highlight. Structures won't help either, since only the structure variable gets highlighted in the editor and not its fields.
For instance, it would be nice if each variable for an agent (i.e., in the Map Container) supported highlighting in the MATLAB editor to quickly find all the instances where that variable ('Var1' in the example code) is called and/or overwritten.
Why would you need to find all the instances where the variable is changed? This seems like your code/variables needs some better data structuring. Provide example of data, and how do you want add/apply modifications to them.
Better data structuring, if possible, is what I am asking about. The issue (and also why highlighting when a variable/field is set and/or called would be helpful) is that the code is currently unwieldly, difficult to revise, and hard to debug. The GUI is over 6000 lines, and the sim is twice as big, spread across a couple dozen .m files.
I'm wondering if some complexity could be eliminated by not essentially managing three copies of variables in both the GUI and the simulation. I could certainly do it all with cell arrays, but then every data value would called by index only and that would be worse. To be clear, the entire input dataset is only stored in cell arrays. In the GUI app, dynamic input fields are used to populate the current Map Container object, which is then written to a cell array containing all the data. The SIM basically does this in reverse, except loops are used to unpack the cell array data and set the Map Container objects.
In terms of example data, imagine there are three kinds of people (i.e., red, green, and blue). A user can define as many of each red, green, and blue person as desired in the GUI. Because of the complexity of the sim, the properties (input data) of each person contains basically every type of MATLAB data (float, string/char, logical, vectors/arrays, etc.). Also, within a person class (red for example), not every field is populated. The data needed for each instance of a person type is dependent on other properties set for that person instance.
The method I'm using may be fine, but I need a sanity check because it feels like I made this more complex than necessary.
One thing I could see, is that you name your variables dynamically such as GreenAgent_Var1 and there should be a better way to do this. You also said that you want to access them with variable name, instead of index, which kind of makes the code longer and more complex, and despised.
If your structure resembles this, where key is one cell, and value is the other cell
% red % cell(1, 2)
% string array of keys(key1, ..., keyN)
% cell array of values(value1, ..., valueN)
and you have people inside cell arrays, like this
% combo % cell (1, N)
% red
% blue
% ...
Suggestion: If there are keys without values, then you can maybe arrange your data in the structure array, create all fields (keys) for specific kind of people, or just squash all keys in type of structure array. For the fields (keys) that do not have value, just leave it empty, and skip analysis on those
Yeah, I was leaning toward structure arrays because they would replace the Map Containers and the Cell Arrays with a single variable type, which would be cleaner. I don't remember if structure arrays support tab autocomplete because of the dot notation, but that would be helpful.
I'm not actually naming variables dynamically. I should have provided clearer example code. These variables are used in functions that are called from a loop. In the loop, the cell array is unpacked, contents written to a map object, and the map object is passed into a function. In the function, it's really like:
AgentAge = GreenAgent(Age) % GreenAgent is the map passed into the function
Thanks. I'll switch to structure arrays

Sign in to comment.

Answers (0)

Products

Release

R2022b

Asked:

on 25 May 2024

Commented:

on 28 May 2024

Community Treasure Hunt

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

Start Hunting!