MATLAB Answers

Any fixes for 'undefined function or variable 'struct2array'?

152 views (last 30 days)
D Peragine
D Peragine on 28 Nov 2019
Commented: Walter Roberson on 4 Apr 2020
Hi there! I'm using CHAP for pupillometry preprocessing, and can't seem to find a workaround for the below. Any tips or tricks out there? Deeply appreciated!
'Undefined function or variable 'struct2array'.
Error in chap>show_analyze_window (line 340)
data_table(i,:) = [outliers.(char(comp_names(i))) num_of_valid_trials int32(struct2array(ploted_data.(char(comp_names(i))).events))];
Error in chap>start_analyze (line 136)
data = show_analyze_window(src, cond_mat_cleaned, cond_events, data);
Error while evaluating UIControl Callback.
  1 Comment
Image Analyst
Image Analyst on 28 Nov 2019
Do you see the same thing I do when I do this:
>> which struct2array
C:\Program Files\MATLAB\R2019b\toolbox\shared\measure\struct2array.m

Sign in to comment.

Answers (1)

Walter Roberson
Walter Roberson on 28 Nov 2019
struct2array() is undocumented. In R2019b it is part of an archive named shared_measure_common
In versions up to R2013a, struct2array was part of the Signal Processing Toolbox and was installed in toolbox/signal/sigtools/struct2array.m . it was moved into basic MATLAB in R2013b and was installed in toolbox/shared/measure/struct2array.m . I find it in every version of MATLAB I have installed, including all the beta versions I have loaded.
If you are stuck you can find an implementation at https://git.dynare.org/Dynare/dynare/blob/2dcaff4f162dbadb1ca9dadb7fc0e61557af74e5/matlab/missing/struct2array/struct2array.m but I would suggest that first you try
restoredefaultpath; rehash toolboxcache
if that works, then you can proceed to save the path -- but note that this will remove any third-party toolboxes from your path (and possibly support packages as well.)
  2 Comments
Walter Roberson
Walter Roberson on 4 Apr 2020
I do not know why it is undocumented.
convert my structure from solve into an array which i could then use for substitution in the symbolic toolbox
You often do not need to do that. You can typically use
subs(expression, SolutionStructure)
and it will match field names to variables.
Historically there was a glitch in this process, though: if you asked for ReturnConditions then the parameters field might come out empty (conditions do not always have to involve introduced parameters), and when you subs() a struct in which any of the fields are empty, historically the entire result was empty.
Anyhow, you can use
temp = struct2cell(SolutionStructure);
mat = horzcat(temp{:});
This will produce an array with one column per variable, and one row per solution (could be multiple rows such as for roots of polynomials of low degree.)
Be careful when using this in subs(): chances are high that your subs() is not expecting a matrix with multiple rows. It is safer to not convert into a matrix, and to instead
subs(expression, cell_array_of_field_names, struct2cell(SolutionStructure))
Assuming, that is, that you did not use ReturnConditions and so do not have a parameters field, as that field is almost certain to be a different length than the other fields.
You need to be careful about the order of variables when you do this. Historically, when you solve for multiple variables and do not specify an output order, MATLAB has not always been consistent about the order of the fields: sometimes it returns them in symvar() order, and sometimes it does not. In particular, if you had something like V1, V2, V10, then historically sometimes you would get the order V1, V2, V10, and sometimes you would get the order V1, V10, V2 (because V10 sorts alphabetically before V2). In even older times, the fields were not always sorted consistently.
Because of the field order question, either specify the desired order of all of the variables when you solve(), or else use reorderfields() to get them into the desired order before you struct2whatever, or else use fieldnames() to find out the order of the fields. Just remember that fieldnames() does not return symbols, so to get the cell array of field names,
cell_array_of_field_names = cellfun(@sym,fieldnames(sol),'uniform', 0);
You do not want sym(fieldnames(sol)) as that will be a plain array of symbolic names, not a cell array with one name per entry as would be needed when you subs() a cell array.

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!