如何通过嵌套函数为MATLAB的integral2提供参数向量?

时间:2015-06-24 16:30:55

标签: arrays matlab function vector

我想在MATLAB中计算参数向量的二维积分。我知道integral2没有'ArrayValued'选项。如何重新排列函数句柄以反馈行向量q? 1D集成工作正常:

    clear all

    L=1000;
    R=80;

    formfactor = @(q,alpha) 2*sin(q.*cos(alpha)*L/2)./(q.*cos(alpha)*L/2).*besselj(1,q.*sin(alpha)*R)./(q.*sin(alpha)*R);
    result = @(q) integral(@(alpha) formfactor(q,alpha).^2.*sin(alpha),0,pi/2,'ArrayValued',true);

    qbins = 100;
    q = logspace(-2,0,qbins);
    I = result(q);

到此为止,alpha的一维整合有效。现在我将被积函数与术语lattice_c相乘,后者另外依赖于phi并尝试再次集成。

    a = 24;
    b = a*sqrt(3)/2;
    x=[-2.5*a, -2*a, -a, -a/2, a/2, a, 2*a, 2.5*a, 2*a, 2.5*a, 2*a, a, a/2, -a/2, -a, -2*a, -2.5*a, -2*a, -a, -a/2, a/2, a, a/2, -a/2 ];
    y=[b ,2*b ,2*b ,3*b ,3*b ,2*b ,2*b ,b ,0 ,-b ,-2*b ,-2*b ,-3*b ,-3*b ,-2*b ,-2*b ,-b ,0 ,0 ,b ,b ,0 ,-b ,-b ];

    lattice_a = @(q,position,alpha,phi) exp(sqrt(-1)*q*(x(position)*sin(alpha)*cos(phi) + y(position)*sin(alpha)*sin(phi)));
    lattice_b = @(q,alpha,phi) sum(lattice_a(q,:,alpha,phi));
    lattice_c = @(q,alpha,phi) formfactor(q,alpha).*lattice_b(q,alpha,phi);
    lattice_d = @(q) integral2(@(alpha,phi) lattice_c(q,alpha,phi).^2.*sin(alpha),0,pi/2,0,pi/3);

    Inew = lattice_d(q);

    figure()
    loglog(q,I)

错误消息是“使用错误。* Matrix尺寸必须同意。”但从技术上讲,没有涉及矩阵,因为这些参数都不再是数组值。我需要以不同的方式传递什么论据?

1 个答案:

答案 0 :(得分:0)

  

但从技术上讲,没有涉及矩阵

有。 integral2的文档指定了正在集成的函数

  

必须接受两个相同大小的数组并返回一个对应值的数组。它必须执行逐元素操作。

也就是说,integral2将一些大小相同的数组alphaphi传递给函数lattice_c。这会立即中断sin(alpha)*cos(phi) - 您需要.*

但这不是故事的结尾,因为你也希望将它乘以x。你引入位置参数然后将:传递给它的想法似乎没有帮助(至少在我的R2013a中,:作为函数参数的效果既没有记录也没有给我清楚)。

如果没有集成,您可以检查lattice_b(-1,0:1,0:1)是否会抛出错误:函数无法处理数组参数。

大多数这些问题的根本原因是你在匿名函数中填充了太多逻辑。这是我的重写:我将lattice_b分开,将lattice_a折叠到其中。由于存在非匿名函数,我将顶级代码包装到函数main中。

哦,q的条目应该一次处理一个,for循环是完全合适的。尝试对复杂的操作进行矢量化是没有意义的,例如双积分的评估(我解释了为什么elsewhere)。

function main()
clear all
L=1000;
R=80;
formfactor = @(q,alpha) 2*sin(q.*cos(alpha)*L/2)./(q.*cos(alpha)*L/2).*besselj(1,q.*sin(alpha)*R)./(q.*sin(alpha)*R);
result = @(q) integral(@(alpha) formfactor(q,alpha).^2.*sin(alpha),0,pi/2,'ArrayValued',true);
lattice_c = @(q,alpha,phi) formfactor(q,alpha).*lattice_b(q,alpha,phi);
lattice_d = @(q) integral2(@(alpha,phi) lattice_c(q,alpha,phi).^2.*sin(alpha),0,pi/2,0,pi/3);

qbins = 100;
q = logspace(-2,0,qbins);
Inew = zeros(size(q));
for i=1:numel(q)
    Inew(i) = lattice_d(q(i));
end
disp(Inew)
end

function z = lattice_b(q,alpha,phi)
a = 24;
b = a*sqrt(3)/2;
x=[-2.5*a, -2*a, -a, -a/2, a/2, a, 2*a, 2.5*a, 2*a, 2.5*a, 2*a, a, a/2, -a/2, -a, -2*a, -2.5*a, -2*a, -a, -a/2, a/2, a, a/2, -a/2 ];
y=[b ,2*b ,2*b ,3*b ,3*b ,2*b ,2*b ,b ,0 ,-b ,-2*b ,-2*b ,-3*b ,-3*b ,-2*b ,-2*b ,-b ,0 ,0 ,b ,b ,0 ,-b ,-b ];
z = 0;
for i=1:numel(x)
    z = z + exp(sqrt(-1)*q*(x(i)*sin(alpha).*cos(phi) + y(i)*sin(alpha).*sin(phi)));
end
end