[英]How to determine the size of an input argument for a function handle
I am creating a function that takes in data ( x,y,z
) and an anonymous function ( M
) as inputs. 我正在创建一个将数据( x,y,z
)和一个匿名函数( M
)作为输入的函数。 M
's inputs are data ( x,y,z
) and a parameter ( theta
). M
的输入是数据( x,y,z
)和一个参数( theta
)。
I need to determine the dimension of the parameter theta
inside FUNC
我需要确定FUNC
内参数theta
的尺寸
EDIT: (To add some context) 编辑:(添加一些上下文)
I have data that follows a known data generating process (DGP). 我有遵循已知数据生成过程(DGP)的数据。 For example, I can generate data using a linear instrumental variable DGP with 1 endogenous variable (hence theta
will be dimension 1): 例如,我可以使用具有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
Then I want to estimate theta0
using my own variation of generalized linear methods ( FUNC
) 然后我想使用我自己的广义线性方法( FUNC
)的变化来估计theta0
M = @(x,y,z,theta) z' * (y - x * theta); % moment condition
thetahat = FUNC(M, x, y, z); % estimate theta0
and FUNC.m
is 和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
In the above example, the DGP is a linear IV model. 在上面的示例中,DGP是线性IV模型。 However, I should be able to use my function for any other DGP. 但是,我应该可以将我的函数用于任何其他DGP。
Other DGPs could, for example, define M
as follows: 例如,其他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));
The (super bad) hack that I am currently using for (!!!)
is: 我当前用于(!!!)
的(超级坏)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
Since you know already what the form and requirements of your function M
will be when you pass it to FUNC
, it doesn't make much sense to then require FUNC
to determine it based only on M
. 因为您已经知道将函数M
传递给FUNC
时函数M
的形式和要求,所以仅要求FUNC
根据M
确定函数就没有多大意义。 It would make much more sense to pass flag values or needed information to FUNC
when you pass it M
. 当将其传递给M
时,将标志值或所需的信息传递给FUNC
会更有意义。 I would write FUNC
in one of two ways: 我将以以下两种方式之一编写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
If you really want to let FUNC
do the extra work, then the answer from excaza is how I would do it. 如果您真的想让FUNC
做额外的工作,那么来自excaza的答案就是我将如何做。
Old answer below. 下面的旧答案。 not really valid since the question was clarified, but I'm leaving it temporarily... 自问题得到澄清以来,它并不是真的有效,但是我暂时离开了...
I think you have two better options here... 我认为您在这里有两个更好的选择...
M
a cell array of anonymous functions: 使M
为匿名函数的单元格数组: You could make your input M
a cell array of possible anonymous functions and use the number of values in theta
as the index. 您可以使输入M
为可能的匿名函数的单元格数组 ,并使用theta
中的值数作为索引。 You would pass this M
to FUNC
: 您可以将此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))};
Then somewhere inside FUNC
: 然后在FUNC
内部:
out = M{numel(theta)}(x, y, z, theta);
M
a normal function instead of an anonymous one: 使M
成为普通函数,而不是匿名函数: An anonymous function is good for quick, simple formulas. 匿名函数适用于快速,简单的公式。 Add in conditional logic and you should probably just make it a fully-fledged function . 添加条件逻辑,您可能应该使它成为一个成熟的函数 。 Here's an example with a switch statement (good for if you have a number of different formulas): 这是一个带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
And here's an example that sets some defaults for parameters (good for if you have one formula with different ways to set its parameters, like you seem to have): 这是一个为参数设置一些默认值的示例(适用于如果您有一个公式用不同的方式设置其参数的公式,就像您看起来那样):
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 doesn't store any information about the size of the inputs to an anonymous function. MATLAB不存储有关匿名函数输入大小的任何信息。 While a better idea would be to modify your code so you don't have to do these kinds of gymnastics, if your function definition is known to fit a narrow band of possibilities you could use a regular expression to parse the function definition itself. 虽然一个更好的主意是修改代码,这样您就不必进行此类操练,但是如果您知道函数定义适合各种可能性,则可以使用正则表达式来解析函数定义本身。 You can get this string from the return of functions
. 您可以从functions
返回中获取此字符串。
For example: 例如:
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
Which returns 1
, 2
, and 3
for your example definitions of M
. 返回1
, 2
,和3
为您的示例定义M
。
This assumes that theta
is present in you anonymous function and that it is defined as a vector. 这假定theta
存在于您的匿名函数中,并且已将其定义为向量。
Also note that MATLAB cautions against utilizing functions
in a programmatic manner, as its behavior may change in future releases. 还要注意,MATLAB告诫不要以编程方式使用functions
,因为其行为在以后的版本中可能会发生变化。 This was tested to function in R2017b. 经过测试,可以在R2017b中运行。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.