Рассчитать произведение Кронекера


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 / Outer , не допускаются
  • В целом: стандартные правила, касающиеся формата ввода / вывода, программы и функций, лазеек и т. Д.

Тестовые случаи:

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, / y /
Луис Мендо

Не каждый человек знает IPA.
Утренняя монахиня

4
Спасибо за объяснение того, как произносится фамилия Мартина. Это супер актуально. : P
Алекс А.

Ну, это, как я проявляю уважение ...
Leaky Nun

;/можно сейчас. (особенность постдатсовой задачи?)
user202729

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 / Octave, 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

Перевод ответа Jelly , который основан на алгоритме Бюттнера ( üпроизносится при попытке сделать 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)вычисляет сумму всех элементов матрицы идентичности А размеров «s. Для матрицы A n × 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.