【问题标题】:Create flexible function handle创建灵活的函数句柄
【发布时间】:2014-10-23 19:41:21
【问题描述】:

我在 MATLAB 中使用数值积分,使用一个变量进行积分,但该函数还包含可变数量的项,具体取决于我的数据维度。现在这对于二维情况如下所示:

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);

我希望这是可以理解的。

【问题讨论】:

    标签: matlab loops function-handle


    【解决方案1】:

    如果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 函数的编写方式时,积分节点作为数组值函数的标量输入,因此除非引发一些奇怪的维度不匹配错误,否则不需要循环。



    数组值输出

    针对下面的cmets,你可以试试这个函数句柄:

    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
    

    ArrayValued 标志是必需的,因为 xu 将存在维度不匹配。 在这种形式中,需要另一个循环来扫描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
    

    【讨论】:

    • 感谢您的努力,我刚刚意识到我上面的代码是错误的,第一个 x(t,2) 必须更改为 x(t,1) - 所以基本上这个函数是不同数字的不同术语,每一个都包含不同的 x。
    • 不同的x 还是只是不同的索引?例如,它是否总是 x(t,i) 和 x(t,i-1)?
    • x 是维度 TK 的矩阵,对于每个 t/row,我希望有涉及所有列的函数,所以我上面的例子是 K = 2,但 x 可能有任何维度。对于 K = 3,我想最终得到: exp(-0.5*(x(t,1) - thetanorminv(u,0,1)).^2) .* exp(-0.5* (x(t,2) - thetanorminv(u,0,1)).^2)*exp(-0.5*(x(t,3) - thetanorminv(u,0, 1)).^2).*;
    【解决方案2】:

    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 = 积分计算(fun,a,b,opstruct);

    【讨论】:

    • 我已经用两种不同的方法更新了答案,考虑到您在此处的示例输入,这两种方法应该可以工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-05-09
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多