Обчисліть продукт Kronecker


11

Пов’язані , але дуже різні.


У наведених нижче прикладах Aі Bбудуть матриці 2 на 2, а матриці одноіндексовані.

Кронекера продукт має такі властивості:

A⊗B =  A(1,1)*B   A(1,2)*B
        A(2,1)*B   A(2,2)*B

     =  A(1,1)*B(1,1)   A(1,1)*B(1,2)   A(1,2)*B(1,1)   A(1,2)*B(1,2)
        A(1,1)*B(2,1)   A(1,1)*B(2,2)   A(1,2)*B(2,1)   A(1,2)*B(2,2)
        A(2,1)*B(1,1)   A(2,1)*B(1,2)   A(2,2)*B(1,1)   A(2,2)*B(1,2)
        A(2,2)*B(2,1)   A(2,2)*B(1,2)   A(2,2)*B(2,1)   A(2,2)*B(2,2)

Завдання: Дано дві матриці Aта Bповернення A⊗B.

  • Розмір матриць буде як мінімум 1-by-1. Максимальний розмір буде залежати від вашого комп'ютера / мови за замовчуванням, але мінімальний 5-by-5вхід.
  • Усі вхідні значення будуть невід’ємними цілими числами
  • Вбудовані функції, які обчислюють продукти Kronecker або продукти Tensor / Outter , заборонені
  • Загалом: стандартні правила щодо формату вводу / виводу, програми та функції, лазівки тощо.

Тестові приклади:

A =   
     1     2
     3     4    
B =    
     5     6
     7     8    
A⊗B =    
     5     6    10    12
     7     8    14    16
    15    18    20    24
    21    24    28    32

B⊗A =    
     5    10     6    12
    15    20    18    24
     7    14     8    16
    21    28    24    32
------------------------
A =    
     1
     2
B =    
     1     2

A⊗B =    
     1     2
     2     4
------------------------
A =    
    16     2     3    13
     5    11    10     8
     9     7     6    12
     4    14    15     1

B =    
     1     1
     0     1

A⊗B  =    
    16    16     2     2     3     3    13    13
     0    16     0     2     0     3     0    13
     5     5    11    11    10    10     8     8
     0     5     0    11     0    10     0     8
     9     9     7     7     6     6    12    12
     0     9     0     7     0     6     0    12
     4     4    14    14    15    15     1     1
     0     4     0    14     0    15     0     1

B⊗A =    
    16     2     3    13    16     2     3    13
     5    11    10     8     5    11    10     8
     9     7     6    12     9     7     6    12
     4    14    15     1     4    14    15     1
     0     0     0     0    16     2     3    13
     0     0     0     0     5    11    10     8
     0     0     0     0     9     7     6    12
     0     0     0     0     4    14    15     1
------------------------

A = 2
B = 5
A⊗B = 10

Відповіді:


1

Желе, 10 9 байт

×€€;"/€;/

Використовує алгоритм Бюттнера ( üвимовляється під час спроби видавати eeзвук [як у зустрічі] у формі рота ooзвуку [як при завантаженні]).

;"/€;/Натхненний Денніс Мітчелл . Це було спочатку Z€F€€;/(що коштує ще один байт).


1
Або в IPA, / у /
Луїс Мендо

Не кожна людина знає IPA.
Leaky Nun

4
Дякую за пояснення, як вимовляти прізвище Мартіна. Це супер актуально. : P
Алекс А.

Ну, як я проявляю повагу ...
Leaky Nun,

;/можна зараз. (функція розміщує виклики?)
користувач202729

6

CJam, 13 байт

{ffff*::.+:~}

Це неназваний блок, який очікує дві матриці на вершині стека і залишає на своєму місці продукт Kronecker.

Тестовий набір.

Пояснення

Це лише частина продукту Kronecker з попередньої відповіді , тому я тут просто відтворюю відповідні частини попереднього пояснення:

Ось короткий огляд операторів фіксації CJam для маніпуляції зі списком:

  • fочікує на стеку список і щось інше і відображає наступного двійкового оператора над списком, передаючи інший елемент як другий аргумент. Наприклад [1 2 3] 2 f*і 2 [1 2 3] f*обидва дають [2 4 6]. Якщо обидва елементи є списками, перший відображається на карті, а другий використовується для виведення бінарного оператора.
  • :має два способи використання: якщо оператор, що стежить за ним, не є одинарним, це проста карта. Наприклад , [1 0 -1 4 -3] :zце [1 0 1 4 3], де zотримує модуль числа. Якщо оператор, що слідує за ним, є двійковим, він замість цього згорне оператор. Наприклад , [1 2 3 4] :+є 10.
  • .векторизує двійковий оператор. Він очікує два аргументи як аргументи і застосовує оператора до відповідних пар. Напр. [1 2 3] [5 7 11] .*Дає [5 14 33].
ffff*  e# This is the important step for the Kronecker product (but
       e# not the whole story). It's an operator which takes two matrices
       e# and replaces each cell of the first matrix with the second matrix
       e# multiplied by that cell (so yeah, we'll end up with a 4D list of
       e# matrices nested inside a matrix).
       e# Now the ffff* is essentially a 4D version of the standard ff* idiom
       e# for outer products. For an explanation of ff*, see the answer to
       e# to the Kronecker sum challenge.
       e# The first ff maps over the cells of the first matrix, passing in the 
       e# second matrix as an additional argument. The second ff then maps over 
       e# the second matrix, passing in the cell from the outer map. We 
       e# multiply them with *.
       e# Just to recap, we've essentially got the Kronecker product on the
       e# stack now, but it's still a 4D list not a 2D list.
       e# The four dimensions are:
       e#   1. Columns of the outer matrix.
       e#   2. Rows of the outer matrix.
       e#   3. Columns of the submatrices.
       e#   4. Rows of the submatrices.
       e# We need to unravel that into a plain 2D matrix.
::.+   e# This joins the rows of submatrices across columns of the outer matrix.
       e# It might be easiest to read this from the right:
       e#   +    Takes two rows and concatenates them.
       e#   .+   Takes two matrices and concatenates corresponding rows.
       e#   :.+  Takes a list of matrices and folds .+ over them, thereby
       e#        concatenating the corresponding rows of all matrices.
       e#   ::.+ Maps this fold operation over the rows of the outer matrix.
       e# We're almost done now, we just need to flatten the outer-most level
       e# in order to get rid of the distinction of rows of the outer matrix.
:~     e# We do this by mapping ~ over those rows, which simply unwraps them.

3
Ваш код майже схожий на адресу IPv6
Digital Trauma

4

MATLAB / Октава, 83 42 байт

Збережено 41 байт, завдяки FryAmTheEggman!

@(A,B)cell2mat(arrayfun(@(n)n*B,A,'un',0))

Тестуйте його тут!

Зламатися

arrayfunє замаскованим циклом for, що множиться n*B, для змінної, nвизначеної другим аргументом. Це працює, тому що циклічне проведення через 2D матрицю - це те саме, що циклічне пересування через вектор. Тобто for x = Aте саме, що for x = A(:).

'un',0еквівалентний більш багатослівній 'UniformOutput', Falseі вказує, що вихід містить клітинки замість скалярів.

cell2mat використовується для перетворення комірок назад в числову матрицю, яка потім виводиться.


Ви повинні уточнити , що arrayfunпетлі лінійно , як ви говорите, як якщо б матриця була вектором, але forробите НЕ (вона перебирає стовпці масиву)
Луїс Mendo

1

Pyth, 14 12 11 байт

JEsMs*RRRRJ

Переклад відповіді Джеллі , який базується на Алгоритмі Бюттнера ( üвимовляється при спробі видати eeзвук [як у зустрічі] у формі ooзвуку [як у завантаженні]).

Спробуйте в Інтернеті (тестовий випадок 1)!

Бонус: обчислити B⊗Aв однаковій кількості байтів

JEsMs*LRLRJ

Спробуйте в Інтернеті (тестовий випадок 1)!


1

Джулія, 40 39 37 байт

A%B=hvcat(sum(A^0),map(a->a*B,A')...)

Спробуйте в Інтернеті!

Як це працює

  • Для матриць A і B , map(a->a*B,A')обчислює твір Кронекера A⊗B .

    Результат є вектором матричних блоків з розмірами B .

    Ми повинні перенести A'), оскільки матриці зберігаються в порядку основного стовпця.

  • sum(A^0)обчислює суму всіх записів матриці ідентичності розмірів A. Для N × N матриці А , це дає п .

  • З першим аргументом п , hvcatзв'язує п матричних блоків по горизонталі, і в результаті (більше) блоків по вертикалі.


0

J, 10 байт

Це одна можлива реалізація.

[:,./^:2*/

J, 13 байт

Це аналогічна реалізація, але натомість використовує можливість J визначати ранги. Він застосовується *між кожним елементом на LHS з усією RHS.

[:,./^:2*"0 _

Використання

   f =: <either definition>
    (2 2 $ 1 2 3 4) f (2 2 $ 5 6 7 8)
 5  6 10 12
 7  8 14 16
15 18 20 24
21 24 28 32
   (2 1 $ 1 2) f (1 2 $ 1 2)
1 2
2 4
   2 f 5
10

0

JavaScript (ES6), 79

Безпосередня реалізація з вкладеним циклом

(a,b)=>a.map(a=>b.map(b=>a.map(y=>b.map(x=>r.push(y*x)),t.push(r=[]))),t=[])&&t

Тест

f=(a,b)=>a.map(a=>b.map(b=>a.map(y=>b.map(x=>r.push(y*x)),t.push(r=[]))),t=[])&&t

console.log=x=>O.textContent+=x+'\n'

function show(label, mat)
{
  console.log(label)
  console.log(mat.join`\n`)
}

;[ 
  {a:[[1,2],[3,4]],b:[[5,6],[7,8]] },
  {a:[[1],[2]],b:[[1,2]]},
  {a:[[16,2,3,13],[5,11,10,8],[9,7,6,12],[4,14,15,1]],b:[[1,1],[0,1]]},
  {a:[[2]],b:[[5]]}
].forEach(t=>{
  show('A',t.a)  
  show('B',t.b)
  show('A⊗B',f(t.a,t.b))
  show('B⊗A',f(t.b,t.a))  
  console.log('-----------------')
})
<pre id=O></pre>

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.