Calculez le produit Kronecker

11

Connexes , mais très différentes.


Dans les exemples ci-dessous, Aet Bseront des matrices 2 par 2, et les matrices sont à un index.

Un produit Kronecker a les propriétés suivantes:

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)

Défi: étant donné deux matrices, Aet B, retour A⊗B.

  • La taille des matrices sera au moins 1-by-1. La taille maximale sera celle que votre ordinateur / langage peut gérer par défaut, mais l' 5-by-5entrée minimale .
  • Toutes les valeurs d'entrée seront des entiers non négatifs
  • Les fonctions intégrées qui calculent les produits Kronecker ou les produits Tensor / Outer ne sont pas autorisées
  • En général: règles standard concernant le format d'E / S, le programme et les fonctions, les failles, etc.

Cas de test:

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
la source

Réponses:

1

Gelée, 10 9 octets

×€€;"/€;/

Utilise l'algorithme de Büttner ( üprononcé en essayant de faire un eeson [comme dans la rencontre] sous la forme d'une bouche d'un ooson [comme dans le démarrage]).

Le ;"/€;/est inspiré de Dennis Mitchell . C'était à l'origine Z€F€€;/(ce qui coûte un octet de plus).

Leaky Nun
la source
1
Ou, dans IPA, / y /
Luis Mendo
Tout le monde ne connaît pas l'IPA.
Leaky Nun
4
Merci pour l'explication de la façon de prononcer le nom de famille de Martin. C'est super pertinent. : P
Alex A.
C'est comme ça que je montre du respect ...
Leaky Nun
;/peut être maintenant. (défi de postdates?)
user202729
6

CJam, 13 octets

{ffff*::.+:~}

Il s'agit d'un bloc sans nom qui attend deux matrices au-dessus de la pile et laisse leur produit Kronecker à leur place.

Suite de tests.

Explication

Ceci est juste la partie du produit Kronecker de la réponse précédente , donc je suis ici en train de reproduire les parties pertinentes de l'explication précédente:

Voici un aperçu rapide des opérateurs d'infixe de CJam pour la manipulation de liste:

  • fattend une liste et quelque chose d'autre sur la pile et mappe l' opérateur binaire suivant sur la liste, en passant l'autre élément comme deuxième argument. Par exemple, [1 2 3] 2 f*et les 2 [1 2 3] f*deux donnent [2 4 6]. Si les deux éléments sont des listes, le premier est mappé et le second est utilisé pour curry l'opérateur binaire.
  • :a deux utilisations: si l'opérateur qui le suit est unaire, il s'agit d'une simple carte. Par exemple , [1 0 -1 4 -3] :zest [1 0 1 4 3], où zobtient le module d'un nombre. Si l'opérateur qui le suit est binaire, cela repliera l'opérateur à la place. Par exemple , [1 2 3 4] :+est 10.
  • .vectorise un opérateur binaire. Il attend deux listes comme arguments et applique l'opérateur aux paires correspondantes. Par exemple, [1 2 3] [5 7 11] .*donne [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
la source
3
Votre code ressemble presque à une adresse IPv6
Digital Trauma
4

MATLAB / Octave, 83 42 octets

Enregistré 41 octets, grâce à FryAmTheEggman!

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

Testez-le ici!

Panne

arrayfunest une boucle for déguisée qui se multiplie n*B, pour une variable ndéfinie par le deuxième argument. Cela fonctionne car le bouclage à travers une matrice 2D est le même que le bouclage à travers un vecteur. C'est à dire for x = Ala même chose que for x = A(:).

'un',0est équivalent à la plus verbeuse 'UniformOutput', Falseet spécifie que la sortie contient des cellules au lieu de scalaires.

cell2mat est utilisé pour reconvertir les cellules en une matrice numérique, qui est ensuite sortie.

Stewie Griffin
la source
Vous devez préciser que les arrayfunboucles sont linéaires comme vous le dites, comme si la matrice était un vecteur, mais forne le fait pas (il boucle sur les colonnes du tableau)
Luis Mendo
1

Julia, 40 39 37 octets

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

Essayez-le en ligne!

Comment ça fonctionne

  • Pour les matrices A et B , map(a->a*B,A')calcule le produit Kronecker A⊗B .

    Le résultat est un vecteur de blocs matriciels avec des dimensions de B .

    Nous devons transposer A (avec ') puisque les matrices sont stockées dans l'ordre des colonnes principales.

  • sum(A^0)calcule la somme de toutes les entrées de la matrice d'identité des dimensions de A. Pour une matrice n × n A , cela donne n .

  • Avec le premier argument n , hvcatconcatène n blocs de matrice horizontalement et les blocs résultants (plus grands) verticalement.

Dennis
la source
0

J, 10 octets

Il s'agit d'une implémentation possible.

[:,./^:2*/

J, 13 octets

Il s'agit d'une implémentation similaire, mais utilise à la place la capacité de J pour définir les rangs. Il s'applique *entre chaque élément du LHS avec l'ensemble du RHS.

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

Usage

   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
miles
la source
0

JavaScript (ES6), 79

Implémentation simple avec boucle imbriquée

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

Tester

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
la source