Pass structure variables one by one to a function (input) and name the outputs based on input names
8 次查看(过去 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
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
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.
0 个评论
更多回答(2 个)
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
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
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.
另请参阅
类别
在 Help Center 和 File Exchange 中查找有关 Debugging and Analysis 的更多信息
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!