Избегание цикла for в Matlab с помощью продукта Kronecker

#matlab #for-loop #sequence

#matlab #for-цикл #последовательность

Вопрос:

Если у меня есть две последовательности A и B, содержащие элементы a1, a2, … и b1, b2, … где a_i и b_i имеют размерность 1xn и 1xm соответственно, тогда я хочу создать новую последовательность C, которая содержит: a_i(1) * b_i, a_i (2) * b_i, … , a_i(n)*b_i. Итак, для i-го элемента C я хочу иметь произведение Kronecker элементов a_i и b_i. Я хочу закодировать это в Matlab, но без цикла for. Для случая, когда b_i являются скалярами, желаемый результат достигается с помощью

 C = A.*B
  

Однако это не работает для нескалярных b_i. Итак, что я делаю сейчас, так это для последовательностей длиной L:

 C = [];
for ii = 1:L
    C = [C; kron(A(ii,:),B(ii,:))];
end
  

Но у меня есть идея, что это должно быть возможно без цикла for. Вот мой код с использованием символьного набора инструментов:

 clc; clear;

L = 5;

syms('a1',[L,1]);
syms('a2',[L,1]);
syms('b1',[L,1]);
syms('b2',[L,1]);

A = [a1,a2];
B = [b1,b2];

C1 = A.*B % only for size(B,2)=1

C2 = [];

for ii = 1:L
    C2 = [C2;kron(A(ii,:),B(ii,:))];
end
C2

C3 = kron(A,B) % does not work
  

Комментарии:

1. Просто для ясности: циклы For не замедляются в MATLAB, по крайней мере, 5 лет назад. Больше нет практической причины (помимо стиля) избегать их. Что является медленным, так это то, что вы не сделали предварительного выделения C2 , и это увеличивает размеры каждого цикла.

2. syms также медленно, если вам это не нужно, неясно, зачем здесь требуется символьный набор инструментов, поможет простой числовой пример

3. @AnderBiguri Ах, я этого не знал! Не предварительно C2 выделенный был для примера, так же как syms и (@Wolfie) . В моем «реальном» скрипте я использовал предварительное выделение и некоторые дополнительные операции вокруг него. В любом случае спасибо за информацию

Ответ №1:

Здесь reshape и неявное расширение используются для вычисления результата:

 C = reshape(B .* reshape (A, L, 1, []), L, []);
  

Комментарии:

1. Во-первых, это выглядело как правильное решение, однако для более высоких измерений это смешивает вещи…

2. @seaver я ответил на текст вашего вопроса. Возможно, у вас есть еще вопросы о более высоких измерениях?

3. Извините, это было неясно, более высокие размеры могут быть не лучшим термином: P. Я имею в виду, что для size(A, 2)> 1 и size(B, 2)> 1 (например, 2 и 4 соответственно) ваш вывод не эквивалентен выводу for-loop и функции Kronecker. Я не уверен, как…

4. Вы можете попробовать это онлайн , сравнивая оба метода. Я не вижу разницы.

5. Тогда, я думаю, есть проблема с длиной L: code