Matlab矢量化方程和矩阵乘法

时间:2014-04-30 03:49:47

标签: matlab matrix vectorization matrix-multiplication

我有一个程序,当前使用for循环来迭代一组函数。我尝试过使用parfor,但这只适用于大学的Matlab版本。我想对它的处理进行矢量化处理,这样就不需要for循环了。使用的等式I基本上调用不同类型的贝塞尔函数并且包含在单独的函数中。

以下是我要做的事情: 对于m的每个值,为每个所需矩阵构建矩阵元素的向量。然后构建每个完整矩阵。我认为这是正常的。

它抛出错误的地方是最终矩阵乘法...即使我只是将左2x2乘以中间2x2我也得到了可怕的错误:

???使用==>时出错mtimes 内部矩阵尺寸必须一致。 ==>中的错误@(米)CL(M)* CM(M)* CR(米)

% Vector for summation. 1 row, 301 columns with data from 0->300
m_max=301;
m=[0:m_max-1];

% Build the 300 elements for the left 2x2 matrix.
CL_11=@(m) H1(m,alpha1);
CL_12=@(m) H2(m,alpha1);
CL_21=@(m) n1*dH1(m,alpha1);
CL_22=@(m) n1*dH2(m,alpha1);

% Build the 300 elements for the middle 2x2 matrix.
CM_11=@(m) n1*dH2(m,alpha2);
CM_12=@(m) -1*H2(m,alpha2);
CM_21=@(m) -1*n1*dH1(m,alpha2);        
CM_22=@(m) H1(m,alpha2);

% Build the 300 elements for the right 2x1 matrix.
CR_11=@(m) J(m,alpha3);
CR_21=@(m) n2*dJ(m,alpha3);

% Build the left (CL), middle (CM) and right (CR) matrices.
CL=@(m) [CL_11(m) CL_12(m);CL_21(m) CL_22(m)];
CM=@(m) [CM_11(m) CM_12(m);CM_21(m) CM_22(m)];
CR=@(m) [CR_11(m);CR_21(m)];

% Build the vector containing the products of each triplet of
% matrices. 
C=@(m) CL(m)*CM(m)*CR(m);
cl=CL(m)
cm=CM(m)
cr=CR(m)

c=CL(m)*CM(m)*CR(m)

如果您有任何建议或建议,我们非常感谢!我仍然是Matlab的新手,我正在尝试使用矩阵和向量来开发更高水平的能力。

谢谢!

2 个答案:

答案 0 :(得分:3)

你的矩阵不是2x2。使用CL_11(m) 1x300向量进行m时,CL_11(m)也将为1x300。因此CL(m)是2x301。要解决这个问题,你必须逐个计算矩阵。这里有两种方法。

c=arrayfun(C,m,'UniformOutput',false)

将返回一个单元格数组,因此c{1}对应m(1)c{2}对应m(2)等。

另一方面,你可以做到

for i=1:m_max
    c(:,:,i)=C(m(i));
end

然后c(:,:,i)对应m(1)等。

我不确定哪个版本会更快,但您可以使用代码轻松测试。

答案 1 :(得分:0)

如果您浏览符号工具箱,则可以构建一个更易于处理的函数。

%% symbolic
CL = sym('CL',[2,2])
CM = sym('CM',[2,2])
CR = sym('CR',[2,1])
r = CL*CM*CR
f = matlabFunction(r)
%% use some simple functions so it can be calculated as example
CL_11=@(m) m+1;
CL_12=@(m) m;
CL_21=@(m) m-1;
CL_22=@(m) m+2;

CM_11=@(m) m;
CM_12=@(m) m;
CM_21=@(m) 2*m;        
CM_22=@(m) 2*m;

CR_11=@(m) m;
CR_21=@(m) 1-m;

%% here the substitution happens:
fh = @(m) f(CL_11(m),CL_12(m),CL_21(m),CL_22(m),CM_11(m),CM_12(m),CM_21(m),CM_22(m),CR_11(m),CR_21(m))

出于兴趣,我做了一个小速度测试:

N=1e5;
v = 1:N;

tic
% .... insert symbolic stuff from above
r1 = fh(v);
t1=toc %  gives  0.0842s for me

vs

CL=@(m) [CL_11(m) CL_12(m);CL_21(m) CL_22(m)];
CM=@(m) [CM_11(m) CM_12(m);CM_21(m) CM_22(m)];
CR=@(m) [CR_11(m);CR_21(m)];

C=@(m) CL(m)*CM(m)*CR(m);
tic
r2 =arrayfun(C,v,'UniformOutput',false);
t2=toc % gives  7.6874s for me

tic
r3 = nan(2,N);
for i=1:N
    r3(:,i)=C(v(i));
end
t3=toc %  8.1503s for me