Using Function Handle in app designer

Hello,
I have written a Matlab code which uses Function Handle while execution.
OB_FUN=@Prony_Inf; % Objective function is Prony_Inf
[Prony,RESNORM] =lsqnonlin(OB_FUN,Prony_0,lb,ub);
Additional input variables:
[Filename, Filepath, ~] = uigetfile('*.xlsx','Select the desired Excel-File with the material values');
addpath(Filepath);
[~, ~, raw] = xlsread(Filename);
%%
Material=cell2mat(raw(2,1)); % Extract the material name from the variable raw
Freq=cell2mat(raw(2:end,2)); % Extract the frequency data from the variable raw
E1=cell2mat(raw(2:end,3)); % Extract the storage modulus data from variable raw
E2=cell2mat(raw(2:end,4)); % Extract the loss modulus data from variable raw
v=cell2mat(raw(2,6)); % Extract the Poisson's ratio from variable raw
E_VALUE=cell2mat(raw(2,5)); % Extract the Value of the modulus of elasticity from variable raw
E_NAME=cell2mat(raw(1,5)); % Extract the Name of the modulus of elasticity from variable raw
E=E_VALUE;
Start=0.1; % Default starting value
Startg = Start;
Starttau = Start;
N_Prony=8;
T=table(E,v,Start,N_Prony);
E1t=transpose(E1); % Value of storage modulus from the Excel file has to be transposed for optimization
E2t=transpose(E2); % Value of loss modulus from the Excel file has to be transposed for optimization
tand_measure=E2t./E1t; % Calculation of the dissipation factor
AngFreq=transpose(Freq.*2.*pi); % Calculation of the angular frequency based on the frequency from the Excel file. Values have to be transposed for optimization
Length_Datas=length(AngFreq); % Get the length of the frequency datas for preallocation
save('variablesforfun.mat','E','AngFreq','E1t','E2t','tand_measure') % datas will be saved to use them in the objective function
%%
ubgi = 1;
ubtaui = 10000; %CHANGE THE LIMITS BASED ON ALREADY AVAILABLE PRONY RELAXATION TIME INPUTS FROM TEXT FILE
save('NumberProny.mat','N_Prony') % Current number of Prony parametes will be saved for the obejective function
Prony_0 = ones(N_Prony*2,1); % Create a vector for the start values of the optimization
Prony_0(1:N_Prony)=Prony_0(1:N_Prony)*Startg; % Define the start values of gi in the variable Prony_0
Prony_0(N_Prony+1:2*N_Prony)=Prony_0(N_Prony+1:2*N_Prony)*Starttau; % Define the start values of taui in the variable Prony_0
lb= zeros(N_Prony*2,1); % Create a vector with the lower bounds of the optimization function
ub=ones(N_Prony*2,1); % Create a vector for the upper bounds of the optimization function
ub(1:N_Prony)=ub(1:N_Prony)*ubgi; % Define the upper bounds for the weights gi in the optimization function
ub(N_Prony+1:N_Prony*2)=ub(N_Prony+1:N_Prony*2)*ubtaui; % Define the upper bounds for the relaxation times taui in the optimization function
%% Calling desired prony results as input
fileID = fopen('Prony_Tool_pronyoutputs_TIM-TC4525_01 - Copy.txt','r');
formatSpec = '%f';
Prony_0 = fscanf(fileID,formatSpec);
fclose(fileID);
Then I have my function as follows:
function ceq=Prony_Inf(Prony_0) % Objective function based on Einf as input
load variablesforfun.mat E % Load variable "E" from hard drive into function workspace
load variablesforfun.mat AngFreq % Load variable "AngFreq" from hard drive into function workspace
load variablesforfun.mat E1t % Load variable "E1t" from hard drive into function workspace
load variablesforfun.mat E2t % Load variable "E2t" from hard drive into function workspace
load variablesforfun.mat tand_measure % Load variable "mechVtand" from hard drive into function workspace
load NumberProny.mat N_Prony % Load variable "N_Prony" from hard drive into function workspace
Storage_Modulus_Calc=E+(E/(1-sum(Prony_0(1:N_Prony,1))))*sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2)./(1+Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2)); % Calculation of Storage Modulus based on E inf
Loss_Modulus_Calc=(E/(1-sum(Prony_0(1:N_Prony,1))))*sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).*AngFreq)./(1+(Prony_0(N_Prony+1:N_Prony*2,1)).^2 .*AngFreq.^2)); % Calculation of Loss Modulus based on E inf
Dissipation_Factor_Calc=((sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).*AngFreq)./(1+(Prony_0(N_Prony+1:N_Prony*2,1)).^2 .*AngFreq.^2)))./(((1-sum(Prony_0(1:N_Prony,1)))+sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2)./(1+Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2))))); % Calculation of the dissipation factor
SigmaE1=std(E1t);
SigmaE2=std(E2t);
Sigmatand=std(tand_measure);
ceq=norm(((E1t-Storage_Modulus_Calc)./SigmaE1).^2+((tand_measure-Dissipation_Factor_Calc)./Sigmatand).^2+((E2t-Loss_Modulus_Calc)./SigmaE2).^2); % Value which should be minimized
end
Now in app designer I tried calling this way:
[app.Prony] =lsqnonlin(@Prony_Inf,app.Prony_0,app.lb,app.ub);
I am getting following error:
"Not enough input arguments.
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue."
Please help me with this issue.
Thank you,

6 Comments

There is some inconsistency with whether prony_fit has a lowercase or capital P, but that is likely just a typo.
What values are you using for Ini_Par, lb, and ub?
When I use made up data, I get the same error message even in MATLAB. It makes sense because Prony_fit has 5 inputs and, as best I can tell, you are only passing in one.
Thanks for answering and sorry for the delayed reply.
My function is quite big and hence I had cut short it previously. But now I have edited my question with all the features. I have also included 2 attachments which will be required while executing above functions.
Specifically I find issue with the variable "AngFreq". Can you please let me know the way I can execute the above using "AppDesigner"?
Thank you,
Stephen23
Stephen23 on 11 Dec 2018
Edited: Stephen23 on 11 Dec 2018
@Sandeep Ramini: your code will be very slow, because you load many .mat files inside the objective function. So every time the optimizer calls that function, it loads the same files again and again and again and again and again... thousands of times. A total waste of time.
In your case it is not required to save them in mat files anyway: simply pass those variables directly to the objective function either using a nested function or an anonymous function, exactly as the MATLAB documentation explains:
And if you do use load, do NOT just load directly into the workspace like that: it is much more robust to load into an output variable (which is a structure):
S = load(...)
Hello, As you suggested I tried using Parameterizing using Nested Functions. Hence I created a separate function file like this:
function ceq = findProny(Prony_0,AngFreq,E1t,E2t,tand_measure,lb,ub)
ceq = lsqnonlin(@prony_Inf,Prony_0,lb,ub);
function ceq=Prony_Inf(Prony_0) % Objective function based on Einf as input
Storage_Modulus_Calc=E+(E/(1-sum(Prony_0(1:N_Prony,1))))*sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2)./(1+Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2)); % Calculation of Storage Modulus based on E inf
Loss_Modulus_Calc=(E/(1-sum(Prony_0(1:N_Prony,1))))*sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).*AngFreq)./(1+(Prony_0(N_Prony+1:N_Prony*2,1)).^2 .*AngFreq.^2)); % Calculation of Loss Modulus based on E inf
Dissipation_Factor_Calc=((sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).*AngFreq)./(1+(Prony_0(N_Prony+1:N_Prony*2,1)).^2 .*AngFreq.^2)))./(((1-sum(Prony_0(1:N_Prony,1)))+sum((Prony_0(1:N_Prony,1).*Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2)./(1+Prony_0(N_Prony+1:N_Prony*2,1).^2.*AngFreq.^2))))); % Calculation of the dissipation factor
SigmaE1=std(E1t);
SigmaE2=std(E2t);
Sigmatand=std(tand_measure);
ceq=norm(((E1t-Storage_Modulus_Calc)./SigmaE1).^2+((tand_measure-Dissipation_Factor_Calc)./Sigmatand).^2+((E2t-Loss_Modulus_Calc)./SigmaE2).^2); % Value which should be minimized
end
end
Then I tried calling it in app Designer like this:
app.Prony = findProny(app.Prony_0,app.AngFreq,app.E1t,app.E2t,app.tand_measure,app.lb,app.ub);
I am still getting the error as follows:
Error in lsqnonlin (line 206)
initVals.F = feval(funfcn{3},xCurrent,varargin{:});
Error in findProny (line 3)
ceq = lsqnonlin(@prony_Inf,Prony_0,lb,ub);
Error in PronyFit/OptimizationMethodListBoxValueChanged (line 232)
app.Prony = findProny(app.Prony_0,app.AngFreq,app.E1t,app.E2t,app.tand_measure,app.lb,app.ub);
Caused by:
Failure in initial objective function evaluation. LSQNONLIN cannot continue.
Error using matlab.ui.control.internal.controller.ComponentController/executeUserCallback (line 352)
Error while evaluating ListBox PrivateValueChangedFcn.
Stephen23
Stephen23 on 11 Dec 2018
Edited: Stephen23 on 11 Dec 2018
@Sandeep Ramini: please save the following input variables in a .mat file, and upload them in a new comment: Prony_0,AngFreq,E1t,E2t,tand_measure,lb,ub.
% Specifically I find issue with the variable "AngFreq".
% Can you please let me know the way I can execute the above using "AppDesigner"?
In app designer, you call the function with the following inputs:
  • app.Prony_0
  • app.AngFreq
  • app.E1t
  • app.E2t
  • app.tand_measure
  • app.lb
  • app.ub
How do you create these variables in app designer? Can you share that code as well? Just sharing the code that works in MATLAB does not help us debug App Designer issues.

Sign in to comment.

Answers (0)

Asked:

on 5 Dec 2018

Commented:

on 11 Dec 2018

Community Treasure Hunt

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

Start Hunting!