我写了一些代码,但我的程序太慢了。问题如下:
我将构建Matrix“A”来解决Ax = b问题
我有一个球体(可能是任何形状),有点显示,
我为每个点分配了一个坐标向量[x y z]。
N是分数。
请先加载(a)
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)
我不知道我能解释清楚吗?
你有什么建议吗? 提前感谢任何建议。
geometrySphere 我是3x3单位矩阵,nij nij表示二元乘积。
(a)运行函数后:an 1x200 array
答案 0 :(得分:2)
前两个循环可以通过以下向量操作轻松替换(我还没有测试过):
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)));
请注意,在您的情况下,dx
,dy
和dz
将是具有零对角线的偏斜对称矩阵,因此只有N(N-1)/2
个独立元素。这种配对可以通过combnk
实现,它可以提供n
个项目中所有可能的对。因此,d
这里是N(N-1)/2x3
元素数组,而您的d
是NxNx3
数组,但包含相同的信息。
现在主循环看起来也可以被矢量化,但是它太长了,我不想花时间浏览所有索引。但这里有一些建议:
.
前缀在MATLAB中执行元素操作。因此,如果您有两个等维数组/向量,例如A=[a b c]
和B=[d e f]
(假设为实数),则两个向量的点积只是A.*B
,它给出[ad be cf]
}。划分和提升权力的类似规则。您可以阅读更多相关信息here。*
运算符(此处没有点)进行矩阵乘法,并且内部维度必须匹配。因此,使用上面的示例,内部产品只是A*B'
,它为您提供ad+be+cf
,外部产品(并列产品)为A'*B
,为您提供3x3
矩阵:[ad ae af;bd be bf;cd ce cf]