-
Notifications
You must be signed in to change notification settings - Fork 0
MATLAB Idiosyncracies
When I started this project, I had never developed in MATLAB before. I spent a lot of time in trial and error, and I'm recording the more frustrating / undocumented things I ran into here to hopefully save the next person some time. If you've programmed in MATLAB before, or your primary programming experience isn't in some other more developer-friendly language, you can safely skip this guide, which is less of a guide and more a list of things I found frustrating to figure out.
Lots of documentation lives in MATLAB itself. It's good to know about the:
-
helpcommand -
inspect()function
in MATLAB, the only way to make pointers is to make a class that inherits from Handle. But be warned! If you put a handle subclass into another data structure (e.g. a cell), then whenever you access that handle and change its properties, you will need to re-assign the cell contents to the new handle. For example:
c = {};
c{end} = HandleSubclassObject();
...
h = c{end};
h.property = newVal; % this line creates a copy of your handle object!
c{end} = h; % without this line, the value will not be updated for the handle object within the cell!
Function calls don't need brackets after them unless they're followed by additional indexing. For example, if a class has a function GetStruct(obj):
struct = obj.GetStruct;
attr = obj.GetStruct().Attribute;
You can also create dependent variables, which work very similarly to obj.GetAttr() functions, but don't need to be followed by brackets when followed by additional indexing.
- Starts at 1.
- Braces
{}are used for cell arrays and some other more modern data structures within matlab. parentheses()are used for simple arrays, and also for named indexing. If you have the name of an object's property as a string, you can access that object's property usingobj.(propertyNameString), as well as using obj.propertyName. - Cell arrays are more flexible than simple arrays - a cell can have pretty much anything in it, which is useful for collections of disparate data
- Sometimes, "invalid array indexing" means you can't index that variable for whatever reason, and sometimes it means you've tried to do some operation on the data structure after indexing, which is often not valid. For example:
% Valid:
cellcontents = cell{1};
cellContentsAttr = cellContents.Attribute;
% Sometimes Invalid:
cellcontentsAttr = cell{1}.Attribute;
Matlab allows foreach loops with the syntax
for instance = array
% some logic related to instance x of array
end
But ONLY for 1xn arrays, not for nx1 arrays! You will need to transpose the array using the ' operator at the end of the array if you want to foreach through an nx1 array.
Or you can do what I did most of the time and use for i=1:length(array)
I used categoricals because they're the easiest way I could find to dynamically code dropdowns for component config. They're a bit of a nightmare to work with, and the documentation / forum activity for them is less robust than I'd like, so here are some bits I figured out:
if you want to extract the value from a categorical, I extracted it from its categories() like this:
newVal = src.Data.values{rownum};
if iscategorical(newVal)
cat = categories(newVal);
idx = find(categorical(cat) == newVal);
newVal = cat{idx};
end
If you want to set the displayed value of a ComponentProperty as a categorical, I did it like this:
cat = prop.getCategorical; %nb look in ComponentProperty for this. It is not a built-in function.
configVal = component.ConfigStruct.(rowNames{fnum});
if ischar(configVal)
configCat = categorical(cellstr(configVal));
idx = find(cat == configCat);
values{fnum} = cat(idx);
elseif isstring(configVal)
configCat = categorical(cellstr(configVal));
idx = find(cat == configCat);
values(fnum) = {cat(idx)};
elseif isnumeric(configVal)
configCat = categorical(configVal);
idx = find(cat == configCat);
values(fnum) = {cat(idx)};
end
Look at all those different ways to use brackets!
Also remember with categoricals that they only accept certain kinds of input: a numeric array, logical array, string array, or cell array of character vectors.
function createPanelThermode(obj,hPanel,~,idxThermode,nThermodes)
obj.h.(thermodeID).panel.params = uipanel(obj.h.fig,...
'CreateFcn', {@obj.createPanelThermode,ii,length(obj.s)});
- Data Linking - dynamic updates of plots as the data changes. Doesn't work on some kinds of plots and requires named variables though.