Поэлементное умножение .* векторов дает матрицу в Matlab

Даны два вектора

a = 1:3;
b = 2:4;

хорошо известно, что поэлементное умножение a.*b производит

[ 2  6  12 ]

Назвав этот результат c, мы получим c(i) = a(i)*b(i)

Но я не понимаю, как a.*b', b'.*a и b'*a производят

[ 2     4     6
  3     6     9
  4     8    12 ]

Для матричного умножения b'*a мы знаем c(i,j) = b(i)*a(j).
Но почему два других также дают тот же результат?


person ddzzbbwwmm    schedule 15.11.2017    source источник
comment
Неявное расширение   -  person rahnema1    schedule 15.11.2017


Ответы (2)


Из-за неявного расширения (представленного в 2016b) это по сути то же самое, что и использование bsxfun.
Но что это означает?

Настраивать:

a = 1:3;
b = 2:4;
  • Все версии MATLAB:

    c = a.*b; 
    % c = [2 6 12], element-wise multiplication c(j) = a(j)*b(j)
    
    c = b'*a;  
    % c = [2 4 5; 3 6 9; 4 8 12]
    % standard matrix multiplication of vectors
    % c(i,j) = a(i) + b(j)
    
    c = bsxfun(@times, b', a)
    % c = [2 4 5; 3 6 9; 4 8 12]
    % bsxfun applies the function (in this case @times) to b' and a
    

    По определению, bsxfun "применяет поэлементную двоичную операцию, заданную дескриптором функции fun, к массивам A и B, с включенным одноэлементным расширением". Это означает, что одноэлементные измерения (размеры которых равны 1) расширяются по строкам/столбцам, чтобы соответствовать размеру другого аргумента, предоставленного bsxfun.

    Итак, bsxfun(@times, b', a) эквивалентно

     % b' in singleton in the 2nd dimension, a is singleton in the 1st dimension
     % Use repmat to perform the expansion to the correct size
     repmat(b', 1, size(a,2)) .* repmat(a, size(b',1), 1)
     % Equivalent to...
     repmat(b', 1, 3) .* repmat(a, 3, 1)
     % Equivalent to...
     [2 2 2; 3 3 3; 4 4 4] .* [1 2 3; 1 2 3; 1 2 3]   
     % = [2 4 5; 3 6 9; 4 8 12] the same as b'*a
    
  • До R2016b

    c = a.*b'; % Error: Matrix dimensions must agree.
    c = b'.*a; % Error: Matrix dimensions must agree.
    
  • С R2016b

    Более новые версии MATLAB используют неявное расширение, что в основном означает, что эквивалент bsxfun вызывается «под капотом», если это необходимо для допустимой операции.

    c = a.*b'; % [2 4 5; 3 6 9; 4 8 12] the same as bsxfun(@times, a, b')
    c = b'.*a; % [2 4 5; 3 6 9; 4 8 12] the same as bsxfun(@times, b', a)
    % These two are equivalent also because order of operations is irrelevant
    % We can see this by thinking about the expansion discussed above
    

Как вы заметили, это может сбивать с толку, если вы не отслеживаете векторную ориентацию! Если вы когда-нибудь захотите получить одномерный вывод (без расширения), вы можете убедиться, что ваши входные данные являются одномерными векторами-столбцами, используя оператор двоеточия, например:

c = a(:).*b(:); % c = [2; 6; 12] always a column vector
person Wolfie    schedule 15.11.2017

Все перечисленные вами примеры являются поэлементным умножением.

a.*b' выдаст ошибку в более раннем Matlab, пока он выполняет

bsxfun(@times, a, b')

в Matlab с R2016b. Это должно объяснить идентичный результат для a.*b', b'.*a и b'*a.

a * b' будет матричным умножением (совпадение внутреннего измерения).

person Xiangrui Li    schedule 15.11.2017
comment
Я думаю, вы имеете в виду R2016b. Мне до сих пор не понятно, почему результаты a.*b' и b'.*a не транспонируются друг в друга. - person ddzzbbwwmm; 15.11.2017