【问题标题】:Nesting multiple functions in Matlab在 Matlab 中嵌套多个函数
【发布时间】:2020-06-30 19:00:58
【问题描述】:

我在 Matlab 中有两个嵌套函数。外部使用fminunc,我希望您能帮助我正确地传递一些参数。这是我的代码

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

这是使用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

这是内部函数

function inner=obj(coeff)

comp1=sum(P.*(coeff.'));

comp2=mean(max(epsilon_sim+[coeff.' 0],[],2));

inner=-(comp1-comp2);
end

例如,在这里我尝试在给定的P 处评估外部函数,这显然给了我一个错误,因为某些参数没有正确地通过obj。能给个建议吗?

P_0=[0.7387,0.1562];
G_star(P_0, number_starting, options, u_starting,epsilon_sim);

【问题讨论】:

  • 如果它们是嵌套函数,那么内部函数将在外部函数内部定义,并且可以访问其变量。就目前而言,obj 看起来像是一个独立的、独立的函数,它使用未定义的变量。因为您捕获所有错误并忽略它们,所以您可能没有注意到这一点。
  • 谢谢。 obj 在计算com1 时使用P,这是G_star 的参数之一。我不知道如何通过P 传递obj

标签: matlab


【解决方案1】:

您可以通过两种不同的方式来实现它。

1:简单的方法

我们创建一个封装函数值的匿名函数。你的内在功能变成:

function inner=obj(coeff,P,epsilon_sim)
    comp1 = sum(P.*(coeff.'));
    comp2 = mean(max(epsilon_sim+[coeff.' 0],[],2));
    inner = -(comp1-comp2);
end

这样它使用的所有值都作为参数传递给它,然后我们创建一个带有一个参数的匿名函数,该函数调用 obj 及其所有参数:

@(x)obj(x,P,epsilon_sim)

这个用法如下:

[~,fval_temp,exitflag_temp] = fminunc(@(x)obj(x,P,epsilon_sim),coeff, options);

2:比较晦涩的方式

我说的比较晦涩,因为这种方法更难看出变量发生了什么。

这里我们创建一个nested 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.

在嵌套函数中,Pepsilon_sim 与封闭函数共享。

【讨论】: