创建灵活的功能句柄

时间:2014-10-23 19:41:22

标签: matlab loops function-handle

我在MATLAB中使用数值积分,有一个varibale要集成,但函数还包含可变数量的术语,具体取决于我的数据维度。现在,对于二维情况,这看起来如下:

for t = 1:T  
   fxt = @(u)  exp(-0.5*(x(t,1)-theta*norminv(u,0,1)).^2) .* ...
         exp(-0.5*(x(t,2) -theta*norminv(u,0,1)).^2);
   f(t) = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3); 
end

我希望这个功能具有灵活性,因为在下一个术语中可以有任意数量的数据点:

exp(-0.5*(x(t,i) -theta*norminv(u,0,1)).^2);

我希望这是可以理解的。

2 个答案:

答案 0 :(得分:0)

如果xu具有减法的有效维度匹配(矢量矢量或数组标量),则可以将整个矩阵x放入句柄并传递给它使用名称 - 参数对(integral'ArrayValued')到true函数:

fxt = @(u)  exp(-0.5*(x - theta*norminv(u,0,1)).^2) .* ...
            exp(-0.5*(x - theta*norminv(u,0,1)).^2);
f   = integral(fxt,1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);

[Documentation]

如果integral将向量u传递到句柄中,则可能需要循环。 但是在查看如何编写integral函数时,集成节点作为数组值函数的标量输入,因此除非抛出一些奇怪的维度不匹配错误,否则不需要循环。



数组值输出

在回复以下评论时,您可以尝试使用此功能句柄:

fx = @(u,t,k)  prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);

然后你的当前循环看起来像

fx = @(u,t,k) prod(exp(-0.5*(x(t,1:k)-theta*norminv(u,0,1)).^2),2);
k  = 2;
for t = 1:T
  f(t) = integral(@(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);
end

由于ArrayValuedx维度不匹配,因此需要u标记。 在这种形式中,需要另一个循环来扫描k索引。 但是,我们可以通过完全跳过循环来改进此函数,因为循环的每个迭代都是使用ArrayValued模式独立的:

fx = @(u,k) prod(exp(-0.5*(x(:,1:k)-theta*norminv(u,0,1)).^2),2);
k  = 2;
f  = integral(@(u)fx(u,k),1e-4,1-1e-4,'AbsTol',1e-3,'ArrayValued',true);


矢量值输出

如果不需要ArrayValued,如果集成需要大量细分并且矢量值u更可取,则可能是这种情况,您也可以尝试使用递归版本的句柄单元格数组:

% x has size [T,K]
fx = cell(K,1);
fx{1} = @(u,t) exp(-0.5*(x(t,1) - theta*norminv(u,0,1)).^2);
for k = 2:K
    fx{k} = @(u,t) fx{k-1}(u,t).*exp(-0.5*(x(t,k) - theta*norminv(u,0,1)).^2);
end

f(T) = 0;
k    = 2;
for t = 1:T
    f(t) = integral(@(u)fx{k}(u,t),1e-4,1-1e-4,'AbsTol',1e-3);
end

答案 1 :(得分:0)

ThanksTroy但现在我遇到了以下内容:

x = [0.3,0.8;1.5,-0.7];
T = size(x,1);
k  = size(x,2);
theta= 1;
fx = @(u,t,k) prod(exp(-0.5*(x(t,1:k) - theta*norminv(u,0,1))^2));
for t = 1,T
  f(t) = integral(@(u)fx(u,t,k),1e-4,1-1e-4,'AbsTol',1e-3);
end

使用时出错 - 矩阵维度必须一致。

@(u,t,k)prod中的错误(exp(-0.5 *(x(t,1:k)-theta * norminv(u,0,1))^ 2))

@(u)fx(u,t,k)中的错误

integralCalc / iterateScalarValued中的错误(第314行)                 fx = FUN(t);

integralCalc / vadapt出错(第133行)             [q,errbnd] = iterateScalarValued(u,tinterval,pathlen);

integralCalc出错(第76行)         [q,errbnd] = vadapt(@ AtoBInvTransform,interval);

积分误差(第89行) Q = integralCalc(fun,a,b,opstruct);