如何计算Matlab中的双和,其中第二个和的上界是第一个和的下界?

时间:2017-06-20 12:46:17

标签: matlab performance sum vectorization memory-efficient

我在Matlab中实现一个函数很困难,该函数调用我在不同.m文件中编写的其他函数。我被卡住的部分是在另一个函数中输入不同值的和的部分,其中在另一个函数内部还有一个和。第一个和的下限是第二个和的上限。

功能是: doubleSum

我有Hh(n,x)函数正常工作,n作为向量输入,x作为标量输入。由于n的向量化输入,In函数内的Hi之和可以通过调用sum(Hh(0:n,x))快速计算。

我想对In函数做同样的事情,但是因为n in in现在的范围从0到k-1而外部函数k的范围从1到n,我不知道如何评估这个双和,其中内部总和具有外部和的下限作为上限。我想尽可能有效地评估这个双和,因为后来我想用这些公式做很多模拟。现在我正在评估函数n次,将每个值存储在一个向量中,然后取总和,这在计算上非常强烈...

In函数的我的Matlab代码是:

function in = In(n,c,alphaa,betaa, delta)
ie = 0:n;
in = -(exp(alphaa*c)/alphaa)...
     .*sum((betaa/alphaa).^(n-ie).*Hh(ie,betaa*c-delta))...
     -(betaa/alphaa).^(n+1)
end

外部函数的Matlab代码,让我们现在称它为函数f:

function f = F(n,a,mu,sigma,eta1,T)
for k = 1: n
    vector(k) =  In(k-1,a-mu*T,-eta1,-1/(sigma*sqrt(T)),-(sigma*eta1*sqrt(T)));
end
f = sum(vector);
end

如何在矢量化中输入n in,这样我就不必分别存储所有输入的n值然后计算总和,而是直接计算输入矢量n的和。

任何帮助都是值得赞赏的,因为我现在严重陷入困境!提前谢谢!

1 个答案:

答案 0 :(得分:0)

所以为了特别回答你的问题(n矢量化的输入),我会做以下几点:

%1。为每个k创建一个从0到k-1的向量ivect,以及对应于iterate ivect的向量kvect:

ivect=[];
kvect=[];
for k=1:n
    ivect = [ivect 0:k-1];
    kvect = [kvect (k-1)*ones(1,k)];
end

%2。创建两个和之内的函数,具体取决于你的迭代i和k:

    function in = In2(k,ie,c,alphaa,betaa, delta)
in = -(exp(alphaa*c)/alphaa)*((betaa/alphaa).^(k-ie).*func(ie,betaa*c-delta))-(betaa/alphaa).^(k+1)./(k+1);
end

%3。然后总结:

f=sum(In2(kvect,ivect,a-mu*T,-eta1,-1/(sigma*sqrt(T)),-(sigma*eta1*sqrt(T))))

起初我认为这种方法会减少计算总和的计算时间(当然,第1点是昂贵的,但可以做一次并用于多次模拟而无需重建这些向量),但即使只是比较线条:

tic
for k = 1: n
    vector(k) =  In(k-1,a-mu*T,-eta1,-1/(sigma*sqrt(T)),-(sigma*eta1*sqrt(T)));
end
f = sum(vector)
toc

tic
f=sum(In2(kvect,ivect,a-mu*T,-eta1,-1/(sigma*sqrt(T)),-(sigma*eta1*sqrt(T))))
toc

第一种方法获得1.029899秒,第二种方法获得1.684432秒,n = 5000.但幸运的是,我找到了原因!这是因为这个方法实际上产生了更多的艺术操作,就像函数In2一样,我要求我的代码计算 - (betaa / alphaa)。^(k + 1)./(k + 1)表示每个k和我,虽然这个词只取决于k。所以现在,让我们定义函数In3和In4:

function in = In3(k,ie,c,alphaa,betaa, delta)
in = -(exp(alphaa*c)/alphaa)*((betaa/alphaa).^(k-ie).*Hh(ie,betaa*c-delta));    end

function in = In4(k,alphaa,betaa)
    in=-(betaa/alphaa).^(k+1);
end

并致电

tic
f=sum(In3(kvect,ivect,a-mu*T,-eta1,-1/(sigma*sqrt(T)),-(sigma*eta1*sqrt(T)))) +sum(In4([1:n],-eta1,-1/(sigma*sqrt(T))))
toc

瞧,我在0.929530秒内获得了相同的结果,N = 5000。总而言之,你在这最后一种方法上获得了一些时间,但为了完全公平,我会说你有两个缺点:

  1. 开始时ivect和kvect的时间计算 - 但我坚持认为这些向量可以构造一次,存储并用于多次模拟 -

  2. 内存成本:ivect和kvect的大小为n(n + 1)/ 2,对于大n来说是很多

  3. 希望它对你有所帮助,无论如何,感谢有趣的问题,这可能会在我自己的研究中为我服务!