MatLab - 给定条件下的数值积分 - 来自Mathematica的翻译

时间:2013-12-06 14:39:13

标签: matlab integration numerical

这不想在 Mathematica 中为我工作 - 我不知道为什么不呢。它通常会给我0,但有时也会给我一个不同的数字。我知道它应该是一个很小的非零数字。

有人能帮我翻译成 MatLab 吗?我是该计划的新手,如果有经验的人可以帮助我开始,那将节省我的时间。

myO[e1_, e2_] := (e1)/((e1) + (e2));
myU[e1_, e2_] := (1 - e2)/((1 - e1) + (1 - e2));
myV[p_, e1_, e2_] := p (e1)/(p (e1) + (1 - p) (1 - e2));
myW[p_, e1_, e2_] := p (1 - e1)/(p (1 - e1) + (1 - p) e2);

NIntegrate[ Boole[0 < e1 < e2 < 1/2 && 0 < e3 < 1/2 && e1 < p < 1 - e1 && 
                  e3 < myV[p, e1, e2] < 1 - e3 < myW[p, e1, e2] && 
                  myO[e1, e2] < e3 < myU[e1, e2]], 
                 {p, 0, 1}, {e1, 0, 1/2}, {e2, 0, 1/2}, {e3, 0, 1/2}]

对于那些不熟悉 Mathematica 的人,如果符合条件,则Boole只提供1,否则提供0。因此,我希望整合所有参数空间,以找到满足条件的子空间的体积。

2 个答案:

答案 0 :(得分:1)

这是另一次尝试,这次是使用Monte Carlo integration。积分限制内的值是随机生成的,在这些点评估函数,积分估计为“命中”的分数乘以积分区域的总体积。

我已经实现了它,以便以1000万个块的形式生成随机数,并且针对每个块迭代地更新估计。该函数永远运行,并且一旦估计值足够精确就应该停止。

运行几分钟后,积分值似乎接近0.001775。

function LauBo2

myO = @(e1, e2) e1 ./ (e1 + e2);
myU = @(e1, e2) (1 - e2) ./ (2 - e1 - e2);
myV = @(p, e1, e2) p .* e1 ./ (p .* e1 + (1 - p) .* (1 - e2));
myW = @(p, e1, e2) p .* (1 - e1) ./ (p .* (1 - e1) + (1 - p) .* e2);

    function I = integrand(p, e1, e2, e3)
        I = double(e3 < myV(p, e1, e2)) .* (myV(p, e1, e2) < 1 - e3) .* ...
            (1 - e3 < myW(p, e1, e2)) .* (myO(e1, e2) < e3) .* ...
            (e3 < myU(e1, e2)) .* (e1 < p) .* ( p < 1 - e1) .* (e1 < e2);
    end

n = 10000000;
S = 0;
N = 0;
while true
    p = rand(n, 1);         % p from 0 1
    e1 = 0.5 * rand(n, 1);  % e1 from 0 to 0.5
    e2 = 0.5 * rand(n, 1);  % e2 from 0 to 0.5
    e3 = 0.5 * rand(n, 1);  % e3 from 0 to 0.5

    S = S + mean(integrand(p, e1, e2, e3));
    N = N + 1;

    I = S / N  * 1 * 0.5 * 0.5 * 0.5;
    fprintf('%.20f\n', I)
end

end

答案 1 :(得分:0)

我相信这应该是你想要的。它不是很优雅,Matlab并不是真的为此做的。我打破了你的条件(Matlab不支持x&lt; y&lt; z),消除了那些带有积分限制的冗余,并将其他变换为变化的积分限制。嵌套积分由一系列函数实现,这些函数评估一个积分并作为下一个积分。 for循环是必要的,因为integral期望给定的函数被矢量化。

我不能告诉你是否有一些明智的事情,因为计算需要很长时间,而且我没有耐心等待它完成。

function I = LauBo

myO = @(e1, e2) e1 ./ (e1 + e2);
myU = @(e1, e2) (1 - e2) ./ (2 - e1 - e2);
myV = @(p, e1, e2) p .* e1 ./ (p .* e1 + (1 - p) .* (1 - e2));
myW = @(p, e1, e2) p .* (1 - e1) ./ (p .* (1 - e1) + (1 - p) .* e2);

    function I = first(p, e1, e2, e3)
        % integrand
        I = double(e3 < myV(p, e1, e2)) .* (myV(p, e1, e2) < 1 - e3) .* ...
            (1 - e3 < myW(p, e1, e2)) .* (myO(e1, e2) < e3) .* (e3 < myU(e1, e2));
    end

    function I = second(e1, e2, e3)
        % integrate over  p   from e1 to (1 - e1)
        I = nan(size(e1));
        for i = 1 : numel(e1)
            I(i) = integral(@(p) first(p, e1(i), e2, e3), e1(i), 1 - e1(i));
        end
    end

    function I = third(e2, e3)
        % integrate over  e1  from 0 to e2
        I = nan(size(e2));
        for i = 1 : numel(e2)
            I(i) = integral(@(e1) second(e1, e2(i), e3), 0, e2(i));
        end
    end

    function I = fourth(e3)
        % integrate over  e2  from 0 to 0.5
        I = nan(size(e3));
        for i = 1 : numel(e3)
            I(i) = integral(@(e2) third(e2, e3(i)), 0, 0.5);
        end
    end

% integrate over  e3  from 0 to 0.5
I = integral(@fourth, 0, 0.5);

end