Code covered by the BSD License  

Highlights from
Multiple matrix multiplications, with array expansion enabled

image thumbnail
from Multiple matrix multiplications, with array expansion enabled by Paolo de Leva
Multiplying matrices, vectors, or scalars contained in two N-D arrays, with array expansion enabled.

arraylab131(a,b,d1,d2)
function c = arraylab131(a,b,d1,d2)
% Slight adjustment to ARRAYLAB13.
% I just used PERMUTE on the whole array, only once, rather than for each
% column of the RxS matrices. As a consequence, a call to subfunction MBYV
% is no longer necessary.

% Transposing: RxS matrices in B become SxR matrices
ndimsB = ndims(b);
order = [1:d1-1, d2, d1, d2+1:ndimsB];
b = permute(b, order);

% Checking
ndimsA = ndims(a); % NOTE - Since trailing singletons are removed,
ndimsB = ndims(b); %        not always NDIMSB = NDIMSA
NsA = d2 - ndimsA; % Number of added trailing singletons
NsB = d2 - ndimsB;
sizA = [size(a) ones(1,NsA)];
sizB = [size(b) ones(1,NsB)];

% Performing products
    p = sizA(d1); % A is PxQ
    s = sizB(d1); % B is SxR
    % Initializing C (PxS)
        sizC = sizA; 
        sizC(d2) = s;
        c = zeros(sizC);
    % Vectorized indices for B and C
        Nd = length(sizB);
        Bindices = cell(1,Nd); % preallocating (cell array)
        for d = 1 : Nd
           Bindices{d} = 1:sizB(d);
        end

    if sizB(d1) == 1 %  PxQ IN A  -  Rx1 IN B (after PERMUTing: 1xR in B)
        % A * B
        Bindices{d1} = ones(1, p); % "Cloned" index
        b2 = b(Bindices{:}); % B2 has same size as A
        c = sum(a .* b2, d2);
 
    else %              PxQ IN A  -  RxS IN B (after PERMUTing: SxR in B)

        Cindices = Bindices;
        Cindices{d1} = 1:p;            
        Cindices{d2} = Bindices{d1}; 
        % Building C
            for Ncol = 1:s
               % Cloning a part of B identified by index Ncol for dim. d1 
               Bindices{d1} = Ncol * ones(1, p); % "Cloned" index
               Cindices{d2} = Ncol;
               b2 = b(Bindices{:}); % B2 has same size as A

               % Performing dot products along dimension d2
               c(Cindices{:}) = sum(a .* b2, d2);
            end
    end

Contact us