繁体   English   中英

如何确定函数句柄的输入参数的大小

[英]How to determine the size of an input argument for a function handle

我正在创建一个将数据( x,y,z )和一个匿名函数( M )作为输入的函数。 M的输入是数据( x,y,z )和一个参数( theta )。

我需要确定FUNC内参数theta的尺寸

编辑:(添加一些上下文)

我有遵循已知数据生成过程(DGP)的数据。 例如,我可以使用具有1个内生变量的线性工具变量DGP生成数据(因此theta将为1维):

n = 100; q = 10;
theta0 = 1;                               % true param value
e = randn(n, 1);                          % 2nd stage error
u = randn(n, 1);                          % 1st stage error
z = randn(n, q);                          % instrument
x = z * ones(q, 1) + u;                   % endog variable
y = x * theta0 + e;                       % dependent variable

然后我想使用我自己的广义线性方法( FUNC )的变化来估计theta0

M = @(x,y,z,theta) z' * (y - x * theta);  % moment condition
thetahat = FUNC(M, x, y, z);              % estimate theta0

FUNC.m

function out = FUNC(M, x, y, z)
k = ; % (!!!) <-- this is what I need to find out!
objFunc = @(theta) M(x, y, z, theta)' * M(x, y, z, theta);
out = fminunc(objFunc, ones(1, k)); % <-- this is where its used
end

在上面的示例中,DGP是线性IV模型。 但是,我应该可以将我的函数用于任何其他DGP。

例如,其他DGP可以将M定义如下:

% E.g. 1) theta is dimension 1
M=@(x,y,z,theta) z' * (y - x * theta); 
% E.g. 2) theta is dimension 2
M=@(x,y,z,theta) z' * (y - (x * theta(1))^theta(2)); 
% E.g. 3) theta is dimension 3
M=@(x,y,z,theta) z' * (y - (theta(1) + x * theta(2))^theta(3)); 

我当前用于(!!!)的(超级坏)hack是:

for ktest = [3,2,1] % the dimension of theta will never be higher than 3
    try 
        M(x, y, z, ones(1, ktest);
        k = ktest;     
    end
end

因为您已经知道将函数M传递给FUNC时函数M的形式和要求,所以仅要求FUNC根据M确定函数就没有多大意义。 当将其传递给M时,将标志值或所需的信息传递给FUNC会更有意义。 我将以以下两种方式之一编写FUNC

function out = FUNC(M, x, y, z, k)  % Accept k as an argument
  ...
end

function out = FUNC(M, x, y, z, theta0)  % Pass the initial guess, of the correct size
  ...
end

如果您真的想让FUNC做额外的工作,那么来自excaza的答案就是我将如何做。



下面的旧答案。 自问题得到澄清以来,它并不是真的有效,但是我暂时离开了...

我认为您在这里有两个更好的选择...

使M为匿名函数的单元格数组:

您可以使输入M为可能的匿名函数单元格数组 ,并使用theta中的值数作为索引。 您可以将此M传递给FUNC

M = {@(x,y,z,theta) z' * (y - x * theta), ...
     @(x,y,z,theta) z' * (y - (x * theta(1))^theta(2)), ...
     @(x,y,z,theta) z' * (y - (theta(1) + x * theta(2))^theta(3))};

然后在FUNC内部:

out = M{numel(theta)}(x, y, z, theta);

使M成为普通函数,而不是匿名函数:

匿名函数适用于快速,简单的公式。 添加条件逻辑,您可能应该使它成为一个成熟的函数 这是一个带switch语句的示例(如果您有许多不同的公式,则非常有用):

function out = M(x, y, x, theta)
  switch numel(theta)
    case 1
      out = z' * (y - x * theta);
    case 2
      out = z' * (y - (x * theta(1))^theta(2));
    case 3
      out = z' * (y - (theta(1) + x * theta(2))^theta(3));
  end
end

这是一个为参数设置一些默认值的示例(适用于如果您有一个公式用不同的方式设置其参数的公式,就像您看起来那样):

function out = M(x, y, x, theta)
  switch numel(theta)
    case 1
      p1 = 0;
      p2 = theta;
      p3 = 1;
    case 2
      p1 = 0;
      p2 = theta(1);
      p3 = theta(2);
    case 3
      p1 = theta(1);
      p2 = theta(2);
      p3 = theta(3);
  end
  out = z' * (y - (p1 + x * p2)^p3);
end

MATLAB不存储有关匿名函数输入大小的任何信息。 虽然一个更好的主意是修改代码,这样您就不必进行此类操练,但是如果您知道函数定义适合各种可能性,则可以使用正则表达式来解析函数定义本身。 您可以从functions返回中获取此字符串。

例如:

function [nelements] = findsizetheta(fh)
defstr = func2str(fh);
test = regexp(defstr, 'theta\((\d+)\)', 'tokens');

if isempty(test)
    % Assume we have theta instead of theta(1)
    nelements = 1;
else
    nelements = max(str2double([test{:}]));
end
end

返回12 ,和3为您的示例定义M

这假定theta存在于您的匿名函数中,并且已将其定义为向量。

还要注意,MATLAB告诫不要以编程方式使用functions ,因为其行为在以后的版本中可能会发生变化。 经过测试,可以在R2017b中运行。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM