Reputation: 2299
I have two nested functions in Matlab. The outer one uses fminunc
and I would like your help how to correctly pass through it some arguments. Here my code
clear
rng default
%Some useful parameters
number_starting=10^3;
r=10^5;
J=2;
epsilon_sim=-evrnd(0,1,r,J+1); %rx(J+1)
options = optimoptions(@fminunc, 'MaxFunctionEvaluations', 10^4 ,'MaxIterations', 10^4, 'StepTolerance', 10^(-8), 'Display', 'off');
u_starting=normrnd(0,1,number_starting,J); %rxJ
This is the outer function which uses fminunc
function conv_conjugate=G_star(P, number_starting, options, u_starting,epsilon_sim)
fval=NaN(number_starting,1);
exitflag=NaN(number_starting,1);
for t=1:number_starting
try
coeff=u_starting(t,:).'; %starting values, column vector
[~,fval_temp,exitflag_temp]=fminunc(@obj,coeff, options);
fval(t)=fval_temp;
exitflag(t)=exitflag_temp;
catch
end
end
fval(exitflag>0,:);
conv_conjugate=-min(fval);
end
This is the inner function
function inner=obj(coeff)
comp1=sum(P.*(coeff.'));
comp2=mean(max(epsilon_sim+[coeff.' 0],[],2));
inner=-(comp1-comp2);
end
Here I try, for example, to evaluate the outer function at a given P
and it clearly gives me a mistake because some arguments are not correctly passed through obj
. Could you advise?
P_0=[0.7387,0.1562];
G_star(P_0, number_starting, options, u_starting,epsilon_sim);
Upvotes: 0
Views: 99
Reputation: 60780
There are two different ways that you can implement this.
1: The simple way
We create an anonymous function that encapsulates function values. Your inner function becomes:
function inner=obj(coeff,P,epsilon_sim)
comp1 = sum(P.*(coeff.'));
comp2 = mean(max(epsilon_sim+[coeff.' 0],[],2));
inner = -(comp1-comp2);
end
such that all values it uses are passed into it as arguments, then we create an anonymous function with one argument that calls obj
with all its arguments:
@(x)obj(x,P,epsilon_sim)
This is used as follows:
[~,fval_temp,exitflag_temp] = fminunc(@(x)obj(x,P,epsilon_sim),coeff, options);
2: The more obscure way
I say more obscure because this method makes it harder to see what is happening with variables.
Here we create a nested function, which shares variables with the function it is nested in. A nested function is defined inside another function, and will only be visible to that function:
function conv_conjugate = G_star(P,number_starting,options,u_starting,epsilon_sim)
fval = NaN(number_starting,1);
exitflag = NaN(number_starting,1);
for t = 1:number_starting
coeff = u_starting(t,:).'; %starting values, column vector
[~,fval_temp,exitflag_temp] = fminunc(@obj,coeff, options);
fval(t) = fval_temp;
exitflag(t) = exitflag_temp;
end
fval(exitflag>0,:);
conv_conjugate = -min(fval);
% Nested function:
function inner=obj(coeff)
comp1 = sum(P.*(coeff.'));
comp2 = mean(max(epsilon_sim+[coeff.' 0],[],2));
inner = -(comp1-comp2);
end
end % Note this "end" terminates the enclosing function, and is mandatory.
In the nested function, P
and epsilon_sim
are shared with the enclosing function.
Upvotes: 1