我正在创建一个将数据(x,y,z
)和匿名函数(M
)作为输入的函数。 M
的输入是数据(x,y,z
)和参数(theta
)。
我需要确定theta
FUNC
的维度
编辑:(添加一些上下文)
我的数据遵循已知的数据生成过程(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
然后我想用我自己的广义线性方法变体估算theta0
(FUNC
)
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));
我目前用于(!!!)
的(超级糟糕)黑客是:
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
答案 0 :(得分:2)
由于您已将函数M
的形式和要求传递给FUNC
时已经知道了什么,因此要求FUNC
没有多大意义仅根据M
确定它。传递标记值或所需信息时,将FUNC
传递给M
会更有意义。我会用两种方式之一写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
做额外的工作,那么the answer from excaza就是这样做的。
下面的旧答案。因问题得到澄清而无法真正有效,但我暂时离开了......
我认为你在这里有两个更好的选择......
M
成为匿名函数的单元格数组:您可以将输入M
设为cell array anonymous functions,并使用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
成为普通函数而不是匿名函数:anonymous function适用于快速简单的公式。添加条件逻辑,您应该只是使它成为一个完全成熟的function。这是一个带有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
答案 1 :(得分:1)
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
对于1
的示例定义,返回2
,3
和M
。
这假设您的匿名函数中存在theta
,并且它被定义为向量。
另请注意,MATLAB警告不要以编程方式使用functions
,因为其行为可能会在将来的版本中发生变化。测试其在R2017b中起作用。