簡體   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