Matlab 加速“for”循环或将其矢量化

Matlab 加速“for”循环或将其矢量化,matlab,vectorization,Matlab,Vectorization,我已经写了一些代码,但是我的程序太慢了。问题如下: 我将构建矩阵“A”来解决Ax=b问题 我有一个球体(可以是任何形状),由某个点显示 我为每个点指定了一个坐标向量[x y z] N是点数 请先装(a) 我不知道我能解释清楚吗 你有什么建议吗? 提前感谢您的建议 其中I是3x3单位矩阵,nij nij表示并矢积。 (a) 运行函数后是:前两个循环可以很容易地替换为以下向量操作(我没有测试它): 注意,在您的例子中,dx、dy和dz将是斜对称矩阵,对角线为零,因此只有N(N-1)/2独立元素。

我已经写了一些代码,但是我的程序太慢了。问题如下:

我将构建矩阵“A”来解决Ax=b问题

我有一个球体(可以是任何形状),由某个点显示

我为每个点指定了一个坐标向量[x y z]

N是点数

请先装(a)

我不知道我能解释清楚吗

你有什么建议吗? 提前感谢您的建议

其中I是3x3单位矩阵,nij nij表示并矢积。


(a) 运行函数后是:

前两个循环可以很容易地替换为以下向量操作(我没有测试它):

注意,在您的例子中,
dx
dy
dz
将是斜对称矩阵,对角线为零,因此只有
N(N-1)/2
独立元素。此配对可以通过
combnk
实现,它提供了
n
项中所有可能的配对。因此,这里的
d
N(N-1)/2x3
元素数组,而
d
NxNx3
数组,但包含相同的信息

现在主循环看起来也可以矢量化,但是它太长了,我不想花时间浏览所有的索引。但这里有一些建议:

  • 您可以在MATLAB中使用运算符前面的
    前缀执行元素操作。因此,如果你有两个等维数组/向量,比如
    A=[abc]
    b=[def]
    (假设为实),两个向量的点积就是
    A.*b
    ,这就给出了
    [ad be cf]
    。类似的划分规则,并将其提升为一个权力。你可以阅读更多关于它的内容
  • 您可以使用
    *
    运算符(此处无点)进行矩阵乘法,并且内部尺寸必须匹配。因此,在上面的例子中,内积只是
    A*B'
    ,它给你
    ad+be+cf
    ,而外积(并矢积)是
    A'*B
    ,它给你一个
    3x3
    矩阵:
    [ad-ae-af;bd-be-bf;cd-ce-cf]

  • 我不明白你在上面等式中的符号
    n_ij n_ij
    不能是二元产品。它相当于
    n
    矩阵的元素平方。你的意思是写不同的
    n
    s,比如
    nux
    nuy
    ?即使这样,符号还是很混乱。@yoda:好的,谢谢你的提醒。@yada:nx,ny和nz是单位向量的x,y和z分量的NxN矩阵。nn为每个i&j构造一个3x3矩阵。n=cat(3,nx,ny,nz),我认为它在运行时不会出现错误-当n为1000或更多时,它真的很耗时。我认为邮件循环可以用你的代码矢量化,我正在处理它。谢谢尤达!
    clc 
    [rv,N,d0]=geometrySphere(5e-9,10);         %#  Nx3 matrix [x1 y1 z1;x2 y2 z2;... ].
    
    %# geometrySphere is a function for replacicg the sphere with points.
     L=(301:500)*1e-9;  K=2*pi./L;                   %# 1x200 array 
     %some constants ==================
     I=eye(3);
     e0=1;
     V=N*d0^3; aeq=(3*V/(4*pi))^(1/3);
     E0y=ones(N,1);
     E0z=E0y;
     Cext=zeros(1,200);
     Qext=zeros(1,200);
     A=zeros(3,3,N^2);
     %=================================
    for i=1:N
        r(i)=sqrt(rv(i,1)^2+rv(i,2)^2+rv(i,3)^2);    %# r is the size of each vector 
    end
    for i=1:N
        for j=1:N
            dx(i,j)=rv(i,1)-rv(j,1); %# The x component of distance between each 2 point
            dy(i,j)=rv(i,2)-rv(j,2);
            dz(i,j)=rv(i,3)-rv(j,3);
        end
    end
    d=cat(3,dx,dy,dz);  %# d is the distance between each 2 point (a 3D matrix)
    nd=sqrt(dx.^2+dy.^2+dz.^2);                     %# Norm of rv vector
    nx=d(:,:,1)./nd; ny=d(:,:,2)./nd; nz=d(:,:,3)./nd;
    n=cat(3,nx,ny,nz);                              %# Unit vectors for points that construct my sphere
    
    
     for s=1:length(L)
        E0x=exp(1i*K(s)*rv(:,1))';                   
        % 1x200 array  in direction of x(in Cartesian coordinate system)
        % Main Loop    =================================================
        p=1;                                                        
        for ii=1:N                                                  
            for jj=1:N                                              
                if ii==jj                                           
                    A(:,:,p)=a(s)*eye(3);           %# 3x3 , a is a 1x200 constant array                        
                    p=p+1;                          %# p is only a counter              
                else                                                
                A(:,:,p)=-exp(1i*K(s)*nd(ii,jj))/nd(ii,jj)*(-K(s)^2*([nx(ii,jj);ny(ii,jj);nz(ii,jj)]... 
                    *[nx(ii,jj) ny(ii,jj) nz(ii,jj)]-I)+(1/nd(ii,jj)^2-1i*K(s)/nd(ii,jj))...             
                    *(3*[nx(ii,jj);ny(ii,jj);nz(ii,jj)]*[nx(ii,jj) ny(ii,jj) nz(ii,jj)]-I));             
                p=p+1;          
                end                                             
            end                                                 
        end                                                     
    
    %===============================================================
    B = reshape(permute(reshape(A,3,3*N,[]),[2 1 3]),3*N,[]).';
    %# concatenation of N^2 3x3 matrixes into a 3Nx3N matrix
        for i=1:N
            E00(:,i)=[E0x(i) E0y(i) E0z(i)]';
        end
        b=reshape(E00,3*N,1);
        P=inv(B)*b;
        Cext(s)=(4*pi*K(s))*imag(b'*P);
        Qext(s)=Cext(s)/(pi*aeq^2);
     end
    
    Qmax=max(Qext); Qext=Qext/Qmax;
    L=L*1e9;
    plot(L,Qext,'--');figure(gcf)
    
    r=sqrt(sum(rv,2).^2);
    [npoints,ndims]=size(rv);
    pairs=combnk(1:npoints,2);
    npairs=size(pairs,1);
    
    index=repmat(pairs(:),ndims,1)+npoints*reshape(repmat(0:ndims-1,npairs*2,1),npairs*2*ndims,1);
    d=reshape(reshape(rv(index),npairs*ndims,2)*[1 -1]',npairs,ndims);           %'
    n=bsxfun(@rdivide,d,sqrt(sum(d.^2,2)));