Pass structure variables one by one to a function (input) and name the outputs based on input names

3 views (last 30 days)
HI there,
This maybe a fundamentally easy question but I am new to MatLab and i dont understand many things.
I am using The curve fitting tool. I have hundreds (457) of variables stored in a structure (called yData) as individual columns (405x1). They are equally sized and I need to fit a curve on each one of them. The function takes two input arguments and has two output arguments.
[fitresult, gof] = createFit(Frequency, yData)
The input Frequency is always the same so this is ok
Could someone please provide a clear and well explained code where you actually show me how to do the following?
How can I pass each variable to the curve fitting tool function sequentially and receive the results (output of the function) incorporating the name of the variable taken?
I am confused with indexing, passing the name of the field and other staff that are alien to newcomers.
I have used somethingg like
L=fieldnames(yData) that creates a cell array of the names of my variables but i have not gone too far as I always get the error
Error using prepareCurveData>iAssertInputsHaveSameNumElements (line 47)
Data sizes do not match. All the data for curve fitting must have the same number of elements.
All input welcome and I am sorry for such rudimentary question. It seems hard for me to find the answer here. Cheers
  1 Comment
Stephen23 on 20 Dec 2021
Edited: Stephen23 on 20 Dec 2021
@Antonios Dougalis: whatever you do, you should ignore bad advice to dynamically name variables (e.g. EVAL).
The MATLAB documentation (which one would presume that TMW staff would be aware of) warns against that approach:
The best approach is to simply loop over the fieldnames and use indexing.

Sign in to comment.

Accepted Answer

Stephen23 on 20 Dec 2021
The simple and efficient MATLAB approach is to use dynamic fieldnames and indexing:
% Creating dummy data
yData.a = rand(405,1);
yData.b = rand(405,1);
yData.c = rand(405,1);
% Get the field names
F = fieldnames(yData);
N = numel(F);
C = cell(1,N);
for k = 1:N
C{k} = createFit(Frequency, yData.(F{k}));
The results are efficiently stored in the cell array C.

More Answers (2)

Sahil Jain
Sahil Jain on 20 Dec 2021
Hi Antonios. From my understanding of the question, you want to pass the variables of the structure one by one to the "createFit" function and the output variable names should contain the name of the input variable names in some form. Using "fieldnames" to get the variable names is a good start. As a next step, you can construct the string of the "createFit" operation and then use the "eval" function to generate the output. The following code snippet demonstrates this.
% Creating dummy data
yData.a = rand(405,1);
yData.b = rand(405,1);
yData.c = rand(405,1);
% Get the field names
L = fieldnames(yData);
% Generating output
for i=1:length(L)
eval(strcat("[out_",L{i},",~]=createFit(Frequency, yData.",L{i},");"));
This snippet will generate three variables "out_a", "out_b" and "out_c". You can modify the code to change the variable names as you wish.

Sign in to comment.

Walter Roberson
Walter Roberson on 20 Dec 2021
function [fitresult, gof] = createFit(Frequency, yData)
names = fieldnames(yData);
N = length(ydata.(names{1}));
t = (0:N-1)/frequency .';
ft = fittype(Appropriate information that describes model);
[fitresult, gof] = structfun(@(y) fit(ft, t, y), yData, 'uniform', 0);
Afterwards, fitresult and gof will each be structures with one field for each field name in yData, giving the results related to that field.

Community Treasure Hunt

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

Start Hunting!