English 中文(简体)
MATLAB: How to pathply two range of matrices?
原标题:MATLAB: How to vector-multiply two arrays of matrices?

我有两个三维阵列,头两个方面代表矩阵,最后一个方面通过参数快速计算,仅举一个例子。

A = repmat([1,2; 3,4], [1 1 4]);

(但<条码>A(:j)对每一条<代码>j有所不同)。 • 如何易于执行每个<代码>j的矩阵表,可复制两种此类矩阵信息:<代码>A和B?

C = A; % pre-allocate, nan(size(A,1), size(B,2)) would be better but slower
for jj = 1:size(A, 3)
  C(:,:,jj) = A(:,:,jj) * B(:,:,jj);
end

工作当然是做的,但如果第三个方面比1e3因素要多,那么,这非常缓慢,因为它没有使用MATLAB的病媒化。 因此,是否有更快的途径?

最佳回答

我高度建议你使用MMX工具箱 matlab。 它可以尽可能快地增加单维矩阵。

</strong>的优点是:

  1. It is easy to use.
  2. Multiply n-dimensional matrices (actually it can multiply arrays of 2-D matrices)
  3. It performs other matrix operations (transpose, Quadratic Multiply, Chol decomposition and more)
  4. It uses C compiler and multi-thread computation for speed up.

For this problem, you just need to write this command:

C=mmx( mul ,A,B);

我在@Amro的答复中增加了以下职能:

%# mmx toolbox
function C=func6(A,B,n,m,p)
    C=mmx( mul ,A,B);
end

www.un.org/Depts/DGACM/index_spanish.htm

    1.6571 # FOR-loop
    4.3110 # ARRAYFUN
    3.3731 # NUM2CELL/FOR-loop/CELL2MAT
    2.9820 # NUM2CELL/CELLFUN/CELL2MAT
    0.0244 # Loop Unrolling
    0.0221 # MMX toolbox  <===================

我使用了@Amro的代码来管理基准。

问题回答

我现在进行了一些时间测试,这是2x2x2x2的最快途径。 注

C = A;
C(1,1,:) = A(1,1,:).*B(1,1,:) + A(1,2,:).*B(2,1,:);
C(1,2,:) = A(1,1,:).*B(1,2,:) + A(1,2,:).*B(2,2,:);
C(2,1,:) = A(2,1,:).*B(1,1,:) + A(2,2,:).*B(2,1,:);
C(2,2,:) = A(2,1,:).*B(1,2,:) + A(2,2,:).*B(2,2,:);

在一般情况下,选择住宿实际上是最快的(登机忘记预先分配C,但!)。

Should one already have the result as cell-array of matrices though, using cellfun is the fastest choice, it is also faster than looping over the cell elements:

C = cellfun(@mtimes, A, B,  UniformOutput , false);

但是,必须打上rel=“nofollow”>num2cell 首先(Ac = num2cell(A, [1 2])和cell2mat,用于3d-array案废物,时间过长。


这里,我是随机挑选的2×2×1e4:

 array-for: 0.057112
 arrayfun : 0.14206
 num2cell : 0.079468
 cell-for : 0.033173
 cellfun  : 0.025223
 cell2mat : 0.010213
 explicit : 0.0021338

Explicit refers to using direct calculation of the 2 x 2 matrix elements, see bellow. The result is similar for new random arrays, cellfun is the fastest if no num2cell is required before and there is no restriction to 2x2xN. For general 3d-arrays looping over the third dimension is indeed the fastest choice already. Here s the timing code:

n = 2;
m = 2;
l = 1e4;

A = rand(n,m,l);
B = rand(m,n,l);

% naive for-loop:
tic
%Cf = nan(n,n,l);
Cf = A;
for jl = 1:l
    Cf(:,:,jl) = A(:,:,jl) * B(:,:,jl);
end;
disp([  array-for:   num2str(toc)]);

% using arrayfun:
tic
Ca = arrayfun(@(k) A(:,:,k)*B(:,:,k), 1:size(A,3),  UniformOutput ,false);
Ca = cat(3,Ca{:});
disp([  arrayfun :   num2str(toc)]);

tic
Ac = num2cell(A, [1 2]);
Bc = num2cell(B, [1 2]);
disp([  num2cell :   num2str(toc)]);

% cell for-loop:
tic
Cfc = Ac;
for jl = 1:l
    Cfc{jl} = Ac{jl} * Bc{jl};
end;
disp([  cell-for :   num2str(toc)]);

% using cellfun:
tic
Cc = cellfun(@mtimes, Ac, Bc,  UniformOutput , false);
disp([  cellfun  :   num2str(toc)]);

tic
Cc = cell2mat(Cc);
disp([  cell2mat :   num2str(toc)]);

tic
Cm = A;
Cm(1,1,:) = A(1,1,:).*B(1,1,:) + A(1,2,:).*B(2,1,:);
Cm(1,2,:) = A(1,1,:).*B(1,2,:) + A(1,2,:).*B(2,2,:);
Cm(2,1,:) = A(2,1,:).*B(1,1,:) + A(2,2,:).*B(2,1,:);
Cm(2,2,:) = A(2,1,:).*B(1,2,:) + A(2,2,:).*B(2,2,:);
disp([  explicit :   num2str(toc)]);

disp(   );

这里是我的基准测试,比较了https://stackoverflow.com/questions/6580656/matlab-how-to-vector-multiply-second-arrays-of-matrices/6580802#65802>@TobiasKienzler。 答案。 我正在使用 TPASIT功能,以获得更准确的时间。

function [t,v] = matrixMultTest()
    n = 2; m = 2; p = 1e5;
    A = rand(n,m,p);
    B = rand(m,n,p);

    %# time functions
    t = zeros(5,1);
    t(1) = timeit( @() func1(A,B,n,m,p) );
    t(2) = timeit( @() func2(A,B,n,m,p) );
    t(3) = timeit( @() func3(A,B,n,m,p) );
    t(4) = timeit( @() func4(A,B,n,m,p) );
    t(5) = timeit( @() func5(A,B,n,m,p) );

    %# check the results
    v = cell(5,1);
    v{1} = func1(A,B,n,m,p);
    v{2} = func2(A,B,n,m,p);
    v{3} = func3(A,B,n,m,p);
    v{4} = func4(A,B,n,m,p);
    v{5} = func5(A,B,n,m,p);
    assert( isequal(v{:}) )
end

%# simple FOR-loop
function C = func1(A,B,n,m,p)
    C = zeros(n,n,p);
    for k=1:p
        C(:,:,k) = A(:,:,k) * B(:,:,k);
    end
end

%# ARRAYFUN
function C = func2(A,B,n,m,p)
    C = arrayfun(@(k) A(:,:,k)*B(:,:,k), 1:p,  UniformOutput ,false);
    C = cat(3, C{:});
end

%# NUM2CELL/FOR-loop/CELL2MAT
function C = func3(A,B,n,m,p)
    Ac = num2cell(A, [1 2]);
    Bc = num2cell(B, [1 2]);
    C = cell(1,1,p);
    for k=1:p
        C{k} = Ac{k} * Bc{k};
    end;
    C = cell2mat(C);
end

%# NUM2CELL/CELLFUN/CELL2MAT
function C = func4(A,B,n,m,p)
    Ac = num2cell(A, [1 2]);
    Bc = num2cell(B, [1 2]);
    C = cellfun(@mtimes, Ac, Bc,  UniformOutput , false);
    C = cell2mat(C);
end

%# Loop Unrolling
function C = func5(A,B,n,m,p)
    C = zeros(n,n,p);
    C(1,1,:) = A(1,1,:).*B(1,1,:) + A(1,2,:).*B(2,1,:);
    C(1,2,:) = A(1,1,:).*B(1,2,:) + A(1,2,:).*B(2,2,:);
    C(2,1,:) = A(2,1,:).*B(1,1,:) + A(2,2,:).*B(2,1,:);
    C(2,2,:) = A(2,1,:).*B(1,2,:) + A(2,2,:).*B(2,2,:);
end

The results:

>> [t,v] = matrixMultTest();
>> t
t =
      0.63633      # FOR-loop
      1.5902       # ARRAYFUN
      1.1257       # NUM2CELL/FOR-loop/CELL2MAT
      1.0759       # NUM2CELL/CELLFUN/CELL2MAT
      0.05712      # Loop Unrolling

正如我在评论中解释的那样,简单易行是最佳解决办法(,就最后一种情况而言,只有2-by-2 matrices才能做到这一点)。

一种办法是,为A和B建立一个2Nx2N 稀释矩阵,并植根于2x2 矩阵。 两种产品是par缩的,其结果为略微cl,将其重新编为2x2xN。

但我怀疑这比单纯的住宿要快。

在我的经验中,一种更快捷的方法是,在三维矩阵上使用清晰的多重复和总结。 以下职能:z_matmultiply(A,B)使两个具有同样深度的三维矩阵形形形形色色。 重复采用尽可能平行的方式进行,因此,你可能要检查这一职能的速度,并在大量重复情况下与其他职能进行比较。

function C = z_matmultiply(A,B)

[ma,na,oa] = size(A);
[mb,nb,ob] = size(B);

%preallocate the output as we will do a loop soon
C = zeros(ma,nb,oa);

%error message if the dimensions are not appropriate
if na ~= mb || oa ~= ob
    fprintf( 
 z_matmultiply warning: Matrix Dimmensions Inconsistent 
 )
else

% if statement minimizes for loops by looping the smallest matrix dimension 
if ma > nb
    for j = 1:nb
        Bp(j,:,:) = B(:,j,:);
        C(:,j,:) = sum(A.*repmat(Bp(j,:,:),[ma,1]),2);
    end
else
    for i = 1:ma
        Ap(:,i,:) = A(i,:,:);
        C(i,:,:) = sum(repmat(Ap(:,i,:),[1,nb]).*B,1);
    end 
end

end




相关问题
WordPress Data Storage Efficiency

I ve been asked to review a WordPress plugin of sorts and try to find ways of making it faster. The premise of this plugin is basically to store a bunch of users and shifts and appointments and ...

Convert a 2D array index into a 1D index

I have two arrays for a chess variant I am coding in java...I have a console version so far which represents the board as a 1D array (size is 32) but I am working on making a GUI for it and I want it ...

Convert an array of integers for use in a SQL "IN" clause

Surely there is a framework method that given an array of integers, strings etc converts them into a list that can be used in a SQL "IN" clause? e.g. int[] values = {1,2,3}; would go to "(1,2,3)"

Sorting twodimensional Array in AS3

So, i have a two-dimensional Array of ID s and vote count - voteArray[i][0] = ID, voteArray[i][1] = vote count I want the top 3 voted items to be displayed in different colors, so i have a 2nd Array -...

C++ Array Sort Me

Stuck on an array sorter. Have to sort numbers from largest to smallest. I m trying two loops (one nested in the other). Here s the code: int counter=0; // inner counter int counter2=0; // outer ...

PHP array callback functions for cleaning output

I have an array of output from a database. I am wondering what the cleanest way to filter the values is example array Array ( [0] => Array ( [title] => title 1 ...

Best practice of big javascript objects

sry for this imprecise topic name. I am querying a dataset a lot of times so using ajax request would end up in tons of http requests. For this reason I decided to use the json encode method to ...

How to get the Array Class for a given Class in Java?

I have a Class variable that holds a certain type and I need to get a variable that holds the corresponding array class. The best I could come up with is this: Class arrayOfFooClass = java.lang....

热门标签