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

6 次查看(过去 30 天)
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 个评论
Stephen23
Stephen23 2021-12-20
编辑:Stephen23 2021-12-20
@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.

请先登录,再进行评论。

采纳的回答

Stephen23
Stephen23 2021-12-20
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);
Frequency=10;
% 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}));
end
The results are efficiently stored in the cell array C.

更多回答(2 个)

Sahil Jain
Sahil Jain 2021-12-20
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);
Frequency=10;
% Get the field names
L = fieldnames(yData);
% Generating output
for i=1:length(L)
eval(strcat("[out_",L{i},",~]=createFit(Frequency, yData.",L{i},");"));
end
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.
  2 个评论
Stephen23
Stephen23 2021-12-20
编辑:Stephen23 2021-12-20
Using fieldnames might be a good start, but the rest of this code is very poor advice: it will make acessing and processing the data complex and less inefficient compared to acessing it directly from the original structure. This is explained in the MATLAB documentation:
Dynamic fieldnames have also existed since 2005:

请先登录,再进行评论。


Walter Roberson
Walter Roberson 2021-12-20
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);
end
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!

Translated by