MATLAB: Creating table from Workspace variables within a for loop

for looptable

Hello Everyone,
I am rather new to Matlab and right now are running slightly into a wall. I want to fit data from a 3D matrix and extract the fit parameters into tables, i.e. my parameters are a, b, c, d, e etc. and I basically want for each x-y value of my matrix a new matrix with the respective fit parameter for that x-y coordinate. I got so far to get the fitting working, when I write the a from my first loop, that obviously works, but in the second loop the a value of that loop just replaces my a from the first loop, and so on.
The Matlab version I work with is R2014a.
for i=1:512
for j=1:640
y2=A(i,j,:);
y1=y2(:,2:nFiles);
y=transpose(y1);
x1=2 : nFiles;
x=transpose(x1);
try
F = fit(x,y,'a*exp(-x/b)+c*exp(-x/d)+g','Algorithm', 'Levenberg-Marquardt','Robust', 'Bisquare' ,'MaxIter', 50, 'StartPoint', [40 0.5 1 75 0]);
plot(F,x,y);
R = coeffvalues(F);
ParamA = table(R(1:1));
catch ME
end
end
end

Best Answer

See my comments to the question. Writing code that is easily understood is just as critical as writing code that works!
Note that you're performing 512 x 640 fit. This is going to take a while.
I'm assuming that in your original code, size(A, 1) is 512, size(A, 2) is 640 and size(A, 3) is nFiles. Avoid using hardcoded constants which need changing if you change the size of arrays. Simply tell matlab to use the size of the arrays, whatever that is.
x = (2:size(A, 3)).'; %no point wasting time doing this repeatedly inside a loop.
numvar = 5; %number of variables in the fit function
[rows, columns] = ndgrid(1:size(A, 1), 1:size(A, 2)); %create pairs of rows/columns to store in output table and to index over
fitresults = zeros(numel(rows), numvar); %preallocate matrix to store fit results
for step = 1:numel(rows)
y = reshape(A(rows(step), columns(step), 2:end), [], 1); %extract 3rd dimension and convert to column vector
try %fit function may error
F = fit(x,y,'a*exp(-x/b)+c*exp(-x/d)+g','Algorithm', 'Levenberg-Marquardt','Robust', 'Bisquare' ,'MaxIter', 50, 'StartPoint', [40 0.5 1 75 0]);
fitresults(step, :) = coeffvalues(F);
catch
fitresults(step, :) = NaN; %if failure store NaN
end
results = array2table([rows(:), columns(:), fitresults], 'VariableNames', [{'row'; 'column'}; coeffnames(F)])
edit: fixed bug in ndgrid call and added error handling in case fit fails