【问题标题】:Matlab vectorizing equations and matrix multiplicationMatlab矢量化方程和矩阵乘法
【发布时间】:2014-04-30 03:49:46
【问题描述】:

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

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

在最后的矩阵乘法中出现错误......即使我只是将左边的 2x2 乘以中间的 2x2,我也会得到可怕的错误:

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

% 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 的新手,并且正在尝试通过使用矩阵和向量来开发更高水平的能力。

谢谢!!

【问题讨论】:

    标签: matlab matrix vectorization matrix-multiplication


    【解决方案1】:

    您的矩阵不是 2x2。当您使用 m 1x300 向量执行 CL_11(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)

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

    【讨论】:

    • 非常感谢!我会试一试......这完全有道理。
    【解决方案2】:

    如果你通过符号工具箱,你可以构造一个更容易处理的函数。

    %% 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
    

    对比

    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
    

    【讨论】:

    • 哇!这是一个显着的进步!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多