2013-08-02 6 views
1

Я новичок в Matlab и просто задаюсь вопросом, можете ли вы помочь мне решить эту проблему.Размер матрицы Matlab

Например, у меня есть две матрицы:

A = [X1 X2 X3 X4] 

B = [Y1; Y2; Y3] 

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

[X1Y1 X2Y1 X3Y1 X4Y1; 
X1Y2 X2Y2 X3Y2 X4Y2; 
X1Y3 X2Y3 X3Y3 X4Y3; 
.... and so on] 

Я попытался с помощью A(1,:).*B(:,1) но MATLAB является говоря, что размеры матрицы должны совпадать.

Я просто не знаю, как манипулировать этим на MATLAB, но в excel возможно.

+0

Вы пытались размножаться справа? B(). A() –

ответ

3

Это простой внешний продукт. kron не нужен (хотя он будет работать). bsxfun - это дикий перебор, хотя и даст то, о чем вы просили. repmat не подходит, потому что, хотя он поможет вам сделать то, что вы пожелаете, он реплицирует массивы в памяти, используя больше ресурсов, чем необходимо. (Избегайте использования неэффективных стилей программирования, когда в вашем распоряжении есть хорошие.)

Все, что вам нужно, это простой * оператор.

A - векторный ряд. B - вектор столбца.

C = B*A 

даст результата C (I, J) = B (я) * А (к), что это именно то, что вы ищете. Обратите внимание, что это работает, потому что B - 3x1, а A - 1x4, поэтому «внутренние» размеры B и A соответствуют друг другу.

В MATLAB, ЕСЛИ вы не уверены, что-то работает, ПОПРОБУЙТЕ ЭТО!

A = [1 2 3 4]; 
B = [1;2;3]; 
C = B*A 
ans = 
    1  2  3  4 
    2  4  6  8 
    3  6  9 12 

Смотрите, что Крон сделал действительно работать, хотя я бы поставил, что использование Крон здесь, вероятно, менее эффективны, чем простой внешний продукт многократно.

C = kron(B,A) 
C = 
    1  2  3  4 
    2  4  6  8 
    3  6  9 12 

Как хорошо, bsxfun будет работать здесь, хотя, так как мы используем общий инструмент, чтобы сделать что-то, что основной оператор будет делать, я бы поставил это немного менее эффективно.

C = bsxfun(@times,B,A) 
C = 
    1  2  3  4 
    2  4  6  8 
    3  6  9 12 

НАИБОЛЬШИЙ выбор - repmat.Опять же, поскольку он искусственно реплицирует векторы в памяти FIRST, он должен выйти и захватить большие куски памяти в случае больших векторов.

C = repmat(B,1,4).*repmat(A,3,1) 
C = 
    1  2  3  4 
    2  4  6  8 
    3  6  9 12 

Я полагаю, что для полноты вы могли бы использовать meshgrid или ndgrid. Смотрите, что он делает именно то, что сделал repmat, но здесь он явно создает новые матрицы. Опять же, это плохой стиль программирования, когда есть хорошие инструменты для выполнения именно того, что вы хотите.

[BB,AA] = ndgrid(B,A) 
BB = 
    1  1  1  1 
    2  2  2  2 
    3  3  3  3 
AA = 
    1  2  3  4 
    1  2  3  4 
    1  2  3  4 

C = BB.*AA 
C = 
    1  2  3  4 
    2  4  6  8 
    3  6  9 12 

Что именно вам нужно понять, именно поэтому каждый из этих инструментов МОЖЕТ использоваться для работы и почему они разные.

+0

+1, в частности для утверждения * В MATLAB, ЕСЛИ вы не уверены, что что-то работает, ПОПРОБУЙТЕ! * Кажется, что это забито людьми, которые предпочитают потратить 20 минут, составляя вопрос и часы, ожидая ответа, чем тратят 20 минут, играя вокруг и выясняя ответ для себя. –

-1

Я думаю, вам просто нужно перенести один из векторов. Вы умножаете вектор-столбец (A (1, :)) на вектор строки (B (:, 1)). Это должно работать:

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

Вы можете сделать элемент по умножению строки и столбца, Matlab не возражает против этого (я думаю, я не на 100% от того, что на самом деле, а не вокруг matlab для тестирования). Octave трансляции поэтому не могут использовать его для проверки). Но в этом случае проблема заключается в том, что 'A' имеет 4 элемента, тогда как' B' имеет только 3. То, что после OP является традиционным умножением матрицы, т.е. 'B * A' – Dan

+1

Я действительно пробовал это в сеансе matlab (2010A) и получил ошибку при попытке сделать A (1,:). * B (:, 1). Но вы правы, похоже, что OP означало что-то еще:) – roger

1

В Matlab есть * и .*, и они очень разные.

* - нормальное умножение матрицы, которое вы хотите, то есть B*A, обратите внимание, что B должен быть первым, поскольку внутреннее измерение должно совпадать. Вы можете умножить столбец на строку, но не строку на столбец (если они не имеют одинаковое количество элементов).

.* является умножением элементов по элементу, в этом случае матрицы должны быть точно такого же размера и формы, что, например, [1 2 3]. * [4 5 6] = [1 * 4 2 * 5 3 * 6] = [4 10 18]

+0

Почему downvote? Мой ответ правильный! – Dan

+0

Sleepy downvote удален. –

+0

@HighPerformanceMark Нет, вы определенно не можете. Попробуйте это: 'A = [1,2,3,4]; B = [1; 2; 3]; A * B;' вы получите ошибку * Внутренние размеры матрицы должны совпадать. * Но 'B * A 'будет работать нормально. Это связано с тем, что во втором случае внутренние размеры равны 1, но в первом случае вы пытаетесь умножить 4x3, что вы не можете сделать по определению матричного умножения. – Dan

0

Не делайте «.*». Вы должны сделать «*». «.*» предназначен для индекса по умножению индекса и должен был дать вам [X1Y1 X2Y2 X3Y3], были ли они векторами равными по размеру. Если вы выполняете регулярное умножение «*», это на самом деле матричное умножение.