Oblicz produkt Kronecker

11

Powiązane , ale bardzo różne.


W poniższych przykładach Ai Bnie większy niż 2-by-2 matryc oraz matryc są jednym indeksowane.

Kronecker produkt ma następujące właściwości:

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)

Wyzwanie: Biorąc pod uwagę dwie matryce Ai B, wróć A⊗B.

  • Rozmiar matryc będzie co najmniej 1-by-1. Maksymalny rozmiar będzie taki, jaki domyślnie obsługuje Twój komputer / język, ale minimalne 5-by-5dane wejściowe.
  • Wszystkie wartości wejściowe będą liczbami całkowitymi nieujemnymi
  • Wbudowane funkcje do obliczania produktów Kronecker lub produktów Tensor / Outer są niedozwolone
  • Ogólnie: Standardowe zasady dotyczące formatu I / O, programu i funkcji, luk itp.

Przypadki testowe:

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
Stewie Griffin
źródło

Odpowiedzi:

1

Galaretka, 10 9 bajtów

×€€;"/€;/

Wykorzystuje Algorytm Büttnera ( üwymawiany przy próbie wytworzenia eedźwięku [jak w spotkaniu] w formie ustnej oodźwięku [jak w bagażniku]).

;"/€;/Jest inspirowana przez Dennis Mitchell . Był pierwotnie Z€F€€;/(co kosztuje jeszcze jeden bajt).

Leaky Nun
źródło
1
Lub, w IPA, / y /
Luis Mendo
Nie każda osoba zna IPA.
Leaky Nun
4
Dziękujemy za wyjaśnienie, jak wymówić nazwisko Martina. To bardzo istotne. : P
Alex A.
Cóż, w ten sposób okazuję szacunek ...
Leaky Nun
;/może być teraz. (funkcja wyzwanie po
datach
6

CJam, 13 bajtów

{ffff*::.+:~}

Jest to nienazwany blok, który oczekuje dwóch matryc na szczycie stosu i pozostawia swój produkt Kronecker na swoim miejscu.

Zestaw testowy.

Wyjaśnienie

To tylko część produktu Kronecker z poprzedniej odpowiedzi , dlatego właśnie tutaj odtwarzam odpowiednie części poprzedniego wyjaśnienia:

Oto krótki przegląd operatorów poprawki CJam do manipulowania listami:

  • foczekuje listy i czegoś innego na stosie i mapuje następujący operator binarny na liście, przekazując drugi element jako drugi argument. Np. [1 2 3] 2 f*I 2 [1 2 3] f*oba dają [2 4 6]. Jeśli oba elementy są listami, pierwszy jest mapowany, a drugi służy do curry operatora binarnego.
  • :ma dwa zastosowania: jeśli podążający za nim operator jest jednoargumentowy, jest to prosta mapa. Na przykład[1 0 -1 4 -3] :z Jest [1 0 1 4 3], gdzie zdostaje moduł liczby. Jeśli podążający za nim operator jest binarny, spowoduje to jego spasowanie . Np . [1 2 3 4] :+Jest 10.
  • .wektoryzuje operator binarny. Oczekuje dwóch list jako argumentów i stosuje operator do odpowiednich par. Np . [1 2 3] [5 7 11] .*Daje [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.
Martin Ender
źródło
3
Twój kod wygląda prawie jak adres IPv6
Digital Trauma
4

MATLAB / Octave, 83 42 bajtów

Zaoszczędź 41 bajtów, dzięki FryAmTheEggman!

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

Sprawdź to tutaj!

Awaria

arrayfunjest ukrytą pętlą for, która się zwielokrotnia n*B, dla zmiennej nzdefiniowanej przez drugi argument. Działa to, ponieważ zapętlanie przez matrycę 2D jest takie samo jak zapętlanie przez wektor. Tj. for x = AJest taki sam jak for x = A(:).

'un',0jest równoważne bardziej szczegółowemu 'UniformOutput', Falsei określa, że ​​dane wyjściowe zawierają komórki zamiast skalarów.

cell2mat służy do konwersji komórek z powrotem do matrycy numerycznej, która jest następnie wyprowadzana.

Stewie Griffin
źródło
Powinieneś wyjaśnić, że arrayfunpętle są liniowe, tak jak mówisz, tak jakby matryca była wektorem, ale fornie robi tego (zapętla się nad kolumnami tablicy)
Luis Mendo
1

Julia, 40 39 37 bajtów

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

Wypróbuj online!

Jak to działa

  • Dla macierzy A i B , map(a->a*B,A')oblicza produktów Kronecker A⊗B .

    Wynikiem jest wektor bloków matrycy o wymiarach B .

    Musimy transponować A (z '), ponieważ macierze są przechowywane w porządku głównym kolumny.

  • sum(A^0)oblicza sumę wszystkich wpisów macierzy tożsamości A wymiarówDla n x n macierzy A , Daje n .

  • Z pierwszego argumentu n , hvcatŁączy n bloków matrycy w poziomie, i wynikające z bloków (większych) w pionie.

Dennis
źródło
0

J, 10 bajtów

To jedna z możliwych realizacji.

[:,./^:2*/

J, 13 bajtów

Jest to podobna implementacja, ale zamiast tego używa zdolności J do definiowania rang. Dotyczy to *każdego elementu LHS z całym RHS.

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

Stosowanie

   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
mile
źródło
0

JavaScript (ES6), 79

Prosta implementacja z zagnieżdżoną pętlą

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

Test

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>

edc65
źródło