Loop with fminsearch and cell arrays

6 views (last 30 days)
Ace
Ace on 5 Jul 2023
Answered: Ace on 4 Oct 2023
Hi there! I am learning to code in Matlab. I've been struggling to perform regression analysis for multiple datasets. I have 3 parameters: perm, which is the measured output, t2lm which is the known input and por which also stands for the known input. I'm given the following equation:
perm=a1*t2lm^a2*por^a3
Now let's suppose I have an excel file with multiple sheets. Each sheet contains those 3 parameters in separate columns. The goal is to find a1-a3 coeffs for each dataset stored in a separate excel sheet and compute the predicted perm value p. So far, I compiled the following piece of code
clear all
%import Excel data separately for each sheet
FName ='Test.xlsx';
S_names = sheetnames(FName);
for ii=1:numel(S_names)
D=readtable(FName, 'Sheet', S_names(ii));
end
%divide the data into parameters
perm = cellfun(@(X) X(:,1), D, 'uniform', 0);
t2lm = cellfun(@(X) X(:,2), D, 'uniform', 0);
por = cellfun(@(X) X(:,3), D, 'uniform', 0);
%transpose the parameters
permT=perm';
t2lmT=t2lm';
porT=por';
%perform non linear regression to find a1 a2 and a3 coeffs
%and compute the p parameter for each dataset
for k = 1:length(D)
Q=@(A) sum ((permT{k} - A(1).*(t2lmT{k}.^A(2)).*porT{k}.^A(3)).^2);
a{k}=fminsearchbnd(Q, [50,4,6],[40,inf,1],[inf,6,6]);
p{k}=a(1).*(t2lmT{k}.^a(2)).*porT{k}.^a(3);
end
The problem is the fminsearchbnd won't work. Probably I am passing the parameters to the function in a wrong way or the function can't handle cell arrays. If so, please help me out how to fix the problem. I would like to end up having a vector consisting of k values of p and ideally a cell array a consisting of k sets of 3 estimated parameters
I would be grateful for your guidance.

Accepted Answer

Ace
Ace on 4 Oct 2023
Well, my colleague helped me to modify this and now it works perfectly. I hope this solution helps anyone:
Changes to make in the code above:
  • Use just one loop for ii=1:numel(S_names) ... end (no need to involve two loops).
  • Get all the 3 parameters separately by using table2array and specifying a given column in D (this is to extract a given column from the excel file).
  • If any variable is imported as a cell, which might be an issue, use str2double, for example that way:
if iscell(parameter)
parameter = str2double(parameter);
end
No need for transposing anything now.
  • Then continue with deleting the 2nd for loop and deleting the indexing with curly braces and brackets as follows.
Q = @(A) sum ((perm - A(1).*(t2lm.^A(2)).*por.^A(3)).^2);
a = fminsearchbnd(Q, [50,4,6], [0,0,0]);
p{ii, :}=a(1).*(t2lm'.^a(2)).*por'.^a(3);
Note that the indexing is only needed for "p" to let the code generate the complete list of the "perm" parameter, for which we solve.
You may also want to see the whole list of the a1-a2-a3 coefficient before they become overwritten in the loop. Simply use something like:
mycoeffs(ii,:) = a;
Best regards,
Ace.

More Answers (1)

rakshit gupta
rakshit gupta on 6 Jul 2023
I think the issue is how you are accessing the elements of 'a' and 'p'. Access the elements using curly braces '{}' instead of '()'.
Changes in the last line of the code:
p{k} = a{k}(1).*(t2lmT{k}.^a{k}(2)).*porT{k}.^a{k}(3);
  1 Comment
Ace
Ace on 6 Jul 2023
Edited: Ace on 7 Jul 2023
Hi Rakshit and thank you for your answer. Unfortunately this doesn't solve the issue. I would be grateful if anybody suggested some solution to this problem. Thanks in advance.

Sign in to comment.

Products

Community Treasure Hunt

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

Start Hunting!