2012-12-06 53 views
1

X,Y和z是表示表面的坐标。为了计算一些数量,让我们称它为流动,在点i,j的曲面上,我需要从所有其他点(i0,j0)计算contibution。要做到这一点,我需要例如知道点i0,j0和所有其他点(alpha)之间角度的cos。然后,所有来自i0,j0的组合必须在一些常数上相乘并相加。 zv0在每一点我,j是最终需要的结果。用于循环矢量化和存储器的Matlab

我想出了一些下面写的代码,它似乎是非常不合适的。首先它会减慢程序的其余部分,并且似乎使用所有可用内存。我的系统有4GB物理内存和12GB交换文件,并且它总是用尽内存,尽管所有变量大小都不会大于10kb。请帮助加速/矢量化和内存问题。

parfor i0=2:1:length(x00); 
    for j0=2:1:length(y00); 
    zv=red3dfunc(X0,Y0,f,z0,i0,j0,st,ang,nx,ny,nz); 
    zv0=zv0+zv; 
    end 
end 


function[X,Y,z,zv]=red3dfunc(X,Y,f,z,i0,j0,st,ang,Nx,Ny,Nz) 
x1=X(i0,j0); 
y1=Y(i0,j0); 
z1=z(i0,j0); 
alpha=zeros(size(X)); 
betha=zeros(size(X)); 
r=zeros(size(X)); 
XXa=X-x1; 
YYa=Y-y1; 
ZZa=z-z1; 
VEC=((XXa).^2+(YYa).^2+(ZZa).^2).^(1/2); 
VEC(i0,j0)=VEC(i0-1,j0-1); 
XXa=XXa./VEC; 
YYa=YYa./VEC; 
ZZa=ZZa./VEC; 
alpha=-(Nx(i0,j0).*XXa+Ny(i0,j0).*YYa+Nz(i0,j0).*ZZa); 
betha=Nx.*XXa+Ny.*YYa+Nz.*ZZb; 
r=VEC; 
zv=(1/pi)*st^2*ang.*f.*(alpha).*betha./r.^2; 
+0

'x00'和'y00'有多大? – HerrKaputt

+0

使得X0 = meshgrid(x00,y00)。如果你需要数字,他们至少50 – user1364012

回答

3

这样做的显而易见的事情是使用Kroneker产品。 matlab函数是kron(A,B),用于尺寸为nAxmA和nBxmB的矩阵。这个函数会返回维度的矩阵(NA * NB)×(毫安* MB),它看起来像

[a11*B a12*B ... a1mA*B; 
.......................; 
anA1*B ........ anAmA*B] 

所以你的问题可以通过引入那些I =一(大小的矩阵来解决(X ))。然后,您将定义XXA,YYA,ZZA和VEC matricies没有任何环路

XXa = kron(I,X)-kron(X,I); 
YYa = kron(I,Y)-kron(Y,I); 
ZZa = kron(I,Z)-kron(Z,I); 
VEC=((XXa).^2+(YYa).^2+(ZZa).^2).^(1/2); 

然后您将找到VEC任何I0,J0为(如果定义n和m为X的大小部件)

VEC((1+n*(i0-1)):(n*i0),(1+m*(j0-1)):(m*j0)) 
+0

可靠的答案。我肯定会尝试 – user1364012

+0

我试图使用这种方法,它太糟糕了,它的工作速度甚至比循环更慢 – user1364012

+0

这是一种悲伤。我唯一能推荐给你的是使用repmat(X,size(X))而不是kron(I,X)。也许这会提高一点速度。 – Krivoi